c# - 解决编译时函数不正确的BUG?

标签 c# delegates

我使用的是 Visual Studio 2012 Update 1 和 .NET 4.5,这里是代码。

void Test(Action a) { }
void Test(Func<int> a) { }
void TestError()
{
    bool throwException = true;
    //Resolves to Test(Action a)
    Test(() =>
    {
    });
    //Resolves to Test(Action a)
    Test(() =>
    {
        if (throwException) throw new Exception();
    });
    //Resolves to Test(Func<int> a)
    //(This seems like a bug since there is no return value)
    Test(() =>
    {
        throw new Exception();
    });
    //Resolves to Test(Action a)
    //(With warning unreachable code detected)
    Test(() =>
    {
        throw new Exception();
        return; //unreachable code detected
    });
}

看起来最后一个函数调用错误地解析为 Func 而不是 Action,它与无条件抛出异常有关。

这是BUG吗?谢谢。

最佳答案

嗯,在我看来,两者都是有效的候选人似乎是合理的。换句话说,我认为可以转换为 () => { throw new Exception(); }。到两个Func<int>Action .在这两种情况下,方法的末尾都是无法访问的——将其放入像这样的普通命名方法中是完全有效的:

public int GoBang()
{
    throw new Exception();
}

然后写:

Func<int> foo = GoBang;

因此,从 lambda 表达式到 Func<int> 的转换和 Action有效。我们现在需要选择使用哪种方法。这在规范第 7.5.3.2 节(更好的函数成员)中指定,其中包括:

For at least one argument, the conversion from Ex to Px is better than the conversion from from Ex to Qx

此时,第 7.5.3.3 节(更好地从表达式转换)开始:

C1 is a better conversion than C2 if at least one of the following holds:

  • [...]
  • E is an anonymous function, T1 is either a delegate type D1 or an expression tree type Expression<D1>, T2 is either a delegate type D2 or an expression tree type Expression<D2>, and one of the following holds:

    • [...]
    • D1 and D2 have identical parameter lists, and one of the following holds:
    • D1 has a return type Y, and D2 is void returning.

这就是为什么 Func<int>优先于 Action ...编译器正在做正确的事情。

关于c# - 解决编译时函数不正确的BUG?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15003876/

相关文章:

c# - C#中的触发事件

javascript - C# Regex.Split 的工作方式与 JavaScript 不同

c# - 在 IIS 中托管 ASP.NET Core 时不会动态压缩响应

ios - 将 View Controller 连接到委托(delegate)类 - CLLocationManager/iOS8

c# - 如何在后台加载图像?

c# - 从 .NET Windows 服务检测系统待机/ sleep /休眠?

c# - 如何手动编程 Int.Parse()

在自己的线程中执行的线程之间的 C# 事件(如何)?

jquery ui 自动完成与委托(delegate)

iphone - obj.delegate=self 是什么意思?