Co- and Contravariance bugs in .NET 4.0

.net-4.0, c#, covariance, delegates

Solution

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.

Problem

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); } } ``` It's results with `ArgumentException: Delegates must be of the same type.` 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? 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()`? ;) p.s. All this affects the VS2010 RC and later versions.

Original source

Related problems