總結: 當你覺得需要方法調用方法的時候,就使用委託吧
.NET以委託形式實現函數指標,但是委託同時又是型別安全的。
在C和C++,只能提取函數的地址,並傳送為一個參數。C是沒有型別安全的,可以把任何函數傳送給需要函數指標的方法。這導致一些問題,例如型別安全。進行物件導向編程的時候,方法不是孤立存在的,在調用前需要與執行個體相關聯。如果要傳遞方法,就必須把方法的細節封裝在一種新類型對象中,這就是委託。
委託主要用於以下3個方面:
例子1:
/* * Created by SharpDevelop. * User: Administrator * Date: 2010-3-15 * Time: 20:19 * * To change this template use Tools | Options | Coding | Edit Standard Headers. */using System;namespace Delegate1{class Program{private delegate string GetAString();public static void Main(string[] args){int x = 40;GetAString firstStringMethod = new GetAString(x.ToString);Console.WriteLine("String is {0}" + firstStringMethod());// TODO: Implement Functionality HereConsole.Write("Press any key to continue . . . ");Console.ReadKey(true);}}}
在C#裡,委託在文法上總是帶有一個參數的建構函式,這個參數就是委託引用的方法。需要用執行個體和方法名來正確初始化委託。 x.ToString
給委託執行個體提供括弧和調用委託的Invoke()方法完全相同。
firstStringMethod(); ==== firstStringMethod.Invoke();
委託的一個簡單樣本:
/* * Created by SharpDevelop. * User: Administrator * Date: 2010-3-15 * Time: 20:52 * * To change this template use Tools | Options | Coding | Edit Standard Headers. */using System;namespace Delegate2{class MathOperations{public static double MultipleByTwo(double value){return value*2;}public static double Square(double value){return value*value;}}class Program{delegate double DoubleOp(double x);public static void Main(string[] args){DoubleOp [] operations = {MathOperations.MultipleByTwo, MathOperations.Square};for (int i = 0; i < operations.Length; i++){Console.WriteLine("Using operations[{0}]:", i);ProcessAndDisplayNumber(operations[i], 2.0);ProcessAndDisplayNumber(operations[i], 7.94);ProcessAndDisplayNumber(operations[i], 1.414);}Console.Write("Press any key to continue . . . ");Console.ReadKey(true);}static void ProcessAndDisplayNumber(DoubleOp action, double value){double result = action(value);Console.WriteLine("Value is {0}, result of operation is {1}", value, result);}}}
運行結果如下:
關於委託經典實用案例分析:
關於冒泡排序:
冒泡排序的過程很簡單,源碼如下:
for (int i = 0; i < sortArray.Length; i++)for(int j = i + 1; j < sortArray.Length; j++){if (sortArray[i] < sortArray [j]){int temp = sortArray [i];sortArray[i] = sortArray[j];sortArray[j] = temp;}}
這是對於一個int型的數組進行的排序。現在目標是要把這個排序過程擴大對任何對象都能排序。這裡面這個就有問題了 sortArray[i] < sortArray [j] 不能對任何對象都可以進行簡單的比較。假定對公司的員工,按薪資順序進行排序,這個可以怎麼做?
首先,冒泡排序的類必須要調用一個比較2個object的方法。
delegate bool Comparison(object x, object y);static public void Sort(object[] sortArray, Comparison comparison)
但是sort不能單獨存在,所以有下面的class
/* * Created by SharpDevelop. * User: Administrator * Date: 2010-3-15 * Time: 21:27 * * To change this template use Tools | Options | Coding | Edit Standard Headers. */using System;namespace Delegate3{class Employee{private string name;private decimal salary;public Employee(string name, decimal salary){this.name = name;this.salary = salary;}public override string ToString(){return string.Format("{0},{1:C}",name,salary);}public static bool CompareSalary(object x, object y){Employee e1 = (Employee)x;Employee e2 = (Employee)y;return(e1.salary < e2.salary);}}delegate bool Comparison(object x, object y);class BubbleSorter{static public void Sort(object [] sortArray, Comparison comparison){for (int i = 0; i < sortArray.Length; i++)for(int j = i + 1; j < sortArray.Length; j++){if (comparison(sortArray[i],sortArray[j])){object temp = sortArray [i];sortArray[i] = sortArray[j];sortArray[j] = temp;}}}}class Program{public static void Main(string[] args){Employee [] employees ={new Employee("Bugs Bunny", 2000),new Employee("Elmer Fudd", 10000),new Employee("Daffy Duck", 2500),new Employee("Wiley Coyte", (decimal) 10456.89),new Employee("Fghon leghorn", 23000),};BubbleSorter.Sort(employees, Employee.CompareSalary);foreach(var employee in employees){Console.WriteLine(employee);}// TODO: Implement Functionality HereConsole.Write("Press any key to continue . . . ");Console.ReadKey(true);}}}
這個例子有個地方需要改進
public static bool CompareSalary(object x, object y){Employee e1 = (Employee)x;Employee e2 = (Employee)y;return(e1.salary < e2.salary);}
上面這段代碼是出現在Employee類裡面的,參數沒有必要用object哦, 可以考慮如下寫法,更簡潔些
public static bool CompareSalary(Employee x, Employee y){return(x.salary < y.salary);}
囧,貌似自作聰明了。 delegate bool Comparison(object x, object y); 聲明的是對object類的調用,委託還是型別安全的。上面的改法肯定不可以哦!