1.爲何要使用委託?spa
生活中的委託就是委託他人幫咱們去辦一件事情,程序中的委託相似。看下面的例子code
class Class1 { static void Main(String[] args) { List<int> list = new List<int>(); list.Add(1); list.Add(2); list.Add(3); list.Add(4); list.Add(5); //過濾偶數 Even(list); ObjectDumper.Write(list); } //過濾集合中的偶數 public static void Even(List<int> list) { for (int i = 0; i < list.Count; i++) { if (list[i] % 2 != 0) { list.RemoveAt(i); i--; } } } //過濾集合中的奇數 public static void Odd(List<int> list) { for (int i = 0; i < list.Count; i++) { if (list[i] % 2 == 0) { list.RemoveAt(i); i--; } } } }
經過上面的例子咱們發現 Even()方法 和 Odd()方法只有一行代碼不一樣,使用委託能夠將方法當成參數傳遞,這樣作的好處是使程序之間的耦合下降,同時節省代碼。blog
改造上面的代碼以下:it
class Class2 { //聲明委託 public delegate bool Cal(int num); static void Main(String[] args) { List<int> list = new List<int>(); list.Add(1); list.Add(2); list.Add(3); list.Add(4); list.Add(5); //過濾偶數 Cal cal = new Cal(Even); MyCal(list, cal); ObjectDumper.Write(list); } public static bool Even(int num) { if (num % 2 == 0) { return true; } return false; } public static bool Odd(int num) { if (num % 2 != 0) { return true; } return false; } public static void MyCal(List<int> list,Cal cal) { for (int i = 0; i < list.Count; i++) { if (cal(list[i])) { list.RemoveAt(i); i--; } } } }
委託描述的是方法的簽名(包括參數類型、個數、返回值),上面聲明一個委託 Cal ,和 咱們要調用的方法同樣,接收一個 int類型的參數,返回bool類型。class
public delegate bool Cal(int num);
使用New關鍵字建立委託:lambda
Cal cal = new Cal(Even);
最後調用cal,獲得全部偶數項的集合List
MyCal(list, cal);
咱們在 MyCal(List<int> list,Cal cal) 方法中,傳遞了一個委託 做爲參數,Cal描述的是 Even 或者Odd方法的簽名,這樣能夠在調用的時候決定 是過濾奇數 仍是 過濾偶數。程序
這和咱們直接調用Even或Odd方法有什麼不一樣,不是更麻煩了嗎,接着往下看:方法
咱們能夠將過濾的方法改爲以下代碼:static
MyCal(list, delegate(int i) { if (i % 2 == 0) { return true; } return false; });
正由於MyCal方法接收的是一個委託,因此咱們能夠在不定義Even或Odd的時候,使用匿名委託。
這樣省去了沒必要要的代碼,使結構看起來更簡單,也不須要預先定義好方法,在調用的時候咱們臨時決定。
.NET 還給咱們提供了更進一步的簡化,使用Lambda表達式:
//代碼演進 //lamada MyCal(list, (i) => { return i % 2 == 0 ? true : false; });
i表示輸入參數 (i) => { return i % 2 == 0 ? true : false; } 是一條lambda語句,標識過濾偶數。
完整的代碼以下:
//聲明委託 public delegate bool Cal(int num); static void Main(String[] args) { List<int> list = new List<int>(); list.Add(1); list.Add(2); list.Add(3); list.Add(4); list.Add(5); MyCal(list, (i) => { return i % 2 == 0 ? true : false; }); ObjectDumper.Write(list); } public static void MyCal(List<int> list, Cal cal) { for (int i = 0; i < list.Count; i++) { if (cal(list[i])) { list.RemoveAt(i); i--; } } }
這樣作是否是比開始的時候簡單多了,不管後面再怎麼添加新的過濾方式,咱們只須要修改咱們的lambda語句,其餘的都不須要變更,這就是委託的魅力。