我使用的是 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/