Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Combining delegates and contravariance

Tags:

c#

The article states the following: http://msdn.microsoft.com/en-us/library/dd799517.aspx

Variance does not apply to delegate combination. That is, given two delegates of types Action<Derived> and Action<Base> (Action(Of Derived) and Action(Of Base) in Visual Basic), you cannot combine the second delegate with the first although the result would be type safe. Variance allows the second delegate to be assigned to a variable of type Action<Derived>, but delegates can combine only if their types match exactly.

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

In the above code baction and daction take different parameters. But still I am able to combine them. What am I missing?

TIA.

like image 231
Paramesh Avatar asked May 19 '11 23:05

Paramesh


1 Answers

The documentation is not clear, I agree.

The problem is that the runtime types of two combined delegates must match. Which means that there are scenarios where the compile time types match, but the runtime types do not.

Consider for example:

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

That's legal at compile time; you're adding two delegates of the same compile-time type. But at runtime it will fail because the runtime requires that the runtime types exactly match.

This is an unfortunate hole in the CLR type system. I'm hoping we can get it fixed some day, but no promises.

like image 53
Eric Lippert Avatar answered Oct 17 '22 05:10

Eric Lippert