Event and delegate contravariance in .NET 4.0 and C# 4.0?

Very interesting. You don't need to use events to see this happening, and indeed I find it simpler to use simple delegates.

Very interesting. You don't need to use events to see this happening, and indeed I find it simpler to use simple delegates. Consider Func and Func.In C# 4.0 you can implicitly convert a Func to Func because you can always use a string reference as an object reference.

However, things go wrong when you try to combine them. Here's a short but complete program demonstrating the problem in two different ways: using System; class Program { static void Main(string args) { Func stringFactory = () => "hello"; Func objectFactory = () => new object(); Func multi1 = stringFactory; multi1 += objectFactory; Func multi2 = objectFactory; multi2 += stringFactory; } } This compiles fine, but both of the Combine calls (hidden by the += syntactic sugar) throw exceptions.(Comment out the first one to see the second one. ) This is definitely a problem, although I'm not exactly sure what the solution should be.

It's possible that at execution time the delegate code will need to work out the most appropriate type to use based on the delegate types involved. That's a bit nasty. It would be quite nice to have a generic Delegate.

Combine call, but you couldn't really express the relevant types in a meaningful way. One thing that's worth noting is that the covariant conversion is a reference conversion - in the above, multi1 and stringFactory refer to the same object: it's not the same as writing Func multi1 = new Func(stringFactory); (At that point, the following line will execute with no exception. ) At execution time, the BCL really does have to deal with a Func and a Func being combined; it has no other information to go on.

It's nasty, and I seriously hope it gets fixed in some way. I'll alert Mads and Eric to this question so we can get some more informed commentary.

Thanks Jon. We'll look into it. – Eric Lippert Jul 13 '09 at 19:15 Cool, I arrived at practically the same example code when tinkering with it on the train home.

Would be very interesting to hear the gnarly details. – Daniel Earwicker Jul 13 '09 at 19:18.

If the exception is being thrown by just the new handler, then I would think that it's backward-compatible. BTW, I think you have your comments mixed up.In C# 3.0 this: button. Click += new EventHandler(button_Click); // old wouldn't have run.

That's c#4.0.

I've removed all references to versioning in the question, as it seems to have just caused you confusion. The comments about new and old related to the issue I was originally thinking about, which I split this question out from. This question has nothing to do with backward compatibility per se.It's about the compiler assuming that a multicast delegate can bind to methods of contravariant types, which then turns out not to be true at runtime.

– Daniel Earwicker Jul 13 '09 at 19:04.

I cant really gove you an answer,but what I can give you is a way to a solution, that is you have to find the anglde that you relate to or peaks your interest. A good paper is one that people get drawn into because it reaches them ln some way.As for me WW11 to me, I think of the holocaust and the effect it had on the survivors, their families and those who stood by and did nothing until it was too late.

Related Questions