C#高级编程 (第六版) 学习 第七章:委托和事件
第七章 委托和事件
回调(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