为什么所有委托类型都互不兼容?

时间:2013-06-20 13:02:59

标签: c#

在C#中,所有委托类型彼此不兼容,即使它们具有相同的签名。举个例子:

delegate void D1();
delegate void D2();

D1 d1 = MethodGroup;
D2 d2 = d1;                           // compile time error
D2 d2 = new D2 (d1);                  // you need to do this instead

这种行为和语言设计决策背后的原因是什么。

3 个答案:

答案 0 :(得分:23)

  

在C#中,所有委托类型彼此不兼容,即使它们具有相同的签名。这种行为和语言设计决策背后的原因是什么?

首先,我认为可以说许多运行时和语言设计者都对此决定感到遗憾。对代理进行结构化键入 - 即通过签名进行匹配 - 是一种经常被请求的功能,Func<int, bool>Predicate<int>无法自由分配给对方似乎很奇怪。

我理解这个决定背后的原因 - 而且我不得不补充一点,这个决定是在我开始使用C#团队大约六年之前做出的 - 是期望会有与语义。您希望这是一个类型错误:

AnyFunction<int, int> af = x=> { Console.WriteLine(x); return x + y; };
PureFunction<int, int> pf = af;

“纯”函数是一种产生和消耗无副作用的函数,在其参数之外不消耗任何信息,并在给定相同参数时返回一致值。显然af至少失败了其中两个,因此不应将pf指定为隐式转换。

但是语义学的代表类型从未发生过,所以现在有些错误。

答案 1 :(得分:15)

基本上是因为编译器会为你创建两个类。你不能这样做的原因是:

class A {}
class B {}

void Main()
{
    A a = new A();
    B b = a;
}

例如,以下代码

void Main() {}

delegate void D();
class C {}

IL代码是:

D.Invoke:

D.BeginInvoke:

D.EndInvoke:

D..ctor:

C..ctor:
IL_0000:  ldarg.0     
IL_0001:  call        System.Object..ctor
IL_0006:  ret         

答案 2 :(得分:2)

委托只是另一种类型。由于class A {}class B {}不兼容,它们不兼容。

delegate void D1();

将近似编译为:

class D1 : MulticastDelegate { .... }