[英]Why can't methods that have a return type match a delegate of the same signature that returns void?
I'm rather curious about this limitation of C# delegates. 我对C#委托的这种限制感到很好奇。 Take the following code, which does not compile: 使用以下代码,该代码无法编译:
class Program
{
delegate void Foo(string s);
static void Main(string[] args)
{
Foo f = Test; // Error
f("Hello");
}
static int Test(string s)
{
return s.Length;
}
}
The error here is that the delegate Foo
does not have a return type, thus cannot be used to create a reference to the function Test
. 这里的错误是委托Foo
没有返回类型,因此不能用于创建对函数Test
的引用。
However, why is this a problem? 但是,为什么这是一个问题呢? Obviously, if one were to call Test
through the delegate f
, they would not have access to Test
's return value, which is perfectly fair, but it seems to me that the compiler could still generate type safe code by simply ignoring the return value, perhaps even being able to optimize that case. 显然,如果要通过委托f
调用Test
,他们将无法访问 Test
的返回值,这很公平,但是在我看来,编译器仍然可以通过简单地忽略返回值来生成类型安全的代码 。 ,甚至可以优化这种情况。
Obviously, if the situation were reversed, and Foo
specified a string
be returned and Test
returned void
, we'd have a problem. 显然,如果情况发生了逆转,并且Foo
指定了要返回的string
而Test
返回了void
,那么我们将遇到问题。 So, I fully agree that that case should result in a compiler error. 所以,我完全同意, 这种情况下应导致编译器错误。 However, why can't int Test(string)
implicitly match the delegate void Foo(string)
? 但是,为什么int Test(string)
隐式匹配委托void Foo(string)
?
I'm looking for one of two possible answers: One, a logical issue with allowing this ability. 我正在寻找以下两个可能的答案之一:一个是允许使用此功能的逻辑问题。 Is there a case where ignoring the return type when calling a method through a delegate would cause an unsafe condition? 是否存在通过委托调用方法时忽略返回类型会导致不安全情况的情况? Or, two, a reference to the C# specification that clarifies why this implementation would violate the spec. 或者,两个,对C#规范的引用,阐明了为什么此实现会违反规范。
The C# specification (section 15.2 Delegate Compatibility) had this to say. C#规范(第15.2节“代理兼容性”)就是这样说的。
A method or delegate M is compatible with a delegate type D if all of the following are true: 如果满足以下所有条件,则方法或委托M与委托类型D兼容:
... ...
· An identity or implicit reference conversion exists from the return type of M to the return type of D. ·存在从M的返回类型到D的返回类型的标识或隐式引用转换。
There is no such conversion between any type and void, so this should not be allowed according to the spec. 在任何类型和void之间都没有这种转换,因此根据规范不允许这样做。
It may very well be that it could be logically done, I'm not sure, but there may not have been a big enough use case for it compared to other features. 我不确定这很可能在逻辑上完成,但是与其他功能相比,它可能没有足够大的用例。 It's also fairly easy to create a wrapper for that yourself, which also lessens the use case need. 为自己创建一个包装器也很容易,这也减少了用例的需求。
public Action Ignore<T>(Func<T> call)
{
return () => call();
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.