C# 类型推断因包含默认参数的方法而失败

标签 c# type-inference

假设我有以下方法:

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/

相关文章:

scala - 创建部分应用函数时的类型推断

generics - 如何强制客户端代码使用合约初始化 Kotlin 中所有必需的构建器字段?

c# - 如何在wpf中单击按钮时更新文本框背景色

c# - 如何将字符串转换为下拉列表?

c# - 为什么隐式使用 ToString() 不会导致异常?

typescript - 键在应该用于索引类型时却不能使用

c# - 允许唤醒定时器 Windows 7/Vista

c# - 如何使用 Linq 或其他方式从列表中删除匹配项

generics - f# 成员约束和 IEnumerable 集合

c# - 如何从实际类型推断 TResult?