我见过开发人员使用下面的代码.它们之间的确切区别是什么,哪些符合标准?他们是一样的,Action而且Func<T>是一个代表,以及:
public event Action<EmployeeEventAgs> OnLeave;
public void Leave()
{
OnLeave(new EmployeeEventAgs(this.ID));
}
Run Code Online (Sandbox Code Playgroud)
VS
public delegate void GoOnLeave(EmployeeEventAgs e);
public event GoOnLeave OnLeave;
public void Leave()
{
OnLeave(new EmployeeEventAgs(this.ID));
}
Run Code Online (Sandbox Code Playgroud)
Han*_*ant 51
Fwiw,这两个例子都没有使用标准的.NET约定.在EventHandler<T>一般的应申报的事件:
public event EventHandler<EmployeeEventArgs> Leave;
Run Code Online (Sandbox Code Playgroud)
应该为引发事件的受保护方法保留"On"前缀:
protected virtual void OnLeave(EmployeeEventArgs e) {
var handler = Leave;
if (handler != null) handler(this, e);
}
Run Code Online (Sandbox Code Playgroud)
你不具备做这种方式,但任何人一眼就能认出的模式,理解你的代码,并知道如何使用和定制.
并且它具有很大的优势,即不必被迫在自定义委托声明之间进行选择Action<>,这EventHandler<>是最好的方法.哪个回答你的问题.
Iva*_*vov 28
以下两行代码几乎相同:
public event Action<EmployeeEventAgs> Leave;
Run Code Online (Sandbox Code Playgroud)
相比:
public event EventHandler<EmployeeEventAgs> Leave;
Run Code Online (Sandbox Code Playgroud)
不同之处在于事件处理程序方法的签名.如果您对该操作使用第一种方法,则可以:
public void LeaveHandler(EmployeeEventAgs e) { ... }
Run Code Online (Sandbox Code Playgroud)
然后这个:
obj.Leave += LeaveHandler;
Run Code Online (Sandbox Code Playgroud)
使用第二种方法,LeaveHandler需要的签名是不同的:
public void LeaveHandler(object sender, EmployeeEventAgs e) { ... }
Run Code Online (Sandbox Code Playgroud)
请注意,在这两种情况下,关键字都用于声明事件成员,这一点非常重要event.以这种方式声明的事件成员不仅仅是类的一个字段,尽管看起来好像是这样.相反,编译器将其创建为事件属性1.事件属性类似于常规属性,除了它们没有get或set访问者.编译器允许它们仅在a +=和-=赋值的左侧使用(添加或删除事件处理程序).无法覆盖已分配的事件处理程序,也无法在声明它的类之外调用事件.
如果两个示例中都缺少event关键字,则可以执行以下操作,不会出现错误或警告:
obj.Leave = LeaveHandler;
Run Code Online (Sandbox Code Playgroud)
这将删除任何已注册的处理程序并替换它们LeaveHandler.
此外,您还可以执行此调用:
obj.Leave(new EmployeeEventAgs());
Run Code Online (Sandbox Code Playgroud)
如果您打算创建事件,则上述两种情况被视为反模式.应仅由所有者对象调用事件,并且不应允许无法删除订阅者.该event关键字是.NET的编程结构,它可以帮助你坚持正确的使用事件.
考虑到上述情况,我相信很多人都坚持这种EventHandler方法,因为EventHandler没有event关键字更不可能使用.操作具有更广泛的使用范围,当用作事件时它们看起来不那么自然.当然,后者是个人意见,因为事件处理程序方法在我自己的编码实践中可能变得太硬.但是,如果正确使用行动,将它们用于事件并非犯罪行为.
1事件属性是编译器在看到如下代码时自动生成的:
event EventHandler SomeEvent
Run Code Online (Sandbox Code Playgroud)
它与下面的代码大致相同:
private EventHandler _someEvent; // notice the lack of the event keyword!
public event EventHandler SomeEvent
{
add { _someEvent += value; }
remove { _someEvent -= value; }
}
Run Code Online (Sandbox Code Playgroud)
我们写的事件调用如下:
this.SomeEvent(sender, args);
Run Code Online (Sandbox Code Playgroud)
转换成这个:
this._someEvent(sender, args);
Run Code Online (Sandbox Code Playgroud)
pdr*_*pdr 22
Action<T> 与...完全相同 delegate void ... (T t)
Func<T> 与...完全相同 delegate T ... ()
Action只是完整委托声明的捷径.
public delegate void Action<T>(T obj)
Run Code Online (Sandbox Code Playgroud)
http://msdn.microsoft.com/en-us/library/018hxwa8.aspx
使用哪一个取决于您的组织编码标准/风格.
是的,Action 和 Func 只是 3.5 clr 中定义的方便委托。
Action、Func 和 lambda 都只是语法糖,方便使用委托。
它们没有什么神奇之处。有几个人编写了简单的 2.0 插件库来将此功能添加到 2.0 代码中。