简体   繁体   English

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

[英]Event parameter; “sender as Object”, or “sender as T”?

When I write public events for my business objects, I've adapted the habit of always passing the instance as " sender as Object ", in addition to additional specific parameters. 当我为业务对象编写公共事件时,除了附加的特定参数之外,我还习惯于将实例作为“ sender as Object ”传递。 I just asked myself now why am I not specifying the class ? 我现在问自己为什么不指定课程

So for you with more experience; 所以对你有更多的经验; Do you ever pass the distinct class as sender in an event ? 您是否曾在活动中将不同的类作为发件人传递 And if so, what are your decision criteria for when this is ok/not ok? 如果是这样,那么当你可以/不好的时候,你的决定标准是什么?

Don't be extreme. 不要太极端。 EventHandler(object sender, EventArgs e) has an object sender so that we can use it in many circumstances. EventHandler(object sender, EventArgs e)有一个对象发送者,因此我们可以在很多情况下使用它。 But it doesn't mean a strongly-typed sender is evil. 但这并不意味着一个强类型的发送者是邪恶的。 A strongly-typed sender is useful when this delegate is not going to be widely used(like EventHandler ) eg 当这个委托不被广泛使用时(例如EventHandler ),强类型发送器很有用

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

Now other developers(or someone using your library) can recogonize that the sender have to be a Controller , and they will be glad not to code like this: 现在,其他开发人员(或使用你的库的人)可以认识到发件人必须是一个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
   }
}

And you can even make it generic: 你甚至可以把它变成通用的:

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

It's pure legal and good practice in C#. 这是C#的纯法律和良好实践。 You should make clear what you want to do, and then choose the better way. 你应该明确你想做什么,然后选择更好的方法。 Either of them is evil/bad. 他们中的任何一个都是邪恶的。

有一个设计指南 ,指定事件处理程序应该有两个参数:sender(一个Object)和e(EventArgs或从中派生)。

There no such restriction. 没有这样的限制。 It is just a guideline that is followed throughout BCL (Base Class Library) and other popular frameworks. 它只是整个BCL(基类库)和其他流行框架遵循的指导原则。

I would recommend you follow it to keep it consistent if it is going to be used by other developers or be released as a framework. 如果它将被其他开发人员使用或作为框架发布,我建议您遵循它以保持一致。

As far as I see it you can either create delegates with the parameters you want and then create an event using that delegate and then you can call the event and pass the parameters in or you can use Custom Event Argument as shown here . 据我看到它,你可以创建你想要的参数代表,然后创建一个使用该委托的事件,然后你可以调用事件和传递的参数,也可以使用自定义事件参数如图所示这里 As the other answer suggests. 正如另一个答案所示。 Keep it consistent. 保持一致。

Doesn't really answer your question about the decision criteria but hope it helps 没有真正回答您关于决策标准的问题,但希望它有所帮助

My current philosophy is to keep code practices as close to the standard Microsoft way as possible. 我目前的理念是尽可能使代码实践尽可能接近标准的Microsoft方式。 You get two things from this: 你从这里得到两件事:

  • New developers can quickly understand your code 新开发人员可以快速了解您的代码
  • You train existing developers how the rest of the framework works 您培训现有开发人员如何使用框架的其余部分

It is good practice to use the object sender, EventArgs e signature, as the method can handle any events of that signature. 最好使用object sender, EventArgs e签名,因为该方法可以处理该签名的任何事件。 For example, in a project using a charting control, there are several types of MouseOver events - from a DataSeries , from the Legend, from the whole Canvas. 例如,在使用图表控件的项目中,有几种类型的MouseOver事件 - 来自DataSeries ,来自Legend,来自整个Canvas。

That way, you can handle any source of the event, as at most times, the information is in the EventArgs . 这样,您可以处理事件的任何来源,因为在大多数情况下,信息都在EventArgs

Also, you don't have to cast the sender when passing it to the delegate, as any class instance is an object deep down. 此外,您不必在将代理传递给委托时强制转发,因为任何类实例都是内部对象。

There was a lot of discussion on a related question on StackOverflow some time ago. 不久前在StackOverflow上就相关问题进行了大量讨论。 Here is that question: Event Signature in .NET -- Using a strong-typed sender 这是一个问题: .NET中的事件签名 - 使用强类型发件人

Eventually, it comes down to preference. 最终,它归结为偏好。 In most cases, you'd like your event handlers to be bound to a particular type of class so making the sender an object and then casting back to the class in order to get access to its properties might not go down well with you [it doesn't go down well for me either]. 在大多数情况下,您希望将事件处理程序绑定到特定类型的类,这样使发件人成为一个对象,然后回滚到该类以便访问其属性可能不会很好地与您[它也不适合我。

Besides, with .NET 3+ and the introduction of delegate covariance and contravariance, it should not be a problem to use a strongly typed delegate. 此外,使用.NET 3+以及委托协方差和逆变的引入,使用强类型委托应该不是问题。 I must admit, I've used strongly typed event handlers more than once in my code. 我必须承认,我在代码中多次使用强类型事件处理程序。

Like I said earlier, it comes down to preference; 就像我之前说的那样,它取决于偏好; Microsoft just issued a set of guide lines not rules... 微软刚刚发布了一套引导线而非规则......

It is not a binding on you to have such implementation. 拥有这样的实现对你没有约束力。 Its usually done because of the EventHandler delegate was designed with such prototype. 它通常是因为EventHandler 委托设计了这样的原型。

Its a simple guideline followed through Base Class Library. 它是一个简单的指南,后面是基类库。 But sure you can make you own Parameters and implementations. 但是你可以确保自己拥有参数和实现。

But remember if it is to be used by some developer other that you, he will need to know about such implementation. 但请记住,如果某些开发人员使用它,他将需要了解此类实现。 Its don for greater good and flexibility to use an event anywhere irrespective of class its used in. 无论在哪个级别使用,它都能提供更好的灵活性和灵活性。

If you define a Custom Prototype for event then i would suggest that you also define Custom Delegate that will ensure you will have catch an exception if proper type is not passed. 如果您为事件定义自定义原型 ,那么我建议您还定义自定义委托 ,以确保如果未传递正确的类型,您将捕获异常 (User will need to do an Explicit cast if required) (如果需要,用户需要进行显式演员)

Like this: 像这样:

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

Then use it where required as: 然后在需要时使用它:

this.MyEvent += new MyEventHandler(my_eventhandlerfunction);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM