Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why this delegate assignment does not work and how to solve it?

I have the following sample code:

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();

        this.del = this.EventHandler; <-- This does not build
    }

    public void EventHandler(object sender, PropertyChangedEventArgs e)
    {

    }

    public delegate void A(object sender, EventArgs e);

    private A del;
}

It complains about the delegate assignment. I suspect it is due to Covariance / Contravariance issues which honestly speaking is a concept that I do not fully understand.

Is there any way of making this code build? I need a generic handler for any event with any event args (inheriting from EventArgs).

like image 556
Ignacio Soler Garcia Avatar asked Nov 22 '25 02:11

Ignacio Soler Garcia


2 Answers

Imagine, that this line is compiled:

        this.del = this.EventHandler;

Then, here's a problem:

        // since del must accept ANY EventArgs descendant, this should be possible:
        del.Invoke(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add));
        // since del's signature IS (object, PropertyChangedEventArgs), we must convert 
        // NotifyCollectionChangedEventArgs to PropertyChangedEventArgs
        // OOOPS...

I need a generic handler for any event with any event args

Use handler with this signature:

public void EventHandler(object sender, EventArgs e)
{

}


// compiles just fine
this.Loaded += EventHandler;
this.Closing += EventHandler;
this.Drop += EventHandler;
like image 101
Dennis Avatar answered Nov 23 '25 16:11

Dennis


You can find an explication about delegate variance and covariance here

When you assign a method to a delegate, covariance and contravariance provide flexibility for matching a delegate type with a method signature. Covariance permits a method to have return type that is more derived than that defined in the delegate. Contravariance permits a method that has parameter types that are less derived than those in the delegate type.

like image 34
Che Avatar answered Nov 23 '25 14:11

Che