Action<T> vs delegate event

匿名 (未验证) 提交于 2019-12-03 01:14:02

问题:

I have seen developers using the below codes quite alternatively. What is the exact difference between these, and which ones go by the standard? Are they same, as Action and Func is a delegate as well:

public event Action OnLeave; public void Leave() {     OnLeave(new EmployeeEventAgs(this.ID)); } 

VS

public delegate void GoOnLeave(EmployeeEventAgs e); public event GoOnLeave OnLeave; public void Leave() {     OnLeave(new EmployeeEventAgs(this.ID)); } 

回答1:

Fwiw, neither example uses standard .NET conventions. The EventHandler generic should declare the event:

public event EventHandler Leave; 

The "On" prefix should be reserved for a protected method that raises the event:

protected virtual void OnLeave(EmployeeEventArgs e) {     var handler = Leave;     if (handler != null) handler(this, e); } 

You don't have to do it this way, but anybody will instantly recognize the pattern, understand your code and know how to use and customize it.

And it has the great advantage of not being forced to choose between a custom delegate declaration and Action, EventHandler is the best way. Which answers your question.



回答2:

The following two lines of code are almost equivalent:

public event Action Leave; 

as opposed to:

public event EventHandler Leave; 

The difference is in the signature of the event handler method. If you use the first approach with the action, you could have:

public void LeaveHandler(EmployeeEventAgs e) { ... } 

and then this:

obj.Leave += LeaveHandler; 

With the second approach, the signature of the LeaveHandler needs to be different:

public void LeaveHandler(object sender, EmployeeEventAgs e) { ... } 

It is very important to notice that in both cases the event keyword is present. An event declared explicitly as such via the event keyword is no longer a field of the class. Instead it becomes an event property. The event properties are similar to regular properties, except that they do not have get or set accessors. The compiler allows them to be used only on the left side of a += and -= assignments (adding or removing an event handler). There is no way to overwrite the already assigned event handlers, or to invoke the event outside the class that declares it.

If the event keyword was missing in both examples, you could do the following operations with no error or warning:

obj.Leave = LeaveHandler; 

which will erase any registered handlers and replace them withe the LeaveHandler.

In addition, you can also perform this call:

obj.Leave(new EmployeeEventAgs()); 

The two examples above are considered an anti-pattern, if you intend to create an event. An event should be invoked only by the owner object and should not allow for untraceable removal of subscribers. The event keyword is the .NET's programmatic construct that helps you stick with the correct use of events.

Having the above in mind, I believe many people stick to the EventHandler approach because it is more unlikely to use an EventHandler without the event keyword. Actions have wider scope of usage, they do not look as naturally when used as events. The latter is, of course, a personal opinion, as the event handler approach has probably become too hardwired in my coding practices. Still, if actions are used properly, it is not a crime to use them for events.



回答3:

Action is exactly the same as delegate void ... (T t)

Func is exactly the same as delegate T ... ()



回答4:

Action is just a shortcut for the full delegate declaration.

public delegate void Action(T obj) 

http://msdn.microsoft.com/en-us/library/018hxwa8.aspx

Which one to use would depend on your organizations coding standards/style.



回答5:

Yes, Action and Func are simply convenience delegates that have been defined in the 3.5 clr.

Action, Func and lambdas are all just syntactical sugar and convenience for using delegates.

There is nothing magic about them. Several people have written simple 2.0 addon libraries to add this functionality to 2.0 code.



回答6:

You may want to look here, seeing what the compiler actually generates for Action is the best description. There's no functional difference in what you wrote, just shorter, more convenient syntax.



回答7:

In general, they are equivalent. But in the context of using a delegate for the type of an event, the convention is to use EventHandler (where T inherits EventArgs):

public event EventHandler Left;  public void Leave() {     OnLeft(this.ID); }  protected virtual void OnLeft(int id) {     if (Left != null) {         Left(new EmployeeEventArgs(id));     } } 


回答8:

You could have written these Action and Func generic delegates yourself, but since they're generally useful they wrote them for you and stuck them in .Net libraries.



标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!