在 C# 中将通用 EventHandler 作为函数参数传递

Passing generic EventHandler as function parameter in C#

我正在创建一个基础对象 class,其中包含一些我想在整个程序中使用的功能。我想包括的函数之一是一个通用的 TriggerEvent 函数,它应该在触发传入的事件之前进行一些基本检查:

/// <summary>
/// Executes the specified event if one of several internal conditions are met:
/// 1. The event is not null
/// 2. The DisableEvents property is not enavled
/// </summary>
/// <param name="eventProcedure">Event to execute</param>
/// <param name="e">Event arguments object (or null if none specified)</param>
protected void TriggerEvent(EventHandler<EventArgs> eventProcedure, EventArgs e = null)
{
    if (eventProcedure != null)
    {
        if (!DisableEvents)
        {
            eventProcedure(this, e);
        }
    }
}

我遇到麻烦的地方是我希望能够将通用 EventHandler 传递给此函数,以便我还可以处理可能采用各种形式的 EventArgs 对象参数的事件。例如,我有一个这样的:

/// <summary>
/// Used with the PrintMessage Event
/// </summary>
public class MessageEventArgs : EventArgs
{
    public MessageEventArgs(string messageText)
    {
        MessageText = messageText;
    }

    public string MessageText { get; private set; }
}

以及相关事件:

public event EventHandler<MessageEventArgs> PrintMessage;

例如,此事件将允许我将消息传递给父对象。但我也希望能够将 TriggerEvent 函数与可能具有与其关联的其他自定义 Event args 对象的事件一起使用:

public event EventHandler<CustomEventArgs> SomeEvent;
public event EventHandler<EventArgs> SomeNormalEvent;

然后可以使用 TriggerEvent 函数执行其中任何一个:

TriggerEvent(PrintMessage, new MessageEventArgs(textToSend));
TriggerEvent(SomeEvent, ExistingCustomEventArgs);
TriggerEvent(SomeNormalEvent);

但是当我尝试使用 TriggerEvent 函数调用 PrintMessage 事件时出现错误,例如:

Argument 1: Cannot convert from 'System.EventHandler<TestProject.MessageEventArgs>' to 'System.EventHandler<System.EventArgs>'

如何修改 TriggerEvent 函数,以便我可以使用它来检查和执行多种类型的事件?

我可以想到两个办法

  1. 传入委托而不是执行事件。

protected void TriggerEvent(Action<EventArgs> eventProcedure, EventArgs e = null) if (eventProcedure != null && !DisableEvents) { eventProcedure(e); }

或者只是...

protected void TriggerEvent(Action eventProcedure) if (eventProcedure != null && !DisableEvents) { eventProcedure(); }

并像这样使用:TriggerEvent(() => MyEvent?.Invoke(this, new MyEventArgs(...)))

  1. 使用通用方法:

protected void TriggerEvent<T>(EventHandler<T> eventProcedure, T e = null) where T : EventArgs if (eventProcedure != null && !DisableEvents) { eventProcedure(this, e); }