IEnumerable <Func <T, S >> and LINQ type inference
The C # compiler can correctly specify the type s (string) in these fragments:
Func<int, string, string> f1 = (n, s) => s.Substring(n); Func<int, Func<string, string>> f2 = n => s => s.Substring(n); But it cannot be in this [1]:
var numbers = Enumerable.Range(1, 10); IEnumerable<Func<string, string>> fs = numbers.Select(n => s => s.Substring(n)); To make it work, you need to do something like this:
var fs = numbers.Select(n => new Func<string, string>(s => s.Substring(n)); or
var fs = numbers.Select(f2); And the question arises: why type inference does not work in [1] if all the necessary information about types is known in advance?
All type information is not known in advance. In the first working fragment, you talk about this in both lines, for which you need to delegate the type s => s.Substring(n) .
In your second snippet, the only place where this information is present is to assign the result to Select ... and is not used as part of type overloading and input when the compiler designs what the Select call itself is.
So, the options are:
- Do it in two steps using
f2 - Enter a lambda expression in a
Selectcall or use thenewoperator as per your snippet Directly enter arguments of type
Select:var fs = numbers.Select<int, Func<string, string>>(n => s => s.Substring(n));