为什么这个对AddEventHandler的调用不工作

本文关键字:调用 工作 AddEventHandler 为什么 | 更新日期: 2023-09-27 18:04:20

我有以下概念类的证明:

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

因为我得到了下面的异常:

系统。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)
}

当事件发生时,服务将根据内部算法调用所有已注册的处理程序。

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

为什么这个对AddEventHandler的调用不工作

事件的委托类型不必从EventHandler/EventHandler<T>继承,如您所见。所以,这里的泛型可能是多余的:

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"));

但看起来你不需要解决它-只需删除泛型。