C#中声明事件的语法是什么?

27

在我的类中,我想声明一个其他类可以订阅的事件。正确的声明事件的方式是什么?

以下代码是不起作用的:

public event CollectMapsReportingComplete;

12
我很喜欢这个问题能够在这里,SO的页面排版对我来说比大多数MSDN文档更易于阅读。 - Zachary Yates
10
我不同意 - SO 不是专门为"专家"程序员而设的,它旨在帮助所有水平的开发者。在我看来,这是一个完全合理的问题。 - Jonathan Perry
5个回答

36

你忘记了提到类型。对于非常简单的事件,EventHandler 可能已经足够:

public event EventHandler CollectMapsReportingComplete;

有时候你会想要声明自己的委托类型来用于事件中,这可以让你使用自己的类型作为 EventArgs 参数(参见Adam Robinson的评论):

public delegate void CollectEventHandler(object source, MapEventArgs args);

public class MapEventArgs : EventArgs
{
    public IEnumerable<Map> Maps { get; set; }
}

您还可以使用通用的EventHandler类型,而不是声明自己的类型:

public event EventHandler<MapEventArgs> CollectMapsReportingComplete;

3
不会因为这个而打负评,但在.NET中的惯例是事件委托应该只包括一个(object)发送器和一个继承自EventArgs的额外参数。这样做还可以让你使用泛型的EventHandler<TEventArgs>委托类型,而不必声明你自己的委托类型。当然,你的方法没有问题(它也能正常工作),但主流观点倾向于基于EventArgs的方式。 - Adam Robinson
1
@Adam:你说得完全正确,我已经更新了我的答案以反映这一点。 - Jørn Schou-Rode

8

您需要指定事件的委托类型:

public event Action CollectMapsReportingComplete;

这里我使用了 System.Action,但您可以使用任何委托类型(甚至是自定义委托)。指定的委托类型的实例将用作事件的后备字段。


1
EventHandler和Action有什么区别? - Tilendor
6
原文:The OP didn't ask about .NET's event pattern they asked for the correct syntax for declaring an event. It is important to understand that events can be declared with any delegate type.翻译:作者并没有询问.NET的事件_pattern,而是问如何正确声明一个事件的语法。重要的是要理解,事件可以使用任何委托类型来声明。 - Andrew Hare
@Andrew:有人可能会认为,同样重要的是他们理解当前的模式,以便他们不必不必要地走向任意事件委托的道路,只是发现它们与被接受的模式不太匹配。 - Adam Robinson
@安德鲁:他(和每个人)肯定应该知道你展示的语法和机制。我只是认为让他们知道“大多数人是这样做的”也是件好事。 :) - Adam Robinson
4
我发现使用Action而不是EventHandler可以使代码更易读(也更少)。我几乎从来不需要“sender”参数。当事件确实需要一些参数时,我只需使用通用的Action,而不需要定义一个继承自EventArgs的类(在使用EventHandler时需要这样做)。 - oferei
显示剩余2条评论

3
一个例子
/// </summary>
/// Event triggered when a search is entered in any <see cref="SearchPanel"/>
/// </summary>
public event EventHandler<string> SearchEntered
{
    add { searchevent += value; }
    remove { searchevent -= value; }
}
private event EventHandler<string> searchevent;

2
public event EventHandler MyEvent;

1

公共事件[DelegateType] [EventName];


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