问题描述
C# 4.0 协变和逆变支持的一些奇怪行为:
Some strange behavior with the C# 4.0 co- and contravariance support:
using System;
class Program {
static void Foo(object x) { }
static void Main() {
Action<string> action = _ => { };
// C# 3.5 supports static co- and contravariant method groups
// conversions to delegates types, so this is perfectly legal:
action += Foo;
// since C# 4.0 much better supports co- and contravariance
// for interfaces and delegates, this is should be legal too:
action += new Action<object>(Foo);
}
}
ArgumentException: Delegates must be the same type 的结果.
很奇怪,不是吗?为什么 Delegate.Combine()
(在对委托执行 +=
操作时调用)在运行时不支持协变和逆变?
Strange, isn't it? Why Delegate.Combine()
(which is been called when performing +=
operation on the delegates) does not support co- and contravariance at runtime?
此外,我发现 BCL 的 System.EventHandler
TEventArgs
参数上没有逆变注释!为什么?这是完全合法的, TEventArgs
类型仅用于输入位置.也许没有逆变注释,因为它很好地隐藏了 Delegate.Combine()
的错误?;)
Moreover, I've found that BCL's System.EventHandler<TEventArgs>
delegate type does not has contravariant annotation on it's generic TEventArgs
parameter! Why? It's perfectly legal, TEventArgs
type used only at input position. Maybe there is no contravariant annotation because of it nicely hides the bug with the Delegate.Combine()
? ;)
附言所有这些都会影响 VS2010 RC 及更高版本.
p.s. All this affects the VS2010 RC and later versions.
推荐答案
长话短说:就方差而言,委托组合都搞砸了.我们在周期的后期发现了这一点.我们正在与 CLR 团队合作,看看我们是否可以想出一些方法来使所有常见场景都工作而不会破坏向后兼容性等等,但是我们想出的任何东西都可能不会进入 4.0 版本.希望我们能在一些服务包中解决所有问题.对于给您带来的不便,我深表歉意.
Long story short: delegate combining is all messed up with respect to variance. We discovered this late in the cycle. We're working with the CLR team to see if we can come up with some way to make all the common scenarios work without breaking backwards compatibility, and so on, but whatever we come up with will probably not make it into the 4.0 release. Hopefully we'll get it all sorted out in some service pack. I apologize for the inconvenience.
这篇关于.NET 4.0 中的协变和逆变错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!