Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/299.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 为什么此委托分配不起作用以及如何解决?_C#_.net_Delegates_Covariance_Contravariance - Fatal编程技术网

C# 为什么此委托分配不起作用以及如何解决?

C# 为什么此委托分配不起作用以及如何解决?,c#,.net,delegates,covariance,contravariance,C#,.net,Delegates,Covariance,Contravariance,我有以下示例代码: public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); this.del = this.EventHandler; <-- This does not build } public void EventHandler(object sender, PropertyChangedEven

我有以下示例代码:

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;
}
公共部分类主窗口:窗口
{
公共主窗口()
{
初始化组件();

this.del=this.EventHandler;方法签名必须与
委托匹配。如果您尝试执行的操作是允许的,那么您可以将任何类型传递给从
EventArgs
继承的第二个参数,但它实际期望的
属性changedeventargs
不能像这样工作。在您的示例c中通常,您的
EventHandler
方法要求
e
的类型为
PropertyChangedEventArgs
,即比委托声明的类型更具体的类型


它将以另一种方式工作,即您的处理程序可能没有委托那么具体。

想象一下,这一行是编译的:

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

我需要一个通用的处理程序来处理任何带有事件参数的事件

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

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;
}
公共部分类主窗口:窗口
{
公共主窗口()
{
初始化组件();

this.del=this.EventHandler;您可以找到关于委托方差和协方差的解释

将方法指定给代理时,协方差和逆变 为委托类型与方法的匹配提供灵活性 协方差允许方法的返回类型为 比委托中定义的派生更多。相反允许 一种方法,其派生的参数类型少于 委托类型


更改其中之一:
PropertyChangedEventArgs
在EventHandler方法中或
EventArgs
在delegateI中我需要一个通用处理程序来处理任何带有任何事件参数的事件(从EventArgs继承)。然后将
PropertyChangedEventArgs
更改为
EventArgs
。这就是我指出的答案,因为问题很简单。谢谢。问题是我有一个通用服务,它将任何事件的处理程序作为EventHandler参数接收,并将其附加到通过反射检索的事件。它与EventArgs一起工作,但它不适用于任何接收从EventArgs继承的内容的处理程序。