You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C#新手技术求助:如何基于ITransformer接口实现数组元素类型转换扩展方法

解决数组扩展方法中使用ITransformer接口的问题

嘿,我来帮你理清这个问题!首先我们得先明确ITransformer<TSource, TResult>接口的定义——它的核心就是封装转换逻辑,应该包含一个用于单元素转换的方法,比如:

public interface ITransformer<TSource, TResult>
{
    TResult Transform(TSource input);
}

这个接口和你常用的ConvertAll最大的区别是:它把转换逻辑封装成了可复用的类,而不是临时的匿名委托,适合需要重复使用同一种转换规则的场景。接下来我们一步步实现目标扩展方法:

步骤1:完成参数合法性校验

按照方法注释的要求,我们要先检查入参是否合法,抛出对应的异常:

public static TResult[] Transform<TSource, TResult>(this TSource[] source, ITransformer<TSource, TResult> transformer)
{
    // 检查数组是否为null
    if (source == null)
        throw new ArgumentNullException(nameof(source));
    // 检查转换器实例是否为null
    if (transformer == null)
        throw new ArgumentNullException(nameof(transformer));
    // 检查数组是否为空(长度为0)
    if (source.Length == 0)
        throw new ArgumentException("源数组不能为空数组", nameof(source));
    
    // 接下来实现转换逻辑
    // ...
}

步骤2:实现核心转换逻辑

我们需要创建一个和源数组长度一致的结果数组,然后遍历源数组的每个元素,调用转换器的Transform方法完成转换,把结果存入新数组:

public static TResult[] Transform<TSource, TResult>(this TSource[] source, ITransformer<TSource, TResult> transformer)
{
    if (source == null)
        throw new ArgumentNullException(nameof(source));
    if (transformer == null)
        throw new ArgumentNullException(nameof(transformer));
    if (source.Length == 0)
        throw new ArgumentException("源数组不能为空数组", nameof(source));

    // 创建结果数组
    TResult[] result = new TResult[source.Length];
    
    // 遍历每个元素并执行转换
    for (int i = 0; i < source.Length; i++)
    {
        result[i] = transformer.Transform(source[i]);
    }
    
    return result;
}

步骤3:实际使用示例

我们来写一个具体的转换器类,比如把int转换成带自定义前缀的string:

public class IntToPrefixedStringTransformer : ITransformer<int, string>
{
    private readonly string _prefix;

    // 通过构造函数传入前缀,让转换器更灵活
    public IntToPrefixedStringTransformer(string prefix)
    {
        _prefix = prefix;
    }

    public string Transform(int input)
    {
        return $"{_prefix}{input}";
    }
}

然后调用扩展方法试试:

int[] numbers = { 1, 2, 3, 4, 5 };
var transformer = new IntToPrefixedStringTransformer("商品编号:");
string[] numberedStrings = numbers.Transform(transformer);

// 输出结果:商品编号:1、商品编号:2...
foreach (var s in numberedStrings)
{
    Console.WriteLine(s);
}

和ConvertAll的区别对比

你之前用的Array.ConvertAll是通过委托(比如Func<TSource, TResult>)传递转换逻辑,而用ITransformer的好处是:

  • 可以封装依赖外部配置的复杂转换逻辑(比如上面示例里的自定义前缀)
  • 转换逻辑可以在多个地方复用,不需要重复编写委托代码
  • 更符合面向对象的"开闭原则":新增转换规则只需要实现新的ITransformer类,不需要修改扩展方法本身

内容的提问来源于stack exchange,提问作者Akzhol

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.27 20:12:39