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

时间:2013-09-19 20:56:48

标签: c# .net clr

我对C#代理的限制非常好奇。请使用以下代码,编译:

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;
   }
}

这里的错误是委托Foo没有返回类型,因此不能用于创建对函数Test的引用。

然而,为什么这是一个问题?显然,如果要通过委托Test致电f,他们将无法访问Test的返回值,这是完全公平的,但是在我看来,编译器仍然可以通过简单地忽略返回值来生成类型安全代码,甚至可以优化该情况。

显然,如果情况发生逆转,Foo指定了string并且Test返回void,我们就会遇到问题。所以,我完全同意 案例应该导致编译器错误。但是,为什么int Test(string) 无法隐式匹配委托void Foo(string)

我正在寻找两种可能的答案之一:一,允许这种能力的逻辑问题。是否存在通过委托调用方法时忽略返回类型会导致不安全情况的情况?或者,二,对C#规范的引用,阐明了为什么这种实现会违反规范。

1 个答案:

答案 0 :(得分:1)

C#规范(第15.2节“委托兼容性”)就是这样说的。

  

如果全部,则方法或委托M与委托类型D兼容   以下是真实的:

     

...

     

·存在身份或隐式引用转换   将M的类型返回到D的返回类型。

任何类型和空白之间都没有这种转换,因此根据规范不允许这样做。

很可能它可以在逻辑上完成,我不确定,但与其他功能相比,它可能没有足够大的用例。为自己创建一个包装器也相当容易,这也减少了用例需求。

public Action Ignore<T>(Func<T> call)
{
    return () => call();
}