4

请考虑以下代码:

class Program
{
    static void Foobar() { }
    static void Test(Action a) { }
    static void Test(Func<bool> a) { }
    static void Main(string[] args)
    {
        Test(Foobar);
    }
}

它不能在 VS2012 上编译。编译器抱怨说,该行中对方法 Foobar 的引用Test(Foobar)是模棱两可的。这是我收到的全部错误消息:

The call is ambiguous between the following methods or properties: 
'Program.Test(System.Action)' and 'Program.Test(System.Func<bool>)'

现在,解决方法是将 Foobar 强制转换为 Action 以强制正确的重载:Test((Action)Foobar).

但我对原因很感兴趣,为什么 C# 不能自己解决这个问题?为什么他必须认为 aFunc<bool>将是 - 函数的有效重载void()

我知道您不能使用仅在返回类型上有所不同的另一种方法来重载方法。但这里似乎并非如此。我没有超载Foobar()。当然,返回值可能不是 Foobar 签名的一部分,但在从方法组转换为委托时,为什么这很重要?

我也意识到这个问题,编译器有时拒绝将具有重载方法的方法组转换为特定的委托,即使他可以拥有他需要的所有信息,但我认为这是一个不同的问题(和不同的错误消息) . 再次 - Foobar 没有超载。只是Test()


编辑:正如马修指出的那样,问题与链接的问题相同。但是,我对 Eric Lippert 和 Jon Skeet 给出的(非常好的)答案并不是 100% 满意。

在他的回答的一部分中,埃里克说:

这里的原则是确定方法组的可转换性需要使用重载决议从方法组中选择一个方法,而重载决议不考虑返回类型

任何线索为什么会这样?对我来说,解决问题的方法似乎就是改变上面这句话,并且在从方法组中选择方法时还要考虑返回类型。期间,结束了,每个人都很高兴,不是吗?;)

为什么这个模棱两可的错误很糟糕的一个实际例子是,Task.Run()不能在没有强制转换的情况下用于void()自己类的 -methods。因此,即使在我看到的一些 MSDN 示例中,它们也使用Task.Run(() => Foobar())了更清洁的Task.Run(Foobar).

4

1 回答 1

0

因为可以在没有任何参数的情况下调用两个委托:

Action action = new Action(() => ...);
Func<bool> func = new Func<bool>(() => true);

action();
func(); // Legal even if you ignore the return value

解决重载时不考虑返回类型。

于 2013-06-05T08:59:53.127 回答