标签:
第二章:C#委托和事件
第二节:事件
事件其实没什么不好理解的,声明一个事件不过类似于声明一个委托类型的变量而已。
1 public class MyTestClass 2 { 3 //定义委托 4 public delegate void MyDelegateHandler(string param); 5 6 //构造函数 7 public MyTestClass() 8 { 9 this.MyDelegateHappened += this.MyInsideDelegateMethod; 10 } 11 12 //内部方法 13 private void MyInsideDelegateMethod(string param) 14 { 15 Console.WriteLine("I am running inside the class \"MyClass\" -> void MyInsideDelegateMethod(string param)"); 16 Console.WriteLine(param); 17 } 18 19 //执行 20 public void Execute(string param) 21 { 22 this.OnMyDeletateHappened(param); 23 } 24 25 //事件 26 public event MyDelegateHandler MyDelegateHappened; 27 protected virtual void OnMyDeletateHappened(string param) 28 { 29 MyDelegateHandler handler = this.MyDelegateHappened; 30 if (handler != null) 31 { 32 handler(param); 33 } 34 } 35 }
调用:
1 static void Main(string[] args) 2 { 3 Console.WriteLine("Only the inside method will be executed!"); 4 //实例化 5 MyTestClass myTestClass = new MyTestClass(); 6 myTestClass.Execute("Hello, world!"); 7 Console.WriteLine(); 8 9 Console.WriteLine("The outside method will be added to the delegate logic!"); 10 //新增外部委托的方法 11 myTestClass.MyDelegateHappened += MyOutsideDelegateMethod; 12 myTestClass.Execute("Hello, world!"); 13 Console.WriteLine(); 14 15 Console.WriteLine("The outside method will be removed from the delegate logic!"); 16 //去除外部委托的方法 17 myTestClass.MyDelegateHappened -= MyOutsideDelegateMethod; 18 myTestClass.Execute("Hello, world!"); 19 Console.ReadLine(); 20 } 21 22 private static void MyOutsideDelegateMethod(string param) 23 { 24 Console.WriteLine("I am running ouside the class \"Program\" -> void MyOutsideDelegateMethod(string param)"); 25 Console.WriteLine(param); 26 }
运行结果:
Only the inside method will be executed!
I am running inside the class "MyClass" -> void MyInsideDelegateMethod(string param)
Hello, world!
The outside method will be added to the delegate logic!
I am running inside the class "MyClass" -> void MyInsideDelegateMethod(string param)
Hello, world!
I am running ouside the class "Program" -> void MyOutsideDelegateMethod(string param)
Hello, world!
The outside method will be removed from the delegate logic!
I am running inside the class "MyClass" -> void MyInsideDelegateMethod(string param)
Hello, world!
相信有部分读者看到这里,会想起C#里面常见的EventHandler
a. 不带参数的
public event EventHandler MyEventHappened; protected virtual void OnMyEventHanppened() { EventHandler handler = this.MyEventHappened; if (handler != null) { handler(this, EventArgs.Empty); } }
其实,请看EventHandler实际的本质是什么:(F12 Go To Definition)
1 #region Assembly mscorlib.dll, v4.0.0.0 2 // C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\mscorlib.dll 3 #endregion 4 5 using System.Runtime.InteropServices; 6 7 namespace System 8 { 9 // Summary: 10 // Represents the method that will handle an event that has no event data. 11 // 12 // Parameters: 13 // sender: 14 // The source of the event. 15 // 16 // e: 17 // An System.EventArgs that contains no event data. 18 [Serializable] 19 [ComVisible(true)] 20 public delegate void EventHandler(object sender, EventArgs e); 21 }
b. 带参数的
public event EventHandler<EventArgs> MyEventHappened; protected virtual void OnMyEventHanppened(EventArgs args) { EventHandler<EventArgs> handler = this.MyEventHappened; if (handler != null) { handler(this, args); } }
1 #region Assembly mscorlib.dll, v4.0.0.0 2 // C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\mscorlib.dll 3 #endregion 4 5 namespace System 6 { 7 // Summary: 8 // Represents the method that will handle an event. 9 // 10 // Parameters: 11 // sender: 12 // The source of the event. 13 // 14 // e: 15 // An System.EventArgs that contains the event data. 16 // 17 // Type parameters: 18 // TEventArgs: 19 // The type of the event data generated by the event. 20 [Serializable] 21 public delegate void EventHandler<TEventArgs>(object sender, TEventArgs e); 22 }
带参数的EventArgs,可以我们自己定义继承类去传递我们需要的数据:
1 public class MyEventArgs : EventArgs 2 { 3 private string _param; 4 5 public MyEventArgs(string param) 6 { 7 this._param = param; 8 } 9 10 public string Param 11 { 12 get { return this._param; } 13 } 14 }
定义event的时候:
1 public event EventHandler<MyEventArgs> MyEventHappened2; 2 protected virtual void OnMyEventHappened2(MyEventArgs args) 3 { 4 EventHandler<MyEventArgs> handler = this.MyEventHappened2; 5 if (handler != null) 6 { 7 handler(this, args); 8 } 9 }
上述两个示例说明:EventHandler本质,依然是一个delegate!只不过它是由系统定义好了而已,现在编程者常用这种方式,便于使用。
代码:
1 public class MyTestClass2 { 2 public void Execute(string param) 3 { 4 this.OnMyEventHappened(new MyEventArgs(param)); 5 } 6 7 public event EventHandler<MyEventArgs> MyEventHappened; 8 protected virtual void OnMyEventHappened(MyEventArgs args) 9 { 10 EventHandler<MyEventArgs> handler = this.MyEventHappened; 11 if (handler != null) 12 { 13 handler(this, args); 14 } 15 } 16 } 17 18 public class MyEventArgs : EventArgs 19 { 20 private string _param; 21 22 public MyEventArgs(string param) 23 { 24 this._param = param; 25 } 26 27 public string Param 28 { 29 get { return this._param; } 30 } 31 }
调用:
1 static void Main(string[] args) 2 { 3 MyTestClass2 myTestClass = new MyTestClass2(); 4 myTestClass.MyEventHappened += MyTestClass_MyEventHappened; 5 myTestClass.Execute("Hi~"); 6 7 Console.ReadLine(); 8 } 9 10 private static void MyTestClass_MyEventHappened(object sender, MyEventArgs e) 11 { 12 Console.WriteLine(e.Param); 13 }
运行结果:
Hi~
此程序中:myTestClass.Execute("Hi~");其实也可以由类的内部调用——这样做,就可以做到类的实例内部触发事件,然后做到“通知”外部注册时逻辑被执行的效果!
综上所述,大家是不是对委托和事件有更清晰的认识了呢?
标签:
原文地址:http://www.cnblogs.com/Min-min/p/5095650.html