能否用IEnumerable<T>替代IEnumerable<string>编写泛型Lambda表达式?
解决泛型元组Lambda的编译问题
这个问题其实是因为静态成员无法直接使用未绑定的泛型参数导致的,咱们来拆解问题并给出两种可行的解决方案:
为什么你的泛型版本编译失败?
你尝试直接在非泛型类的静态字段里使用<T,U>,但静态字段属于整个类,而非某个特定的泛型实例——编译器根本不知道T和U应该从哪里获取类型信息,自然没法生成有效的代码。
方案1:用泛型方法替代静态Func字段(推荐)
泛型方法可以直接声明自己的类型参数,调用时编译器还能自动推断类型,是最简洁的解决方案:
static (IEnumerable<T>, IEnumerable<U>) JoinListTuples<T, U>((IEnumerable<T>, IEnumerable<U>) a, (IEnumerable<T>, IEnumerable<U>) b) { return (a.Item1.Concat(b.Item1), b.Item2.Concat(b.Item2)); }
调用的时候完全不用手动指定类型,编译器会自动识别:
var tupleA = (new List<string>{"a"}, new List<int>{1}); var tupleB = (new List<string>{"b"}, new List<int>{2}); var result = JoinListTuples(tupleA, tupleB); // result的类型会被自动推断为(IEnumerable<string>, IEnumerable<int>)
方案2:把静态Func放在泛型类中
如果一定要保留Func字段的形式,你需要把它封装在一个泛型类里——泛型类的静态成员会和类的泛型参数绑定,每个不同的<T,U>组合都会有对应的字段实例:
public static class TupleJoiner<T, U> { public static readonly Func<(IEnumerable<T>, IEnumerable<U>), (IEnumerable<T>, IEnumerable<U>), (IEnumerable<T>, IEnumerable<U>)> Join = (a, b) => (a.Item1.Concat(b.Item1), b.Item2.Concat(b.Item2)); }
调用时需要显式指定泛型参数(或者让编译器推断):
var result = TupleJoiner<string, int>.Join(tupleA, tupleB);
额外说明
两种方案都能实现你要的泛型效果,其中泛型方法更推荐——它不需要额外的类包装,调用体验也更流畅,完全满足你“保留返回值类型”的需求,而且不管元组里的IEnumerable是什么类型,都能正确拼接并返回对应类型的结果。
内容的提问来源于stack exchange,提问作者Robert K. Bell
相关产品推荐
相关产品推荐

