C # type inference terminates using methods that contain default parameters

Let's say I have the following method:

static int MethodWithDefaultParameters(int a, int b=0, int c=1) { return a + b + c; } 

And then I use this method in the LINQ query as follows:

 Enumerable.Range(1,10).Select(MethodWithDefaultParameters); 

This fails:

Error 1 Type arguments for the method "System.Linq.Enumerable.Select (System.Collections.Generic.IEnumerable, System.Func)" cannot be taken out of use. Try explicitly specifying type arguments.

Of course, I can get around this by inserting a lambda that redirects the function call as follows:

 Enumerable.Range(1,10).Select(i => MethodWithDefaultParameters(i)); 

But my question is why type inference fails? As far as I can tell, this should not be ambiguous, since there is only one variant of the function that satisfies the input variable.

+6
source share
1 answer

There are two overloads for Select() . One that takes as its second parameter (i.e., the Delegate) a Func<TSource, TResult> , and one that accepts Func<TSource, int, TResult> . That is, a method signature with one or two parameters.

Your method does not satisfy either one or the other. Even with default values, it still has three parameters. The default parameters are a compilation time construct and must be provided on the call site. They are not populated at run time by invoking the delegate instance.

So, in fact, your work is one of two reasonable ways to solve the problem. Another would be to implement the default settings in different ways (ie, "Old School" :)):

 static int MethodWithDefaultParameters(int a) { return MethodWithDefaultParameters(a, 0, 1); } static int MethodWithDefaultParameters(int a, int b, int c) { return a + b + c; } 

Then you can use MethodWithDefaultParameters in your Select() call directly, since the compiler will find a one-parameter overload compatible with one of the Select() overloads.

+10
source

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


All Articles