通俗解釋:委托就是一個能存放符合某種格式(方法簽名)的方法的指針
自己理解:委托就是定義一個變量來存放方法,這個委托可以存放多個方法,在調用的時候,會按照添加的次序來執行添加的方法
其實委托類似於C語言中的指針,他是一種數據類型的名字,例如int、double等,只不過,指針類型存放的是方法。 委托本身就是一個類,可以寫在類的裡面或者類的外邊,本身是一個語法糖,在編譯的時候會編譯成一個類。
因為委托是一個存放方法的數據類型,所以委托的作用如下 將方法作為參數將方法作為返回值將方法作為外部屬性
因為委托本身就是一個類,在使用的時候需一下幾個步驟
聲明委托創建委托對象調用委托
1.排序
現有一個Dog類,這個Dog類屬性有 Name、Age 如下:
public class Dog { private string name; public string Name { get { return name; } set { name = value; } } private int age; public int Age { get { return age; } set { age = value; } } }
為這個Dog類創建多個對象,並存放在List的泛型中,如下:Listlist = new List (); list.Add(new Dog() { Name = "小黑", Age = 12 }); list.Add(new Dog() { Name = "小綠", Age = 2 }); list.Add(new Dog() { Name = "小白", Age = 22 }); list.Add(new Dog() { Name = "小青", Age = 34 });
需求:現在需要為這個泛型集合中的小狗狗們按照年齡進行排序,目前有兩種解決方案,1.使用接口;2.使用委托;3.使用lamda表達式在List集合中,有一個排序的方法Sort(),具有4個重載,分別如下:
public void Sort();
public void Sort(Comparisoncomparison);
public void Sort(IComparercomparer);
public void Sort(int index, int count, IComparercomparer);
在這裡,1,4,不進行闡述,主要講解2,3
1.使用接口進行排序。
public void Sort(IComparer
comparer); 這個方法就是使用接口實現對對象進行排序
講解:
IComparer是一個接口,其接口會實現一個Compare方法,來指定排序的條件,接口定義如下:
// 摘要: // 定義類型為比較兩個對象而實現的方法。 // // 類型參數: // T: // 要比較的對象的類型。 public interface IComparer{ // 摘要: // 比較兩個對象並返回一個值,指示一個對象是小於、等於還是大於另一個對象。 // // 參數: // x: // 要比較的第一個對象。 // // y: // 要比較的第二個對象。 // // 返回結果: // 一個帶符號整數,它指示 x 與 y 的相對值,如下表所示。值含義小於零x 小於 y。零x 等於 y。大於零x 大於 y。 int Compare(T x, T y); }
那麼,在使用接口的時候,我們要定義一個類CompareDog,來繼承這個接口,並且設定排序的條件是按照對象中的年齡屬性進行排序的,代碼如下:public class CompareDog:IComparer{ public int Compare(Dog x, Dog y) { return x.Age - y.Age; } }
這樣的話,我們就可以使用Sort(IComparercomparer)這個方法來對集合進行排序了,這裡的參數就是我們上邊定義的CompareDog類,它實現了IComparer接口。 list.Sort(new CompareDog());//這樣既實現了對集合的排序
2.使用委托排序
public void Sort(Comparisoncomparison);
這個方法就是使用委托對集合進行排序
講解: Comparison其實就是一個委托類型,定義如下:// 摘要: // 表示比較同一類型的兩個對象的方法。 // // 參數: // x: // 要比較的第一個對象。 // // y: // 要比較的第二個對象。 // // 類型參數: // T: // 要比較的對象的類型。 // // 返回結果: // 一個有符號整數,它指示 x 與 y 的相對值,如下表所示。值含義小於 0x 小於 y。0x 等於 y。大於 0x 大於 y。 public delegate int Comparison(T x, T y);
既然是委托類型的參數,那麼我們就要寫一個符合該委托的方法,並指定排序的條件,代碼如下:int Comparison(Dog x, Dog y) { return x.Age - y.Age; }
這樣,我們在排序的時候,只需要將上邊的這個方法傳入作為參數即可:list.Sort(Comparison);
3.使用lamda表達式排序
其實,lamda表達式的本質就是一個委托,只不過微軟把它變成了語法糖,方便程序員的使用,這裡不多闡述,代碼如下即可實現:list.Sort((x,y)=>x.Age-y.Age);
2.求最大值
要求:有一個int型的數組,求其中的最大值
我們先按照常規的思想來做,然後在使用委托實現。
int[] arrInt = new int[5] { 1,3,8,4,2};
常規思想:定義一個方法,傳入這個數組作為參數,然後循環遍歷該數組,取出最大值,方法如下:
int MaxInt(int[] arr) { int maxInt = arr[0]; for (int i = 1; i < arr.Length; i++) { if (maxInt < arr[i]) { maxInt = arr[i]; } } return maxInt; }
調用:int[] arrInt = new int[5] { 1,3,8,4,2}; int max = MaxInt(arrInt);
注:以上自定義的方法可以實現求int型數據的最大值,那麼如果求double型的最大值?string類型的字符串長度?對象中按照指定的屬性求最大值? 這樣的話就得針對每一種情況都要寫一個方法,從邏輯上是可以實現的,但是使用委托會是一種更好的方法。
委托實現
定義一個泛型方法,傳入數組作為參數,同時傳入Comparison
類型作為比較的委托,這個委托在上邊已經講解過,代碼如下: T MaxValue(T[] arr,Comparison func) { T maxInt = arr[0]; for (int i = 1; i < arr.Length; i++) { //使用委托來比較 if (func(maxInt, arr[i]) < 0) { maxInt = arr[i]; } } return maxInt; }
調用:這裡的委托方法參數使用lamda表達式表示//求最大數 int[] arrInt = new int[5] { 1,3,8,4,2}; int max = MaxValue(arrInt, (x, y) => x - y); //求字符串長度最大的字符串 string[] arrStr = new string[] { "aa","fcc","tgtgc"}; string maxLenght = MaxValue (arrStr, (x, y) => x.Length - y.Length); //按照年齡,求對象集合中年齡最大的對象 Dog[] dogs = new Dog[] { new Dog() { Name = "小黑", Age = 12 }, new Dog() { Name = "小lv", Age = 2 }, new Dog() { Name = "小bai", Age = 62 }, new Dog() { Name = "小qing", Age = 22 } }; Dog maxDog = MaxValue (dogs, (x, y) => x.Age - y.Age);
不喜勿噴,歡迎評論!