委托,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));    
        }

 第一次写,呵呵

原文地址:https://www.cnblogs.com/piaoxuewuming/p/2675352.html