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?

+5
source share
1 answer

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 Select call or use the new operator as per your snippet
  • Directly enter arguments of type Select :

     var fs = numbers.Select<int, Func<string, string>>(n => s => s.Substring(n)); 
+7
source

Source: https://habr.com/ru/post/1209771/


All Articles