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 a LINQ query like so:
Enumerable.Range(1,10).Select(MethodWithDefaultParameters);
This fails with:
Error 1 The type arguments for method 'System.Linq.Enumerable.Select(System.Collections.Generic.IEnumerable, System.Func)' cannot be inferred from the usage. Try specifying the type arguments explicitly.
Of course, I can work around this by inserting a lambda that forwards the function call like this:
Enumerable.Range(1,10).Select(i => MethodWithDefaultParameters(i));
But my question is why does the type inference fail? As far as I can tell, it should not be ambiguous as there is only one variant of the function that satisfies the input variable.
There are two overloads for Select()
. One that takes as the second parameter (i.e. the delegate) a Func<TSource, TResult>
, and one that takes a Func<TSource, int, TResult>
. I.e. a method signature with either one parameter or two.
Your method satisfies neither. Even with the default values, it still has three parameters. Default parameters are a compile-time construct and must be provided at the call site. They aren't filled in at run-time via a call to a delegate instance.
So, in fact, your work-around is one of the two reasonable ways to address the problem. The other would be to implement the default parameters differently (i.e. "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 call to Select()
directly, as the compiler will find the single-parameter overload that is compatible with one of the Select()
overloads.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With