方法推理不适用于方法组 [英] Method Inference does not work with method group

查看:31
本文介绍了方法推理不适用于方法组的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

考虑

void Main()
{
    var list = new[] {"1", "2", "3"};
    list.Sum(GetValue); //error CS0121
    list.Sum(s => GetValue(s)); //works !
}

double GetValue(string s)
{
    double val;
    double.TryParse(s, out val);
    return val;
}

CS0121 错误的描述是

The description for the CS0121 error is

以下方法或属性之间的调用不明确:'System.Linq.Enumerable.Sum(System.Collections.Generic.IEnumerable,System.Func)''System.Linq.Enumerable.Sum(System.Collections.Generic.IEnumerable,System.Func)'

The call is ambiguous between the following methods or properties: 'System.Linq.Enumerable.Sum<string>(System.Collections.Generic.IEnumerable<string>, System.Func<string,decimal>)' and 'System.Linq.Enumerable.Sum<string>(System.Collections.Generic.IEnumerable<string>, System.Func<string,decimal?>)'

我不明白的是,s => 是什么信息?GetValue(s) 为编译器提供了简单的 GetValue 不 - 后者不是前者的语法糖吗?

What I don't understand is, what information does s => GetValue(s) give the compiler that simply GetValue doesn't - isn't the latter syntactic sugar for the former ?

推荐答案

Mark 的回答是正确的,但可以使用更多的解释.

Mark's answer is correct but could use a bit more explanation.

问题确实是由于方法组的处理方式和 lambda 的处理方式之间存在细微差别.

The problem is indeed due to a subtle difference between how method groups are handled and how lambdas are handled.

具体来说,细微的区别在于,一个方法组被认为可转换为委托类型仅根据参数是否匹配,而不是根据返回类型匹配. Lambdas 检查参数和返回类型.

Specifically, the subtle difference is that a method group is considered to be convertible to a delegate type solely on the basis of whether the arguments match, not also on the basis of whether the return type matches. Lambdas check both the arguments and the return type.

这个奇怪规则的原因是方法组转换为委托本质上是重载解决问题的解决方案.假设 D 是委托类型 double D(string s) 并且 M 是包含一个方法的方法组,该方法接受一个字符串并返回一个字符串.在解析从 M 到 D 的转换的含义时,我们进行重载解析,就像您说 M(string) 一样.重载解析会选择接受一个字符串并返回一个字符串的 M,因此 M 可以转换为该委托类型即使转换以后会导致错误.就像常规"重载解析会成功一样,如果您说string s = M(null);"-- 重载解析成功,即使稍后会导致转换失败.

The reason for this odd rule is that method group conversions to delegates are essentially a solution of the overload resolution problem. Suppose D is the delegate type double D(string s) and M is a method group containing a method that takes a string and returns a string. When resolving the meaning of a conversion from M to D, we do overload resolution as if you had said M(string). Overload resolution would pick the M that takes a string and returns a string, and so M is convertible to that delegate type even though the conversion will result in an error later. Just as "regular" overload resolution would succeed if you said "string s = M(null);" -- overload resolution succeeds, even though that causes a conversion failure later.

这个规则很微妙,也有点奇怪.这里的结果是您的方法组可以转换为所有不同的委托类型,它们是每个接受委托的 Sum 版本的第二个参数.由于找不到最佳转换,方法组 Sum 上的重载解析不明确.

This rule is subtle and a bit weird. The upshot of it here is that your method group is convertible to all the different delegate types that are the second arguments of every version of Sum that takes a delegate. Since no best conversion can be found, the overload resolution on method group Sum is ambiguous.

方法组转换规则是合理的,但在 C# 中有点奇怪.我有点恼火,因为它们与更直观正确"的 lambda 转换不一致.

Method group conversions rules are plausible but a bit odd in C#. I am somewhat vexed that they are not consistent with the more "intuitively correct" lambda conversions.

这篇关于方法推理不适用于方法组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆