当我为业务对象编写公共事件时,除了额外的特定参数外,我还习惯于将实例作为“ sender as Object ”传递。我现在问自己为什么我没有指定课程?
所以对你有更多的经验; 您是否曾在活动中将不同的类作为发件人传递?如果是这样,那么你的决策标准是什么时候可以/不好?
答案 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);