我能够为方法M
分配一个方法d
,使用一个不太具体的参数类型,但当我想指定一个匿名方法时,签名与方法{{1}相同} M
,我收到错误。
为什么?
d
答案 0 :(得分:16)
这在C#语言规范的6.5节中有所介绍。如果明确键入匿名函数的参数,则它们必须在类型和修饰符中匹配才能成为兼容的签名。
具体而言,委托类型D与提供的匿名函数F兼容
...
如果F具有显式类型参数列表,则D中的每个参数与F中的相应参数具有相同的类型和修饰符。
答案 1 :(得分:15)
Jared当然是正确的,这是设计的。
该设计的原因是在逆变方法转换的情况下,您可能有一个未编写的方法,并将其分配给您未编写的委托变量。您无法控制类型。所以我们对你有点容易,让参数不相容地匹配,返回类型可以协调匹配。
在lambda-to-delegate转换中,执行控制所分配的内容。没有什么停止你使它与参数类型完全匹配,因此我们要求你。这里不允许捏造。
答案 2 :(得分:2)
虽然您已得到答案,但如果需要,我将提供解决方法。比如说,你得到的只是签名(object, EventArgs)
的代表,在这种情况下,你想将它转换为你的newDelegate
类型,你可以这样做:
SomeDelegate p = (object o, EventArgs e) => { }; //comes from somewhere
NewDelegate d = (o, e) => p(o, e); //can rewrite like this
或者通用代理的泛型和(反)方差特征,您可以使用一个代理类型:
delegate void NewDelegate<in T>(object o, T e) where T : EventArgs;
//then
NewDelegate<EventArgs> p = (object o, EventArgs e) => { }; //comes from somewhere
NewDelegate<DerivedEventArgs> d = p; //straightforward assignable - contravariance