C# .NET事件最佳实践-通过属性公开或在EventArgs中返回

C# .NET事件最佳实践-通过属性公开或在EventArgs中返回,c#,events,class,C#,Events,Class,我不确定事件处理/类设计的最佳实践 我有一个类,它有一个Discover方法。当该方法完成时,它将引发一个事件DiscoveryCompleted。DiscoveryCompleted事件具有EventArgs 在Discover方法中,将创建一个对象列表。当在EventArgs中触发DiscoveryCompleted事件时(仍需要创建一个从EventArgs派生的类),应该返回这些值,或者将其设置为类的属性(ReadOnlyCollection)。我有一个bool DISCOVERY,它是在

我不确定事件处理/类设计的最佳实践

我有一个类,它有一个Discover方法。当该方法完成时,它将引发一个事件DiscoveryCompleted。DiscoveryCompleted事件具有EventArgs


在Discover方法中,将创建一个对象列表。当在EventArgs中触发DiscoveryCompleted事件时(仍需要创建一个从EventArgs派生的类),应该返回这些值,或者将其设置为类的属性(ReadOnlyCollection)。我有一个bool DISCOVERY,它是在DiscoveryCompleted激发时设置的,因此可以使用它来确定是否应该填充数据。

我认为大多数开发人员都会在继承自EventArgs的类中返回它们。这样,订阅事件的任何方法都会在其事件处理程序中获得结果

class EventArgsX : EventArgs {
        public IEnumerable<object> YourCollection { get; set; }
}

instance.SomeEvent += (s, args) => {
   foreach(object O in args.YourCollection){
      //do something
   }
}
类EventArgsX:EventArgs{
公共IEnumerable集合{get;set;}
}
instance.SomeEvent+=(s,args)=>{
foreach(args.YourCollection中的对象O){
//做点什么
}
}

遗漏了很多内容,但我相信您理解了要点。

如果数据是可传递的(在触发事件后,值可能会更改,并且您希望订阅者能够查看与该特定事件相关的数据),或者与您的组件不直接相关(异步调用的结果,组件以后不会使用它自己),然后在事件args中返回它


否则,如果将该值作为组件上的属性公开是有意义的(忽略事件),然后这样做,不必担心
EventArgs
。如果没有,则将其包含在args中。

这取决于相关数据的性质。如果数据作为类的一部分是有意义的,则应该有一个属性。如果类封装数据没有意义,则创建一个EventArg类f或者它


想想控制事件是如何完成的。CheckBox.CheckChanged不会传递Checked状态,因为这作为CheckBox类的属性是有意义的,但是KeyPress事件传递KeyPressEventArgs,因为按下的键与复选框本身无关。

我认为这最终归结为架构/e要在代码中启用的扩展点。
Discover
函数的使用者是否总是希望/需要与已发现的
对象进行交互?如果是,则应从
Discover
方法返回这些扩展点。但是,如果调用
Discover
函数,则会保留这些对象以供内部使用了解发现哪些对象是可选的(或者您不想每次都用类核心功能以外的方法处理它们),然后通过事件提供信息是一个不错的选择。

感谢您的评论。基本上,返回给订阅服务器的数据将在稍后阶段通过将其传递到另一个方法(在同一程序集中,不同的类)进行更改。当该方法完成时,它还将返回更新后的数据。即使数据只能通过属性检索,订阅处理程序仍然可以通过
对象发送者
参数(
s
在您的示例中)。此参数包含发送事件的对象(即具有相关数据的对象).是的,没错。我想这只是偏好的问题。将其附加到args似乎是更常见的做法,但正如您所说,您可以采用任何一种方式。除非数据在事件发生后发生变化,如@Adam Robinson所述,在这种情况下,它应该在args上。Discover方法是一种长期运行的方法,应该返回的对象很可能会被使用并传递给另一个方法和类进行进一步处理。