Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/24.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# 为什么对AddEventHandler的调用不起作用?_C#_.net_Events_Reflection_Delegates - Fatal编程技术网

C# 为什么对AddEventHandler的调用不起作用?

C# 为什么对AddEventHandler的调用不起作用?,c#,.net,events,reflection,delegates,C#,.net,Events,Reflection,Delegates,我有以下概念验证课程: private class SourceMock { public event PropertyChangedEventHandler TestEvent; public void Raise() { if (this.TestEvent != null) { this.TestEvent(this, new PropertyC

我有以下概念验证课程:

    private class SourceMock
    {
        public event PropertyChangedEventHandler TestEvent;

        public void Raise()
        {
            if (this.TestEvent != null)
            {
                this.TestEvent(this, new PropertyChangedEventArgs("S"));
            }
        }
    }

    private class HandlerMock
    {
        public HandlerMock()
        {
        }

        public void PropertyHandler(object sender, PropertyChangedEventArgs e)
        {
        }
    }
那么,如果我执行以下操作,它就会起作用:

    SourceMock sourceMock = new SourceMock();
    HandlerMock handler = new HandlerMock();

    sourceMock.GetType().GetEvent("TestEvent").AddEventHandler(sourceMock, new PropertyChangedEventHandler(handler1.PropertyHandler));
但如果执行以下操作,则不起作用:

    SourceMock sourceMock = new SourceMock();
    HandlerMock handler = new HandlerMock();

    sourceMock.GetType().GetEvent("TestEvent").AddEventHandler(sourceMock, new EventHandler<PropertyChangedEventArgs>(handler1.PropertyHandler));
SourceMock SourceMock=newsourcemock();
HandlerMock handler=new HandlerMock();
sourceMock.GetType().GetEvent(“TestEvent”).AddEventHandler(sourceMock,新的EventHandler(handler1.PropertyHandler));
因为我得到以下异常:

System.ArgumentException:类型为的对象 'System.EventHandler'1[System.ComponentModel.PropertyChangedEventArgs]' 无法转换为类型 “System.ComponentModel.PropertyChangedEventHandler”

我希望有一个处理事件的泛型类,但我不能将委托用作泛型类型,我必须使用EventArgs,这给了我第二种语法(非工作语法)

关于如何克服这个问题有什么想法吗

编辑:这就是我想要实现的目标

我需要一个类来截获事件,并在引发事件之前进行处理(比如计数、过滤、重新排序等等)。客户端不会注册到事件,但会要求此类将其注册到事件。我认为签名如下:

public class EventHandlerService<T> where T : EventArgs
{
    public void Register(object eventSource, string eventName, EventHandler<T> handler)
}
公共类EventHandlerService,其中T:EventArgs
{
公共无效寄存器(对象eventSource、字符串eventName、EventHandler)
}
当事件发生时,服务将根据内部算法调用所有已注册的处理程序


在内部,它与EventInfo类一起工作,而与非从EventHandler派生的EventHandler不一起工作,因此这个问题。

事件的委托类型不必继承自
EventHandler
/
EventHandler
。因此,这里的泛型可能是多余的:

public class EventHandlerService
{
    /// <example>
    /// Use this overload, when delegate type for the event isn't inherited from EventHandler/EventHandler{T}.
    /// <code>
    /// service.Register(someObj, "SomeEvent", new PropertyChangedHandler(TheHandler));
    /// </code>
    /// </example>
    public void Register(object eventSource, string eventName, Delegate handler)
    {
        // do the work here
    }

    /// <example>
    /// Use this overload, when delegate type for the event is inherited from EventHandler{T}.
    /// <code>
    /// service.Register<FooEventArgs>(someObj, "SomeEvent", TheHandler);
    /// </code>
    /// </example>
    public void Register<T>(object eventSource, string eventName, EventHandler<T> handler)
        where T : EventArgs
    {
        Register(eventSource, eventName, handler);
    }

    /// <example>
    /// Use this overload, when delegate type for the event is inherited from EventHandler.
    /// <code>
    /// service.Register(someObj, "SomeEvent", TheHandler);
    /// </code>
    /// </example>
    public void Register(object eventSource, string eventName, EventHandler handler)
    {
        // we need cast here to help compiler to find desired overload
        Register(eventSource, eventName, (Delegate)handler);
    }
}
问题中的特定问题可以通过以下方式解决:

var eventInfo = sourceMock.GetType().GetEvent("TestEvent");
eventInfo.AddEventHandler(sourceMock, Delegate.CreateDelegate(eventInfo.EventHandlerType, handler, "PropertyHandler"));

但是看起来您不需要解决它—只需删除泛型。

您只是使用了错误的委托类型。EventHandler是一个完全不相关的类型。PropertyChangedEventHandler可以追溯到.NET1.x,该版本中还没有泛型。两个不同的委托类型永远不会被认为是相同的,即使它们的签名匹配。那么,有没有办法创建一个泛型类,在其他处理程序中接收PropertyChangedEventHandler处理程序并使用它们?使用EventHandler并将T指定为EventArgs可以解决问题,但对于从EventHandler继承的事件,则不行……感谢您指出这一点。我添加了X部分。