简体   繁体   English

为什么具有返回类型的方法不能与返回void的具有相同签名的委托匹配?

[英]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指定了要返回的stringTest返回了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.

相关问题 为什么部分方法只能有void返回类型? - Why partial methods can only have void return type? 匿名委托可以将返回值作为非void类型吗? - Can anonymous delegate have return value as non void type? 为什么条件方法的返回类型必须为void? - Why does conditional methods must have a return type of void? 为什么类类型参数的方差必须与其方法的返回/参数类型参数的方差相匹配? - Why does the variance of a class type parameter have to match the variance of its methods' return/argument type parameters? 委托 - 委托返回类型是否也必须与其委托的方法相匹配? - Delegates - does the delegate return type have to match the method it is delegating too? 如果可以编写我们自己的等待,那么为什么异步方法只能返回Task <T>,Task和void? - If it's possible to write our own awaitables, then why can async methods only return Task<T>, Task and void? 指定的函数与委托类型&#39;void(void)&#39;不匹配 - the specified function does not match the delegate type 'void (void)' 为什么事件处理程序的返回类型总是 void? - Why do event handlers always have a return type of void? 多播代表的返回类型必须为void。 为什么? - Multicast Delegates must have a return type of void. Why? IEnumerable<T> 与委托的返回值具有相同的类型 - IEnumerable<T> having the same type as the return value of delegate
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM