什么时候C#可以推断参数的类型?

时间:2014-11-28 10:30:32

标签: c# type-inference

为什么以下正确推断出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());
}

2 个答案:

答案 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>());
}