行动<T>与委托事件

我已经看到开发人员使用下面的代码相当不错。 这些之间的确切区别是什么,哪些符合标准? 它们是否相同, ActionFunc<T>也是一个委托:

 public event Action<EmployeeEventAgs> 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)); } 

Fwiw,都没有使用标准的.NET约定。 EventHandler<T>generics应该声明事件:

 public event EventHandler<EmployeeEventArgs> Leave; 

“On”前缀应该保留给引发事件的受保护的方法:

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

你不必这样做,但任何人都会立即认识到这个模式,理解你的代码,知道如何使用和定制它。

它具有不被强迫在自定义委托声明和Action<>之间进行select的巨大优势, EventHandler<>是最好的方法。 哪个回答你的问题。

Action<T>delegate void ... (T t)完全相同

Func<T>delegate T ... ()完全相同delegate T ... ()

以下两行代码几乎是等价的:

 public event Action<EmployeeEventAgs> Leave; 

而不是:

 public event EventHandler<EmployeeEventAgs> Leave; 

不同之处在于事件处理程序方法的签名。 如果您使用第一种方法,您可以:

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

然后这个:

 obj.Leave += LeaveHandler; 

第二种方法, LeaveHandler的签名需要不同:

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

注意到在这两种情况下, event关键字都存在是非常重要的 。 通过event关键字明确声明的event不再是类的字段。 相反,它成为一个事件属性 。 事件属性与常规属性相似,除了它们没有getset访问器。 编译器允许它们仅用于+=-=赋值(添加或删除事件处理程序)的左侧。 无法覆盖已经分配的事件处理程序 ,或者在声明的类之外调用该事件

如果在这两个示例中缺lessevent关键字,则可以执行以下操作,而不会出现错误或警告:

 obj.Leave = LeaveHandler; 

这将删除任何注册的处理程序,并用LeaveHandlerreplace它们。

另外,你也可以执行这个调用:

 obj.Leave(new EmployeeEventAgs()); 

上面的两个例子被认为是反模式 ,如果你打算创build一个事件。 一个事件只能由所有者对象调用,不应该允许不可追踪的用户移除。 event关键字是.NET的程序化结构,可以帮助您坚持正确使用事件。

考虑到上述情况,我相信很多人坚持使用EventHandler方法,因为不使用event关键字就不太可能使用EventHandler 。 行动有更广泛的使用范围,用作事件时看起来不那么自然。 后者当然是个人意见,因为事件处理方法在我的编码实践中可能已经变得太硬了。 不过,如果行动得到妥善使用,将其用于事件并不构成犯罪。

行动只是完整的委托声明的捷径。

 public delegate void Action<T>(T obj) 

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

使用哪一个取决于你的组织编码标准/风格。

是的,Action和Func只是3.5 clr中定义的方便代表。

Action,Func和lambda都是使用代表的语法糖和方便。

他们没有任何魔力。 有几个人编写了简单的2.0附加库来将这个function添加到2.0代码中。

你可能想看看这里 ,看看编译器为Action所产生的是最好的描述。 你写的东西没有什么function上的区别,只是更短,更方便的语法。

一般来说,它们是相同的。 但是在为事件types使用委托的上下文中,约定是使用EventHandler(其中TinheritanceEventArgs):

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

你可以自己编写这些Action和Funcgenerics委托,但是因为它们通常是有用的,所以他们为你写了这些代码,并把它们放在.Net库中。