Search code examples
c#.netdelegatescovariancecontravariance

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).


Solution

  • 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;