c# - 为什么 C# 的重载解析在 Func<T,T> 和 Action<T> 之间不起作用?

标签 c# linq

<分区>

因此,一个相当常见的 IEnumerable 扩展方法,运行:

public static IEnumerable<T> Run<T>(this IEnumerable<T> source, Action<T> action)
{
    foreach (var item in source)
    {
        action(item);
        yield return item;
    }
}

当我尝试将其用于例如 DbSet.Add 时:

invoice.Items.Run(db.InvoiceItems.Add);
// NB: Add method signature is
// public T Add(T item) { ... }

...编译器提示它有错误的返回类型,因为它需要一个 void 方法。因此,为 Run 添加一个重载,它采用 Func 而不是 Action:

public static IEnumerable<T> Run<T>(this IEnumerable<T> source, Func<T, T> action)
{
    return source.Select(action).ToList().AsEnumerable();
}

现在编译器提示“调用在以下方法之间不明确...”

所以我的问题是,Run 方法的 Action 重载对方法组无效时怎么会导致歧义?

最佳答案

Eric 和 Jon 已经在对 this question 的回答中对此进行了解释.长话短说——这就是 C# 编译器的工作方式;准确地说,在处理方法组转换时决定将其转换为哪个委托(delegate)时使用重载决策,不考虑返回类型:

The principle here is that determining method group convertibility requires selecting a method from a method group using overload resolution, and overload resolution does not consider return types.

在您的示例中,编译器同时看到 Action<T>Func<T, T>作为 Add最佳匹配 .这加起来有两个可能的选择,并且由于它需要一个 - 发出适当的错误。

关于c# - 为什么 C# 的重载解析在 Func<T,T> 和 Action<T> 之间不起作用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11225125/

相关文章:

c# - 如何使用 Azure DevOps Pipelines 正确构建 MSI 安装项目?

C# 查找最高数组值和索引

c# - LINQ to Entities 无法识别方法 'Int32 Parse(System.String)' 方法,

c# - 将选定的数据从 DataTable 复制到另一个 DataTable

c# - 检查我的对象是否在 C# 中实现通用接口(interface)

linq - 使用 LINQ 的动态枢轴是否可能?

c# - Linq 递归求和

linq - 将表达式传递给 NHibernate 中的方法会导致类型 'ConstantExpression' 的对象无法转换为类型 'LambdaExpression'

c# - LINQ GroupBy 并选择不同的属性

c# - 如何禁用 dataGridView 中不可点击的按钮(c# windows 应用程序)