第七章 委托和事件
回调(callback)函数是Windows编程的一个重要方面,实际上是方法调用的指针,也称为函数指针。
.Net以委托的形式实现了函数指针的概念,.Net的委托是类型安全的。
使用委托的时候,需要先声明,后实例化。
声明委托
delegate void MethodInvoker(); |
可以在委托前加public,private,protected。
?
实际上,定义委托是指定义一个新类,委托实现为派生自基类System.MulticastDelegate。
?
使用委托
private delegate string GetAString(); ? static void Main() { ????int x = 10; ????GetAString firstMethod = new GetAString(x.ToString); ????Console.WriteLine("String is {0}", firstMethod()); ????// Console.WriteLine("String is {0}", firstMethod.Invoke()); ? ? } |
委托在语法上总是带有一个参数的构造函数,这个参数就是委托引用的方法
C#引入和委托推断:
GetAString firstMethod = x.ToString; |
?
多播委托
包含多个方法调用的委托。调用委托的个数也与方法相同
delegate void DoubleOp(double value); ? DoubleOp operations = MathOperations.MultiplyByTwo; operations += MathOperations.Square; operations(2.0); |
会执行两个函数
也可使用-=
多播委托包含一个逐个调用的委托集合。如果通过委托调用的一个方法抛出了异常,整个迭代就会停止。解决方法:
DemoDelegate d1 = One; d1 += Two; ? Delegate[] delegates = d1.GetInvocationList(); foreach(DemoDelegate d in delegates) { ????try ????{ ????} ????catch(Exception) ????{ ????} } |
?
匿名方法
delegate string DelegateTest(string val); … DelegateTest an1 = delegate(string param) { ????statements; }; |
?
lambada表达式
C#3.0引入,创建匿名函数
DelegateTest an1 = param => { ????statements; ????return "some string"; }; |
lambada表达式中,运算符=>左边列出了参数类型和个数
可以忽略类型,只写标识符,用括号括住,当标识符只有一个时,可以省略括号。
?
例子
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Timers; ? namespace Chapter_7 { public delegate void MessageHandler(string messageText); ? public class Connection { public event MessageHandler MessageArrived; private Timer pollTimer; private static Random random = new Random(); private uint count = 0; ? public Connection() { pollTimer = new Timer(100); pollTimer.Elapsed += new ElapsedEventHandler(CheckForMessage); } ? public void Connect() { pollTimer.Start(); } ? public void Disconnect() { pollTimer.Stop(); } ? private void CheckForMessage(object source, ElapsedEventArgs e) { Console.WriteLine("Checking for new message."); if ((random.Next(9) == 0) && (MessageArrived != null)) { count++; MessageArrived("Hello Mum!"); } } } } |
using System; using System.Collections.Generic; using System.Linq; using System.Text; ? namespace Chapter_7 { public class Display { public void DisplayMessage(string message) { Console.WriteLine("message arrived:{0}", message); } } } |
using System; using System.Collections.Generic; using System.Linq; using System.Text; ? namespace Chapter_7 { public delegate void DoubleOp(double value); class Program { static void Main(string[] args) { ? Connection myConnection = new Connection(); Display myDisplay = new Display(); myConnection.MessageArrived += new MessageHandler(myDisplay.DisplayMessage); myConnection.Connect(); Console.ReadKey(); } } } |
第一行定义事件发布器
第二行定义事件订阅器
最后一行演示事件使用方法
参考:http://www.runoob.com/csharp/csharp-event.html
原文:http://www.cnblogs.com/xyb930826/p/5293929.html