views:

19

answers:

1

Suppose I have a simple EventArgs subclass:

class MyArgs : EventArgs { }

Consider I have two classes with events:

class MyData {
    public event EventHandler<MyArgs> Method;
}

class MyObject {
    public event EventHandler Method;
}

And a simple program that uses them:

    static void Main(string[] args){

        MyObject o = new MyObject();
        o.Method += MyMethod;

        MyData data = new MyData();
        data.Method += MyMethod;

    }

    static void MyMethod(object sender, EventArgs e) { }

Thanks to Contravariance, MyMethod counts as both an EventHandler and an EventHandler<MyArgs>. However, if I change MyObject's event handler into a property that forwards the method to a MyData:

class MyObject {

    MyData data = new MyData();

    public event EventHandler Method {
        add { data.Method += value; }
        remove { data.Method += value; }
    }

}

The event property is unable to forward the EventHandler to the EventHandler. This seems strange to me because it seems to fall into the contravariance category - a handler with a weaker signature (base classes) should be able to accept arguments with a stronger signature (subclasses).

Why won't C# let me do this? Is there a way to tunnel a generic EventHandler down through an event property into an EventHandler? Is there some sort of legal cast that can be performed on the delegates?

A: 

There is no implicit conversion from EventHandler to EventHandler<T>. However since both are of compatible types with each other, you could just pass the EventHandler to the constructor to "convert" it.

public event EventHandler Method
{
    add { data.Method += new EventHandler<MyArgs>(value); }
    remove { data.Method -= new EventHandler<MyArgs>(value); }
}
Jeff M
Huh - I hadn't thought of that. I didn't realize it was using implicit conversions there - thanks!
benjamin.popp