可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
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. 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?
回答1:
Don't be extreme. EventHandler(object sender, EventArgs e)
has an object sender so that we can use it in many circumstances. 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
) e.g.
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:
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#. You should make clear what you want to do, and then choose the better way. Either of them is evil/bad.
回答2:
There is a design guideline that specified that an event-handler should have two params: sender (an Object) and e (EventArgs or derived from that).
回答3:
There no such restriction. It is just a guideline that is followed throughout BCL (Base Class Library) and other popular frameworks.
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.
回答4:
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
回答5:
My current philosophy is to keep code practices as close to the standard Microsoft way as possible. You get two things from this:
- New developers can quickly understand your code
- You train existing developers how the rest of the framework works
回答6:
It is good practice to use the object sender, EventArgs e
signature, as the method can handle any events of that signature. 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.
That way, you can handle any source of the event, as at most times, the information is in the 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.
回答7:
There was a lot of discussion on a related question on StackOverflow some time ago. Here is that question: Event Signature in .NET -- Using a strong-typed sender
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. 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 guidelines not rules...
回答8:
It is not a binding on you to have such implementation. Its usually done because of the EventHandler
delegate was designed with such prototype.
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);