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

Ale*_*exC 13 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
Run Code Online (Sandbox Code Playgroud)

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

Eri*_*ert 23

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

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

正如我所理解的那样,这个决定背后的原因 - 并且我必须补充一点,这个决定是在我开始使用C#团队大约六年之前做出的 - 期望是会有代理类型带有语义.您希望这是一个类型错误:

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

"纯"函数是一种产生和不消耗副作用的函数,在其参数之外不消耗任何信息,并在给定相同参数时返回一致值.显然af至少失败了两个,所以不应该pf作为隐式转换赋值.

但是语义学上的委托类型从未发生过,所以现在它有点像错误.


dav*_*v_i 15

基本上是因为编译器为你创建了两个类.你做不到同样的原因:

class A {}
class B {}

void Main()
{
    A a = new A();
    B b = a;
}
Run Code Online (Sandbox Code Playgroud)

例如,以下代码

void Main() {}

delegate void D();
class C {}
Run Code Online (Sandbox Code Playgroud)

IL代码是:

D.Invoke:

D.BeginInvoke:

D.EndInvoke:

D..ctor:

C..ctor:
IL_0000:  ldarg.0     
IL_0001:  call        System.Object..ctor
IL_0006:  ret         
Run Code Online (Sandbox Code Playgroud)