事件参数; “发件人为对象”,或“发件人为T”?

时间:2011-02-09 12:09:07

标签: c# .net vb.net oop events

当我为业务对象编写公共事件时,除了额外的特定参数外,我还习惯于将实例作为“ sender as Object ”传递。我现在问自己为什么我没有指定课程

所以对你有更多的经验; 您是否曾在活动中将不同的类作为发件人传递?如果是这样,那么你的决策标准是什么时候可以/不好?

8 个答案:

答案 0 :(得分:11)

不要太极端。 EventHandler(object sender, EventArgs e)有一个对象发件人,以便我们可以在很多情况下使用它。但这并不意味着一个强类型的发送者是邪恶的。当这个委托不被广泛使用时(例如EventHandler),强类型发送者很有用。例如

public delegate void SaveHandler(Controller sender, EventArgs e);

现在,其他开发人员(或使用您图书馆的人)可以认识到发件人必须Controller,并且他们很乐意不这样编码:

public void MySaveHandler(object sender, EventArgs arg)
{
   var controller = sender as Controller;
   if (controller != null)
   {
       //do something
   }
   else
   {
       //throw an exception at runtime? 
       //It can be avoided if sender is strongly-typed
   }
}

你甚至可以把它变成通用的:

public delegate void SaveHandler<T>(T sender, EventArgs args) 
                                              where T: IController;

这是C#中纯粹的法律和良好做法。你应该明确你想做什么,然后选择更好的方法。他们中的任何一个都是邪恶的/坏的。

答案 1 :(得分:5)

有一个design guideline指定事件处理程序应该有两个参数:sender(一个Object)和e(EventArgs或派生自它)。

答案 2 :(得分:1)

没有这样的限制。它只是整个BCL(基类库)和其他流行框架遵循的指南。

我建议你按照它来保持一致,如果它将由其他开发人员使用或作为框架发布。

答案 3 :(得分:1)

据我所知,您可以使用所需参数创建委托,然后使用该委托创建事件,然后您可以调用事件并传入参数,或者您可以使用自定义事件参数,如图所示{{ 3}}。正如另一个答案所示。保持一致。

没有真正回答您关于决策标准的问题,但希望有所帮助

答案 4 :(得分:1)

我目前的理念是让代码实践尽可能接近标准的Microsoft方式。你从中得到两件事:

  • 新开发人员可以快速了解您的代码
  • 您培训现有开发人员框架的其余部分如何工作

答案 5 :(得分:1)

最好使用object sender, EventArgs e签名,因为该方法可以处理该签名的任何事件。例如,在使用图表控件的项目中,有几种类型的MouseOver事件 - 来自DataSeries,来自Legend,来自整个画布。

这样,您可以处理任何事件来源,因为大多数情况下,信息都在EventArgs

此外,您不必在将代理传递给委托时强制转发,因为任何类实例都是深层对象。

答案 6 :(得分:1)

前一段时间,StackOverflow上有很多关于相关问题的讨论。这是一个问题:Event Signature in .NET -- Using a strong-typed sender

最终,归结为偏好。在大多数情况下,您希望将事件处理程序绑定到特定类型的类,这样使发件人成为一个对象,然后回滚到该类以便访问其属性可能不会很好地与您[它对我来说也不顺利。]

此外,使用.NET 3+以及委托协方差和逆变的引入,使用强类型委托应该不是问题。我必须承认,我在代码中多次使用强类型事件处理程序。

正如我之前所说的那样,归结为偏好;微软刚刚发布了一套指南行而非规则......

答案 7 :(得分:0)

拥有此类实施并不具有约束力。它通常是因为EventHandler 委托而设计的。

它的simple guideline后面是基类库。但是你可以确保自己拥有参数和实现。

但请记住,如果某些开发人员使用它,他将需要了解此类实现。它可以提供更好的灵活性,可以灵活地在任何地方使用事件,无论其使用的类别如何。

如果您为事件定义自定义原型,那么我建议您还定义自定义代理,以确保您能够捕获异常如果没有传递正确的类型。 (如果需要,用户需要进行显式演员)

像这样:

public delegate void MyEventHandler( MyType sender, EventArgs e);

然后在需要时使用它:

this.MyEvent += new MyEventHandler(my_eventhandlerfunction);