行动<T>与委托事件
我已经看到开发人员使用下面的代码相当不错。 这些之间的确切区别是什么,哪些符合标准? 它们是否相同, Action
和Func<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
不再是类的字段。 相反,它成为一个事件属性 。 事件属性与常规属性相似,除了它们没有get
或set
访问器。 编译器允许它们仅用于+=
和-=
赋值(添加或删除事件处理程序)的左侧。 无法覆盖已经分配的事件处理程序 ,或者在声明它的类之外调用该事件 。
如果在这两个示例中缺lessevent关键字,则可以执行以下操作,而不会出现错误或警告:
obj.Leave = LeaveHandler;
这将删除任何注册的处理程序,并用LeaveHandler
replace它们。
另外,你也可以执行这个调用:
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库中。