说我有以下方法:
static int MethodWithDefaultParameters(int a, int b=0, int c=1)
{
return a + b + c;
}
然后我在LINQ查询中使用此方法,如下所示:
Enumerable.Range(1,10).Select(MethodWithDefaultParameters);
这失败了:
错误1方法的类型参数' System.Linq.Enumerable.Select(System.Collections.Generic.IEnumerable,System.Func)'无法从使用中推断出来。尝试明确指定类型参数。
当然,我可以通过插入一个转发函数调用的lambda来解决这个问题:
Enumerable.Range(1,10).Select(i => MethodWithDefaultParameters(i));
但我的问题是为什么类型推断会失败?据我所知,它不应该是模糊的,因为只有一个函数变量满足输入变量。
答案 0 :(得分:10)
Select()
有两个重载。一个将Func<TSource, TResult>
作为第二个参数(即代理人),另一个采用Func<TSource, int, TResult>
。即带有一个参数或两个参数的方法签名。
你的方法既不满足。即使使用默认值,它仍然有三个参数。默认参数是编译时构造,必须在调用站点提供。它们不会在运行时通过调用委托实例来填充。
因此,事实上,您的解决方案是解决问题的两种合理方法之一。另一种方法是以不同方式实现默认参数(即“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;
}
然后你可以直接在MethodWithDefaultParameters
的调用中使用Select()
,因为编译器会找到与Select()
重载之一兼容的单参数重载。