委托和事件
1.委托是一种引用类型,用于将方法作为参数传递给其他方法。
通过委托进行冒泡排序
1 using System; 2 class delegatesample { 3 // 定义一个委托 4 public delegate bool del (int fir, int sec); 5 public static void BubbleSort (int[] item, 6 del com) { 7 int i, j, temp; 8 for (i = item.Length - 1; i >= 0; i--) 9 for (j = 1; j <= i; j++) { 10 if (com (item[j - 1], item[j])) { 11 temp = item[j - 1]; 12 item[j - 1] = item[j]; 13 item[j] = temp; 14 } 15 } 16 } 17 // 委托实例化 18 public static bool method (int fir, int sec) { 19 return fir > sec; 20 } 21 static void Main () { 22 int[] item = { 2, 3, 6, 5, 4, 9, 5, 4, 33 }; 23 // 将方法当做参数传入另一个方法 24 BubbleSort (item, method); 25 for (int i = 0; i < item.Length; i++) 26 System.Console.WriteLine (item[i]); 27 } 28 }
使用匿名方法
1 using System; 2 class delegatesample { 3 // 定义一个委托 4 public delegate bool del (int fir, int sec); 5 public static void BubbleSort (int[] item, 6 del com) { 7 int i, j, temp; 8 for (i = item.Length - 1; i >= 0; i--) 9 for (j = 1; j <= i; j++) { 10 if (com (item[j - 1], item[j])) { 11 temp = item[j - 1]; 12 item[j - 1] = item[j]; 13 item[j] = temp; 14 } 15 } 16 } 17 static void Main () { 18 int[] item = { 2, 3, 6, 5, 4, 9, 5, 4, 33 }; 19 // 匿名方法 20 BubbleSort (item, delegate (int fir, int sec) { 21 return fir > sec; 22 }); 23 for (int i = 0; i < item.Length; i++) 24 System.Console.WriteLine (item[i]); 25 } 26 }匿名
使用Lambda语句
1 static void Main () { 2 int[] item = { 2, 3, 6, 5, 4, 9, 5, 4, 33 }; 3 // Lambda 4 BubbleSort (item, (fir, sec) => { 5 return fir > sec; 6 }); 7 for (int i = 0; i < item.Length; i++) 8 System.Console.WriteLine (item[i]); 9 }
使用Lambda表达式
1 static void Main () { 2 int[] item = { 2, 3, 6, 5, 4, 9, 5, 4, 33 }; 3 // Lambda 4 BubbleSort (item, (fir, sec) => fir > sec); 5 for (int i = 0; i < item.Length; i++) 6 System.Console.WriteLine (item[i]); 7 }


通用委托:System.Func和System.Action
func有返回值action没有

他俩不需要委托实例化,直接封装方法,需要命名空间System
Func最后一个类型总是委托的返回类型
1 using System; 2 class delegatesample { 3 public static void BubbleSort (int[] item, 4 Func<int, int, bool> com) { 5 int i, j, temp; 6 for (i = item.Length - 1; i >= 0; i--) 7 for (j = 1; j <= i; j++) { 8 if (com (item[j - 1], item[j])) { 9 temp = item[j - 1]; 10 item[j - 1] = item[j]; 11 item[j] = temp; 12 } 13 } 14 } 15 static void Main () { 16 int[] item = { 2, 3, 6, 5, 4, 9, 5, 4, 33 }; 17 BubbleSort (item, (fir, sec) => fir > sec); 18 for (int i = 0; i < item.Length; i++) 19 System.Console.WriteLine (item[i]); 20 } 21 }
注意:避免在匿名函数内捕捉循环变量,委托没有结构相等性。


2.事件

简单多播委托
1 using System; 2 // 注释为不用action的方法 3 /* delegate void del (string s); */ 4 class test { 5 static void Yahoo (string s) { 6 Console.WriteLine ("Yahoo,{0}!", s); 7 } 8 static void Huohua (string s) { 9 Console.WriteLine ("Huohua {0}!", s); 10 } 11 static void main () { 12 /* del fir, sec, one, two; */ 13 Action<string> fir = Yahoo, sec = Huohua, 14 two = fir + sec, one = two - sec; 15 /* fir = Yahoo; 16 sec = Huohua; 17 two = fir + sec; 18 one = two - sec; */ 19 Console.WriteLine ("输出:fir"); 20 fir ("a"); 21 Console.WriteLine ("输出:sec"); 22 sec ("b"); 23 Console.WriteLine ("输出:two"); 24 two ("c"); 25 Console.WriteLine ("输出:one"); 26 one ("d"); 27 } 28 }
温度控制多播委托
1 using System; 2 class Cooler { 3 public Cooler (float temperature) { Temperature = temperature; } 4 public float Temperature { get; set; } 5 public void OnTemperatureChanged (float newTemperature) { 6 if (newTemperature > Temperature) { 7 Console.WriteLine ("Cooler:On"); 8 } else Console.WriteLine ("Cooler:Off"); 9 } 10 } 11 class Heater { 12 public Heater (float tempreature) { 13 Temperature = tempreature; 14 } 15 public float Temperature { get; set; } 16 public void OnTemperatureChanged (float newTemperature) { 17 if (newTemperature < Temperature) { 18 System.Console.WriteLine ("Heatera:On"); 19 } else System.Console.WriteLine ("Heater:Off"); 20 } 21 } 22 public class Thermostat { 23 public Action<float> OnTemperatureChange { get; set; } 24 public float CurrentTem { 25 get { return _current; } 26 set { 27 if (value != CurrentTem) { 28 _current = value; 29 OnTemperatureChange?.Invoke (value); 30 } 31 } 32 } 33 private float _current; 34 } 35 //委托定义需要初始化 36 class P1 { 37 public static void Main () { 38 Thermostat thermostat = new Thermostat (); 39 Heater heater = new Heater (60); 40 Cooler cooler = new Cooler (80); 41 thermostat.OnTemperatureChange += 42 heater.OnTemperatureChanged; 43 thermostat.OnTemperatureChange += 44 cooler.OnTemperatureChanged; 45 // 从包容的类外部触发事件 46 thermostat.OnTemperatureChange (90); 47 } 48 }
注意:使用-=操作符会返回一个新实例 P371(c#本质论)
事件通过关键字event(event是CIL可以显示识别的一种东西)进行封装以更改委托两处问题。
- 防止使用=操作符出错
- 事件保证只有包容的类可以触发

1 using System; 2 class Cool : Handler { 3 public Cool (float tempreature, Handler tem) { 4 Tem = tempreature; 5 tem.OnTemChange += OnTemChanged; 6 } 7 private float Tem; 8 public void OnTemChanged (object sender, TemArgs T) { 9 if (T.NewTem > Tem) { 10 Console.WriteLine ("Cooler:On"); 11 } else Console.WriteLine ("Cooler:Off"); 12 } 13 } 14 // 订阅者 15 class Heat : Handler { 16 public Heat (float tempreature, Handler tem) { 17 Tem = tempreature; 18 tem.OnTemChange += OnTemChanged; 19 } 20 private float Tem; 21 public void OnTemChanged (object sender, TemArgs T) { 22 if (T.NewTem < Tem) { 23 System.Console.WriteLine ("Heater:On"); 24 } else System.Console.WriteLine ("Heater:Off"); 25 } 26 } 27 class Handler { 28 // 事件数据类型 29 public class TemArgs : System.EventArgs { 30 public TemArgs (float newTem) { 31 NewTem = newTem; 32 } 33 public float NewTem; 34 } 35 36 // 定义事件发布者 37 public event EventHandler<TemArgs> 38 OnTemChange = delegate { }; 39 40 // 事件触发器 41 public void handler (int i) { 42 if (OnTemChange != null) 43 OnTemChange (this, 44 new Handler.TemArgs (i)); 45 } 46 } 47 class P2 { 48 public static void Main () { 49 Handler publish = new Handler (); 50 Heat heater = new Heat (60, publish); 51 Cool cooler = new Cool (80, publish); 52 publish.handler (20); 53 Console.WriteLine (); 54 publish.handler (90); 55 } 56 }

浙公网安备 33010602011771号