如何创建一个通用的事件触发方法

7

我有一组具有相同签名的事件。现在我想知道是否可以创建一个通用的事件处理程序来处理所有这些事件?

  • 是否可以将事件作为 <T> 发送?
3个回答

11

如果这些都在同一个类中,你可以创建一个方法来触发事件并适用于任何事件。例如,如果你的事件都是EventHandler<T>,你可以使用以下方法:

private void RaiseEvent<T>(EventHandler<T> eventHandler, T eventArgs)
{
    if (eventHandler != null)
    {
        eventHandler(this, eventArgs);
    } 
}

您可以通过以下方式调用它:

this.RaiseEvent(this.MyEvent, new MyEventArgs("Foo"));

@mohsen.d 没有竞争条件。eventHandler 是一个参数。 - CrazyCasta
2
@mohsen.d 不会 - 当您将其作为参数传递时,它实际上执行相同的操作。 eventHandler 成为方法中使用的“局部变量”,因此您不会遇到竞争条件。 - Reed Copsey
@ReedCopsey:当事件从子类中引发时怎么办?使用通用类仍然可行吗?我找不到方法来做这件事。 - mohsen dorparasti
1
@mohsen.d 只有类本身可以引发它的事件。您可以传递一个 Func<EventHandler<T>> 并使用 lambda 引发它,但在调用方面会变得更加丑陋。通常更容易在子类中重新执行此操作。 - Reed Copsey
为了使这段代码正常工作,请不要忘记在您的T类型上添加EventArgs类型约束:因为EventHandler<T>期望T派生自事件参数,所以您也需要。private void RaiseEvent<T>(EventHandler<T> eventHandler, T eventArgs) where T : EventArgs - Vova
显示剩余3条评论

2
为了静态化Reed Copsey的回复,我创建了一个静态类Event:
public static class Event
{
    public static bool Raise<T>(Object source, EventHandler<T> eventHandler, T eventArgs) where T : EventArgs
    {
        EventHandler<T> handler = eventHandler;
        if (handler != null)
        {
            handler(source, eventArgs);
            return true;
        }
        return false;
    }
}

这也假设您的事件处理程序是EventHandler<T>类型。返回类型从void更改为bool,并返回事件是否有任何侦听器。很少使用,所以可以随意改回void示例用法:
public event EventHandler<FooArgs> FooHappend;

public void Foo()
{
    Event.Raise(this, FooHappend, new FooArgs("Hello World!");
}

-1

请查看this。它描述了你想要的内容。

您可以通过使用类型化委托并将其用于事件来创建一个类型化事件:

public delegate void myDel<T>(T stuff);

public event myDel<int> myEvent;

public doStuff()
{
    myDel(1);
}

1
不仅似乎这并不是问答者想要的,而且在SO上“仅仅”发布链接是不合适的,即使它回答了问题也是如此。[更多信息](http://meta.stackexchange.com/questions/94022/how-can-i-link-to-an-external-resource-in-a-community-friendly-way) - Servy

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接