1

我对 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指定 a stringbe returned 和Testreturned void,我们就会遇到问题。所以,我完全同意这种情况会导致编译器错误。但是,为什么不能int Test(string) 隐式匹配委托void Foo(string)

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

4

1 回答 1

1

C# 规范(第 15.2 节委托兼容性)有这样的说法。

如果满足以下所有条件,则方法或委托 M 与委托类型 D 兼容:

...

· 存在从 M 的返回类型到 D 的返回类型的标识或隐式引用转换。

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

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

public Action Ignore<T>(Func<T> call)
{
    return () => call();
}
于 2013-09-20T00:32:06.947 回答