C# 类型推断因包含默认参数的方法而失败
C# Type Inference fails with methods that contain default parameters
假设我有以下方法:
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>
作为第二个参数(即委托),另一个将 Func<TSource, int, TResult>
作为第二个参数。 IE。带有一个或两个参数的方法签名。
你的方法都不满足。即使使用默认值,它仍然具有三个参数。默认参数是一个 compile-time 构造,必须在调用站点提供。它们不会在 运行 时通过调用委托实例填写。
所以,事实上,您的解决方法是解决问题的两种合理方法之一。另一种是以不同方式实现默认参数(即 "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;
}
然后您可以在对 Select()
的调用中直接使用 MethodWithDefaultParameters
,因为编译器会找到与 Select()
重载之一兼容的单参数重载。
假设我有以下方法:
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>
作为第二个参数(即委托),另一个将 Func<TSource, int, TResult>
作为第二个参数。 IE。带有一个或两个参数的方法签名。
你的方法都不满足。即使使用默认值,它仍然具有三个参数。默认参数是一个 compile-time 构造,必须在调用站点提供。它们不会在 运行 时通过调用委托实例填写。
所以,事实上,您的解决方法是解决问题的两种合理方法之一。另一种是以不同方式实现默认参数(即 "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;
}
然后您可以在对 Select()
的调用中直接使用 MethodWithDefaultParameters
,因为编译器会找到与 Select()
重载之一兼容的单参数重载。