標籤:
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);
C# 委託、Lambda運算式和事件——學習總結