在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
这种行为和语言设计决策背后的原因是什么。
答案 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 { .... }