(*) 委托 delegate
从最简单的例子开始:
namespace ConsoleApplication1 { class Program { // 委托其实就相当于一个类型。这里,类型的名字叫BinaryOp public delegate int BinaryOp(int x, int y); static public int Add(int x, int y) { return x + y; } static void Main() { // 创建一个BinaryOp类型的实例,用静态Add方法初始化 BinaryOp d = new BinaryOp(Add); Console.WriteLine(d(10, 10)); Console.ReadLine(); } } }
输出结果为:20
上面是静态方法的委托,下面再来看一个实例方法的委托。
class MyClass { private string name; public MyClass(string name) { this.name = name; } public void DisplayName() { Console.WriteLine("{0}", name); } } class Program { // 委托其实就相当于一个类型。这里,类型的名字叫SimpleDelegate public delegate void SimpleDelegate(); static void Main() { MyClass a = new MyClass("A"); MyClass b = new MyClass("B"); // 用实例方法DisplayName初始化 SimpleDelegate d = new SimpleDelegate(a.DisplayName); d(); d = new SimpleDelegate(b.DisplayName); d(); Console.ReadLine(); } }
输出结果为:A
B
(*) 事件
委托是个类型,而事件是个成员。看下面的代码:
namespace ConsoleApplication1 { public class SimpleMath { public delegate int BinaryOp(int a, int b); // 定义Binary类型 public event BinaryOp BinaryEvent; // 定义BinaryEvent成员 public int Add(int a, int b) { return a + b; } public int Substract(int a, int b) { return a - b; } public int Calculate() { // Raise the event by using the () operator. return BinaryEvent(1, 2); // 只能在定义事件的类的内部调用,如果写在外面会编译不过 } } class Program { static void Main() { SimpleMath sm = new SimpleMath(); // sm.BinaryEvent(1, 2); 编译错误!只能在定义事件的类的内部调用 // 下面两种注册方法效果是一样的,相当于注册了两遍,也的确会依序执行两遍 sm.BinaryEvent += new SimpleMath.BinaryOp(sm.Add); sm.BinaryEvent += sm.Add; Console.WriteLine(sm.Calculate()); // 结果是3 // 下面两种注册方法效果是一样的,相当于注册了两遍,也的确会依序执行两遍 sm.BinaryEvent += new SimpleMath.BinaryOp(sm.Substract); sm.BinaryEvent += sm.Substract; Console.WriteLine(sm.Calculate()); // -1, 只保留最后一次调用的返回值(3,3,-1,-1) Console.ReadLine(); } } }
输出结果为:3
-1
(*) 匿名方法
匿名方法的作用是使代码更简化,方便了程序员。如果没有匿名方法,则定义一套事件监听需要这样:
class Program { public delegate void SomeDelegate(); // 定义委托 static void Main() { SomeType obj = new SomeType(); obj.SomeEvent += new SomeDelegate(MyEventHandler); } // 一般来说,定义的MyEventHandler方法只用来响应事件,只在上面那一处地方使用 public static void MyEventHandler() // 定义委托所调用的方法 {} }
上面的代码比较啰嗦,尤其是为委托和它所调用的方法起名字比较费劲我觉得。有了匿名方法以后,仅需要这样:
class Program { static void Main() { SomeType obj = new SomeType(); obj.SomeEvent += delegate{ // 实现事件处理逻辑 }; // 注意要有分号 } }
与上一段代码相比,省去了SomeDelegate和MyEventHandler的定义。
拓展:点击打开链接
时间: 2024-12-01 22:06:35