C#类型推断:求类型参数依赖未固定类型参数的示例
理解C#双阶段类型推断中的“类型参数依赖未固定类型参数”
先看你写的代码为什么运行失败:
你的foo方法中,第一个实参是List<int>,所以type1会被推断为int,但你给的lambda参数写成了string str,这和type1=int冲突;另外你还把Length拼写成了Lenth,这两个问题导致编译失败。
什么是“类型参数依赖未固定类型参数”
简单来说,就是某个泛型类型参数的推断结果,必须以另一个还没被确定(未固定)的类型参数的推断结果为前提,没法直接从实参独立推断出来。
示例代码
下面是一个典型的场景,其中U的推断依赖于先确定T:
using System; using System.Linq; class Program { // 泛型方法:接收T类型输入,通过转换器得到List<U>,再处理这个列表 static void ProcessAndWrap<T, U>(T input, Func<T, System.Collections.Generic.List<U>> wrapper) { var wrappedResult = wrapper(input); Console.WriteLine($"转换后列表元素数量:{wrappedResult.Count}"); Console.WriteLine($"第一个元素:{wrappedResult[0]}"); } static void Main() { // 调用方法:输入是字符串,转换器把字符串按逗号分割成字符串列表 ProcessAndWrap("apple,banana,orange", str => str.Split(',').ToList()); } }
推断过程分析
第一阶段:确定不依赖其他参数的类型参数
第一个实参是字符串"apple,banana,orange",所以T可以直接被确定为string,不需要依赖任何其他未固定的类型参数。第二阶段:推断依赖已固定参数的类型参数
现在T已经固定为string,wrapper参数的类型就明确为Func<string, List<U>>。查看lambda表达式str => str.Split(',').ToList():str的类型是string(因为T=string)str.Split(',')返回string[],调用ToList()后得到List<string>
因此U被推断为string。
另一个更直观的示例(双向依赖场景)
如果我们调整方法参数,让两个类型参数互相依赖,必须分阶段推断:
static void RoundTripConvert<T, U>(T initialValue, Func<T, U> forwardConvert, Func<U, T> backwardConvert) { U converted = forwardConvert(initialValue); T restored = backwardConvert(converted); Console.WriteLine($"初始值:{initialValue},转换后还原:{restored}"); } // 调用 RoundTripConvert(100, num => num.ToString(), str => int.Parse(str));
推断过程:
- 第一阶段:
initialValue是int,所以T被固定为int。 - 第二阶段:
forwardConvert是Func<int, U>,lambda返回string,因此U被推断为string;同时backwardConvert的参数类型也匹配U=string,返回int匹配T=int,验证通过。
内容的提问来源于stack exchange,提问作者HeartBleed
相关产品推荐
相关产品推荐

