结合代表和逆转

Par*_*esh 6 c#

该文章陈述如下:http://msdn.microsoft.com/en-us/library/dd799517.aspx

差异不适用于代表组合.也就是说,给定两个类型的委托Action<Derived>Action<Base>(Action(Of Derived)Action(Of Base)在Visual Basic中),您不能将第二个委托与第一个委托合并,尽管结果是类型安全的.Variance允许将第二个委托分配给类型变量Action<Derived>,但委托只有在其类型完全匹配时才能组合.

Action<B> baction = (taret) => { Console.WriteLine(taret.GetType().Name); };
Action<D> daction = baction;
Action<D> caction = baction + daction;
Run Code Online (Sandbox Code Playgroud)

在上面的代码bactiondaction采取不同的参数.但我仍然可以将它们结合起来.我错过了什么?

TIA.

Eri*_*ert 10

我同意,文件不清楚.

问题是两个组合委托的运行时类型必须匹配.这意味着存在编译时类型匹配的情况,但运行时类型不匹配.

考虑例如:

Func<string> f1 = ()=>"";
Func<object> f2 = ()=>null;
Func<object> f3 = f1; // legal in C# 4 because of covariance
Func<object> f4 = f2 + f3;
Run Code Online (Sandbox Code Playgroud)

这在编译时是合法的; 您正在添加两个具有相同编译时类型的委托.但在运行时它会失败,因为运行时要求运行时类型完全匹配.

这是CLR类型系统中的一个不幸的漏洞.我希望有一天我们可以修好它,但没有承诺.

  • 你在外交上没有指出现在正在运作的部分是_you_负责的部分. (3认同)
  • @Eric Lippert:关于推导与可兑换的观点.在某些方面,我希望代表是一个接口而不是类类型; 然而,这样的设计在没有泛型的情况下是无用的,并且当泛型被添加到.net 2.0时,代表已经很好地建立了.如果委托是接口类型,那么类似闭包的东西只需要创建一个对象实例而不是两个.我想知道这种设计的广泛含义是什么? (2认同)
  • @nawfal:这不是一个*逻辑*问题,它是一个*实现*问题.基本上,CLR中处理委托组合的代码不能很好地处理这些协变场景. (2认同)