委托,Lambda,事件学习
委托是寻址方法的.net版本,是类型安全的类,它定义了返回类型和参数的类型,包含方法的引用及多个方法的引用(微软的解释)。
我理解是:就是一个方法的类型(就是有相同参数个数,相同参数类型和返回类型)。
委托的定义:delegate T qiuhe<T>(T a, T b); T 为任何类型
委托实现派生System.MulticastDelegate>System.Delegate
定义委托基本上是定义一个新类,所以可以在定义类的任何相同地方第一委托(可以在另一个类的内部或外部命名空间中定义),可以加访问修饰符:public,private,protected等。
泛型委托:Action<T>,Func<T>,至多可以传递16个参数类型和一个返回类型
例子:对不同类型实体按指定规则排序
1 class Program 2 { 3 static void Main(string[] args) 4 { 5 Employee[] ems = { 6 new Employee("张三",20000), 7 new Employee("李四",15000), 8 new Employee("杨过",55000), 9 new Employee("小龙女",75000), 10 new Employee("段誉",85000), 11 new Employee("周五",35000), 12 }; 13 Console.WriteLine("排序前:"); 14 foreach (var item in ems) 15 { 16 Console.WriteLine(item); 17 } 18 Sort<Employee>(ems, Employee.CompareSalary); 19 Console.WriteLine("排序后:"); 20 foreach (var item in ems) 21 { 22 Console.WriteLine(item); 23 } 24 Console.WriteLine("--------------------------------------"); 25 MaxSalary<Employee>(ems, Employee.GetSalaryEmployee); 26 MinSalary<Employee>(ems, Employee.GetSalaryEmployee); 27 Console.WriteLine("----------2---------------------------"); 28 Action<IList<Employee>, Func<Employee, Employee, bool, Employee>> aa = MaxSalary; 29 aa += MinSalary; 30 test(aa, ems, Employee.GetSalaryEmployee); 31 Console.WriteLine("------------匿名方法------------------"); 32 niming(); 33 Console.WriteLine("============Lambda----------------表达式---------"); 34 35 lambda(ems); 36 37 Console.ReadLine(); 38 } 39 40 public static void Sort<T>(IList<T> sortArray, Func<T, T, bool> com) 41 { 42 bool swapped = true; 43 do 44 { 45 swapped = false; 46 for (int i = 0; i < sortArray.Count - 1; i++) 47 { 48 if (com(sortArray[i + 1], sortArray[i])) 49 { 50 T temp = sortArray[i]; 51 sortArray[i] = sortArray[i + 1]; 52 sortArray[i + 1] = temp; 53 swapped = true; 54 } 55 } 56 } 57 while (swapped); 58 } 59 60 public static void MaxSalary<T>(IList<T> sortArray, Func<T, T, bool, T> com) 61 { 62 T temp = sortArray[0]; 63 for (int i = 0; i < sortArray.Count - 1; i++) 64 { 65 temp = com(temp, sortArray[i + 1], true); 66 } 67 Console.WriteLine("最高工资:" + temp.ToString()); 68 69 } 70 71 public static void MinSalary<T>(IList<T> sortArray, Func<T, T, bool, T> com) 72 { 73 T temp = sortArray[0]; 74 for (int i = 0; i < sortArray.Count - 1; i++) 75 { 76 temp = com(temp, sortArray[i + 1], false); 77 } 78 Console.WriteLine("最低工资:" + temp.ToString()); 79 } 80 81 public static void test(Action<IList<Employee>, Func<Employee, Employee, bool, Employee>> action, IList<Employee> sortArray, Func<Employee, Employee, bool, Employee> com) 82 { 83 action(sortArray, com); 84 } 85 86 public static void niming() 87 { 88 string str; 89 Func<string, string, string> funcdel = delegate(string str1, string str2) 90 { 91 return str1 + "和" + str2; 92 }; 93 str = funcdel("小龙女", "杨过"); 94 Console.WriteLine(str); 95 } 96 97 public static void lambda(IList<Employee> ems) 98 { 99 Console.WriteLine("最高工资 " + ems.Max(p => p.Salary)); 100 101 } 102 }
1 class Employee 2 { 3 public Employee(string name, decimal salary) 4 { 5 this.Name = name; 6 this.Salary = salary; 7 } 8 public string Name { get; set; } 9 public decimal Salary { get; set; } 10 /// <summary> 11 /// 重写tostring方法 12 /// </summary> 13 /// <returns></returns> 14 public override string ToString() 15 { 16 return string.Format("{0},{1:C}", Name, Salary); 17 } 18 /// <summary> 19 /// 小到大 20 /// </summary> 21 /// <param name="e1"></param> 22 /// <param name="e2"></param> 23 /// <returns></returns> 24 public static bool CompareSalary(Employee e1, Employee e2) 25 { 26 return e1.Salary < e2.Salary; 27 } 28 /// <summary> 29 /// 比较大小返回大的对象或小的 30 /// </summary> 31 /// <param name="e1"></param> 32 /// <param name="e2"></param> 33 /// <param name="ismax">true 返回大的</param> 34 /// <returns></returns> 35 public static Employee GetSalaryEmployee(Employee e1, Employee e2, bool ismax) 36 { 37 if (ismax) 38 { 39 return e1.Salary < e2.Salary ? e2 : e1; 40 } 41 return e1.Salary < e2.Salary ? e1 : e2; 42 } 43 44 }
多播委托:委托也可以包含多过方法,这种委托称为多播委托
如果调用多播委托,就可以按顺序连续调用多个方法,为此,委托的签名就必须返回void;否则,就只能得到委托调用的最后一个方法的结果。
Action<IList<Employee>, Func<Employee, Employee, bool, Employee>> aa = MaxSalary;
aa += MinSalary;
test(aa, ems, Employee.GetSalaryEmployee);
支持运算符+,+=,-,-=
匿名方法:是用着委托的参数的一段代码
例如:
public static void niming()
{
string str;
Func<string, string, string> funcdel = delegate(string str1, string str2)
{
return str1 + "和" + str2;
};
str = funcdel("小龙女", "杨过");
Console.WriteLine(str);
}
使用匿名方法时,必须遵循两条规则。在匿名方法中不能使用跳转语句(break,goto或continue)跳到该匿名方法的外部,反之亦然:匿名方法外部的跳转语句不能跳到该匿名方法的内部。在匿名方法内部不能访问不安全的代码。另外,也不能访问在匿名方法外部使用的ref和out参数。但可以使用在匿名方法外部定义的其他变量。
如果需要匿名方法多次编写同一个功能,就不要使用匿名方法。
Lambda 表达式
运算符=>
访问外部变量,编译器会创建一个匿名类,它有一个构造函数来传递外部变量。
public static void lambda(IList<Employee> ems)
{
Console.WriteLine("最高工资 " + ems.Max(p => p.Salary));
}
第一次写,呵呵