假设我有以下方法:
static int MethodWithDefaultParameters(int a, int b=0, int c=1)
{
return a + b + c;
}
然后我在 LINQ 查询中使用此方法,如下所示:
Enumerable.Range(1,10).Select(MethodWithDefaultParameters);
这失败了:
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.
当然,我可以通过插入一个像这样转发函数调用的 lambda 来解决这个问题:
Enumerable.Range(1,10).Select(i => MethodWithDefaultParameters(i));
但我的问题是为什么类型推断会失败?据我所知,它不应该是模棱两可的,因为只有一种函数变体满足输入变量。
最佳答案
Select()
有两个重载.一个将 Func<TSource, TResult>
作为第二个参数(即委托(delegate)) ,还有一个需要 Func<TSource, int, TResult>
. IE。带有一个或两个参数的方法签名。
您的方法都不满足。即使使用默认值,它仍然具有三个参数。默认参数是编译时 构造,必须在调用站点提供。它们不会在运行时通过调用委托(delegate)实例来填充。
因此,实际上,您的解决方法是解决问题的两种合理方法之一。另一种是以不同方式实现默认参数(即“老派”:)):
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()
之一兼容的单参数重载过载。
关于C# 类型推断因包含默认参数的方法而失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28493104/