When can C# infer the type of a parameter?

Why does the following correctly infer the type of T:

void foo<T>(IEnumerable<T> src){
  src.Select(id => id);
}

But this doesn't:

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

void foo() {
  new List<int>().Select(Id());
}
Jon Skeet
people
quotationmark

Type argument inference always works on method arguments - including the first argument to an extension method like Select.

So your second call is effectively:

Enumerable.Select(new List<int>(), Id())

Select will be able to use those arguments to infer the type argument there, but the Id() call doesn't have any arguments, and type inference doesn't try to work out what the type argument should be based on how the method is used.

In other words, it's not Select that's the problem here - it's Id(). So this would work:

// No type inference available
var idFunc = Id<int>();
// Type argument to Select is inferred
var selection = new List<int>.Select(idFunc);

people

See more on this question at Stackoverflow