为什么这个委托分配不起作用,如何解决?

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

我有以下示例代码:

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

它抱怨委托分配。我怀疑这是由于协方差/逆变问题,老实说这是一个我不完全理解的概念。

有什么方法可以构建此代码吗?我需要一个通用处理程序来处理具有任何事件参数的任何事件(继承自 EventArgs)。

方法签名必须与 delegate 匹配。如果允许您尝试执行的操作,那么您可以将任何类型传递给继承自 EventArgs 的第二个参数,但它实际上期望 PropertyChangedEventArgs.

那不行。在您的示例代码中,您的 EventHandler 方法要求 ePropertyChangedEventArgs 类型,即比委托声明的类型更具体。

反之亦然,即您的处理程序可以不如委托具体。

想象一下,编译了这一行:

        this.del = this.EventHandler;

那么,问题来了:

        // 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

使用具有此签名的处理程序:

public void EventHandler(object sender, EventArgs e)
{

}


// compiles just fine
this.Loaded += EventHandler;
this.Closing += EventHandler;
this.Drop += EventHandler;

应该是

在方法重载

中使用PropertyChangedEventArgs

因为在将事件分配给任何代表时。他们的签名必须相同

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

你可以找到关于委托方差和协方差的解释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.