无法分配委托具有较少特定参数类型的匿名方法

我能够分配一个方法M来委托具有较少特定参数类型的对象d ,但是当我想要将具有相同签名的匿名方法分配给方法Md ,我得到一个错误。

这是为什么?

 class derivedEventArgs : EventArgs { } delegate void newDelegate(object o, derivedEventArgs e); static void Main(string[] args) { newDelegate d = M; // ok d = (object o, EventArgs e) => { }; // error } public static void M(object o, EventArgs e) { } 

Jared当然是正确的,这是设计的。

这种设计的原因是在逆变方法转换的情况下,你可能有一个你没有编写的方法,并将它分配给你没有编写的委托变量。 您无法控制类型。 所以我们对你有点容易,让参数不相容地匹配,返回类型协调匹配。

在lambda-to-delegate转换中,您可以控制所分配的内容。 没有什么可以阻止你使它与参数类型完全匹配,因此我们要求你。 这里不允许捏造。

这在C#语言规范的6.5节中有所介绍。 如果明确键入匿名函数的参数,则它们必须在类型和修饰符中匹配才能成为兼容的签名。

具体地,委托类型D与提供的匿名functionF兼容

如果F具有明确类型化的参数列表,则D中的每个参数与F中的相应参数具有相同的类型和修饰符。

虽然您已得到答案,但如果需要 ,我会提供解决方法。 比如说,你得到的只是签名(object, EventArgs)的委托,在这种情况下,你想将它转换为newDelegate类型,你可以这样做:

 SomeDelegate p = (object o, EventArgs e) => { }; //comes from somewhere NewDelegate d = (o, e) => p(o, e); //can rewrite like this 

或者使用generics委托的generics和(反)方差特征,您可以使用一个委托类型:

 delegate void NewDelegate(object o, T e) where T : EventArgs; //then NewDelegate p = (object o, EventArgs e) => { }; //comes from somewhere NewDelegate d = p; //straightforward assignable - contravariance