Why is this delegate assignment not working and how to solve it?
I have the following example 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;
}
He complains about the appointment of a delegate. I suspect it has something to do with covariance / contravariance issues, which, frankly, is a concept I don't fully understand.
Is there a way to do this assembly of code? I need a generic handler for any event with any args events (inheriting from EventArgs).
source to share
Imagine this line is compiled:
this.del = this.EventHandler;
Then here comes the problem:
// since del must accept ANY EventArgs descendant, this should be possible:
del.Invoke(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add));
// since del signature IS (object, PropertyChangedEventArgs), we must convert
// NotifyCollectionChangedEventArgs to PropertyChangedEventArgs
// OOOPS...
I need a generic handler for any event with any args events
Use a handler with this signature:
public void EventHandler(object sender, EventArgs e)
{
}
// compiles just fine
this.Loaded += EventHandler;
this.Closing += EventHandler;
this.Drop += EventHandler;
source to share
You can find an explanation of delegate variance and covariance here
When you assign a method to a delegate, covariance and contravariance provide the flexibility to map the delegate type using the method signature. Covariance allows for a return method of a type that is larger than that defined in the delegate. Contravariance resolution is a method that has parameter types that are less derived than those cast in the delegate type.
source to share
It cannot work like this. In your code example, your method EventHandler
requires to e
be of a type PropertyChangedEventArgs
, that is, a more specific type than what the delegate has declared.
It will work the other way around, i.e. your handler may be less specific than the delegate.
source to share
It should be
Use PropertyChangedEventArgs
in Method A Overload
Because when assigning an event to any delegate. their signature must be the same
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, PropertyChangedEventArgs e);
private A del;
}
source to share