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
相关产品推荐
相关产品推荐

