Before you read this, go over and watch last week's DotNetRocks TV. I'll wait.

Finished?

Ok, in that episode, Venkat talks about "covariance" and "contravariance" in delegates in .NET 2.0. The idea is that a delegate that takes a certain type as a parameter can be pointed at a method that actually takes a different type, provided the method's parameter is an ancestor class of the delegate's parameter.

The example he gives is a "StockSellDelegate" which takes a "Stock" parameter, and the method that gets called is an "EquitySold" method, which actually takes an "Equity" parameter. Because "Stock" derives from "Equity", the code compiles and it works fine.

Venkat, however, doesn't mention the one really cool result of this added feature.

As you know, all events in .NET follow a certain pattern. They all take a "sender" parameter of type "object", and an "e" parameter of some other type. Typically it's "EventArgs" but sometimes it's some other type. For example, the "KeyDown" event has a "KeyEventArgs" as its second parameter.

Contravariance in delegates means that it's possible to use the same event handler to handle both the "Click" and "KeyDown" event of a control, because "KeyEventArgs" derives from "EventArgs". So I can have this code:

 private void button1_Click(object sender, EventArgs e) { MessageBox.Show("button1 clicked or key pressed!"); } private void Form1_Load(object sender, EventArgs e) { button1.Click += button1_Click; button1.KeyDown += button1_Click; } 

And it compiles and runs just fine.

Obviously this is a contrived example, but the ability to use the same event handler for events that take different "e" parameters can be very handy.

Imagine a special kind of MenuItem, for example, that passed extra information in its "e" parameter. It's certainly nice for the Click event on that MenuItem to point to the same event handler as the Click event for the toolbar button that does the same thing.

Note that the IDE is still a bit dumb when it comes to this stuff. It won't show you non-matching event handlers when you drop down the combobox next to the event in the Properties window. You have to do it in code. No biggie, though.