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

Mar*_*ijn 2 c# type-inference

为什么以下正确推断出T的类型:

void foo<T>(IEnumerable<T> src){
  src.Select(id => id);
}
Run Code Online (Sandbox Code Playgroud)

但这不是:

Func<T, T> Id<T>() {
  return (T t) => t;
}

void foo() {
  new List<int>().Select(Id());
}
Run Code Online (Sandbox Code Playgroud)

Jon*_*eet 8

类型参数推断始终适用于方法参数 - 包括扩展方法的第一个参数Select.

所以你的第二个电话是有效的:

Enumerable.Select(new List<int>(), Id())
Run Code Online (Sandbox Code Playgroud)

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);
Run Code Online (Sandbox Code Playgroud)

  • @Martijn,主要区别在于C#无法推断泛型类型参数是否仅用于返回类型.因此,例如,如果ID是函数本身而不是构建一个,例如`T ID <T>(T t){return t; }`,然后`.Select(ID)`将与lambda一样工作 (2认同)