C# 为什么所有委托类型都彼此不兼容?
在C#中,所有委托类型彼此不兼容,即使它们具有相同的签名。例如:C# 为什么所有委托类型都彼此不兼容?,c#,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 这种行为和语言设计决策背后的原因是什么。基本上是因
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
这种行为和语言设计决策背后的原因是什么。基本上是因为编译器为您生成了两个类。同样的原因,你不能这样做:
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
委托只是另一种类型。它们不兼容的原因与
A类{}
和B类{}
不兼容的原因相同
delegate void D1();
将大致编译为以下内容:
class D1 : MulticastDelegate { .... }
在C#中,所有委托类型彼此不兼容,即使它们具有相同的签名。这种行为和语言设计决策背后的原因是什么
首先,我认为公平地说,许多运行时和语言设计师对这个决定感到遗憾。委托上的结构类型(即,通过签名进行匹配)是一个经常需要的功能,而Func
和谓词
不能自由分配给彼此似乎很奇怪
据我所知,这个决定背后的原因是——我赶紧补充说,这个决定是在我加入C#团队的六年前做出的——人们期望会有具有语义的委托类型。您希望这是一个类型错误:
AnyFunction<int, int> af = x=> { Console.WriteLine(x); return x + y; };
PureFunction<int, int> pf = af;
AnyFunction af=x=>{Console.WriteLine(x);返回x+y;};
纯函数pf=af;
“纯”函数是一个函数,它不产生和使用任何副作用,不使用参数以外的信息,并且在给定相同参数时返回一致的值。显然,af
至少有两个失败,因此不应作为隐式转换分配给pf
但是充满语义的委托类型从未出现过,所以现在有点不合适。我无法给出理由,但委托是一种原始的语言功能。从那时起,他们增加了lambda方法,而这些方法不会遇到同样的问题。@Brandon什么?lambda转换为委托(或表达式树),
Action
s和Func
s只是委托类型,因此它们遵循完全相同的规则。委托调用也会在运行时检查。这是一种重要的优化,只支持严格的类型标识。这很快。@s区别在于Actions、Funcs和lambda表达式隐式转换为您指定给它们的委托类型,甚至允许稍有不同的签名,这正是OP所抱怨的。@Brandon关于Action
s和Func
s确实没有什么特别之处,他们的工作方式与任何其他代理类型完全相同。我必须记住“不完美”这个词。我会满怀爱意地记得,在很短的时间内,我得到了一个比埃里克·利珀特(Eric Lippert)票数更多的答案。