1.概括
1.1、委托是寻址方法的.NET版本,类似C++中的指针。委托可以理解成指向函数的指针,它是类型安全的,定义了具体的参数和返回值。
——定义一个委托,实际上是定义一个类。委托是对方法的引用,如方法Func,把其功能交给委托的类来实现。
——委托的作用:结合泛型,可以实现功能上的扩展(如针对整型的函数,可以通过委托指向多种函数,实现类中某个属性的比较)。Lambda表达式需要使用委托定义。事件需要使用到委托。
1.2、Lambda表达式与委托直接相关。Lambda表达式可以理解成一个简单的方法定义(包含参数、返回值),表达式由委托来指向。
——Lambda表达式的作用,减少代码量。
1.3、事件,基于委托,为委托提供了一种发布/订阅机制。最直接的就是Button的Click事件。
2.代码展示
2.1、委托
2.1.1:如何定义一个委托:
1、这是需要进行委托的函数
public static double MultiplyByTwo(double value) { return value * 2; } public static double Square(double value) { return value * value; }
2、然后定义一个委托DoubleOp
delegate double DoubleOp(double x); DoubleOp[] operations = { MathOperations.MultiplyByTwo, MathOperations.Square };
3、调用委托
Console.WriteLine(operations[0](2)); Console.WriteLine(operations[1](2));
4、返回结果
2.1.2:Action<T>委托和Func<T>委托
Action为返回值void的委托,Func为带返回类型(最后一个参数为返回类型)。
如A中的第2步,可以改写做:
Func<double, double>[] operations2 = { MathOperations.MultiplyByTwo, MathOperations.Square };
委托更多的用处是作为函数的参数,可以把符合一定要求(参数、返回值一致)的函数作为参数传入其他函数(是不是很类似指针?)。
如C#高级编程中的冒泡排序法:
//Func的参数是动态的,根据实际添加的个数决定。 static public void Sort<T>(IList<T> sortArray, Func<T, T, bool> comparison) { bool swapped = true; do { swapped = false; for (int i = 0; i < sortArray.Count - 1; i++) { if (comparison(sortArray[i+1], sortArray[i])) { T temp = sortArray[i]; sortArray[i] = sortArray[i + 1]; sortArray[i + 1] = temp; swapped = true; } } } while (swapped); }
其中一个参数为Func<T,T,bool> comparison。Sort<T>为泛型函数,可以对不同类型T的对象进行排序,而排序方法使用委托comparison。这样使用委托的改动,可以提高Sort函数的适用性,如范例中需要根据员工工资来进行排序,只需要传入一个根据类型Employee来比较员工工资的comparison即可。
以下为调用的范例:
Employee[] employees = { new Employee("Bugs Bunny", 20000), new Employee("Elmer Fudd", 10000), new Employee("Daffy Duck", 25000), new Employee("Wile Coyote", 1000000.38m), new Employee("Foghorn Leghorn", 23000), new Employee("RoadRunner", 50000) }; BubbleSorter.Sort(employees, Employee.CompareSalary);
比较员工工资的comparison——即Employee.CompareSalary是这么写的:
public static bool CompareSalary(Employee e1, Employee e2) { return e1.Salary < e2.Salary; }
2.2、Lambda表达式
简单的定义函数的方式。
string mid = ",2,"; //有花括号(多条语句的情况)的需要return语句 Func<string, string> lambdaTest = param => { param += mid; param += "3"; return param; }; Console.WriteLine(lambdaTest("1")); //没有花括号的会隐式添加一条return语句 Func<string, string> oneParam = s => String.Format("change uppercase {0}", s.ToUpper()); Console.WriteLine(oneParam("test")); Func<double, double, double> twoParams = (x, y) => x * y; Console.WriteLine(twoParams(3, 2)); Func<double, double, double> twoParamsWithTypes = (double x, double y) => x * y; Console.WriteLine(twoParamsWithTypes(4, 2)); Func<double, double> operations = x => x * 2; operations += x => x * x; ProcessAndDisplayNumber(operations, 2.0);