为什么以下正确推断出T的类型:
void foo<T>(IEnumerable<T> src){
src.Select(id => id);
}
但这并不是:
Func<T, T> Id<T>() {
return (T t) => t;
}
void foo() {
new List<int>().Select(Id());
}
答案 0 :(得分:8)
类型参数推断始终适用于方法参数 - 包括Select
等扩展方法的第一个参数。
所以你的第二个电话是有效的:
Enumerable.Select(new List<int>(), Id())
Select
将能够使用这些参数来推断那里的类型参数,但Id()
调用没有任何参数,类型推断也不会尝试工作根据使用方法的方式,类型参数应该是什么。
换句话说,它不是Select
这里的问题 - 它是Id()
。所以这会奏效:
// No type inference available
var idFunc = Id<int>();
// Type argument to Select is inferred
var selection = new List<int>.Select(idFunc);
答案 1 :(得分:1)
第7.4.2节类型推断
如果提供的参数数量不同于 方法中的参数,然后推断立即失败。否则, 假设泛型方法具有以下签名:
Tr M(T1 x1 ... Tm xm)
使用M(E1 ... Em)形式的方法调用,类型推断的任务是 为每个类型参数找到唯一的类型参数S1 ... Sn X1 ... Xn使呼叫M(E1 ... Em)有效。
此代码应该可以正常工作:
Func<T, T> Id<T>()
{
return (T t) => t;
}
void foo()
{
new List<int>().Select(Id<int>());
}