委托是安全封裝方法的類型,類似於 C 和 C++ 中的函數指針。
與 C 函數指針不同的是,委托是面向對象的、類型安全的和可靠的。 委托的類型由委托的名稱確定。
使用委托工作有兩種方式:一種是事先定義好一個方法,然后委托到該方法上,另外一種就是直接在代碼中使用匿名方法。
1.直接使用委托
1 public delegate void Printf(string str); 2 static void Main(string[] args) 3 { 4 Printf printf = DelegateMethod; 5 printf("This is the first DelegateFunction!"); 6 Console.Read(); 7 } 8 public static void DelegateMethod(string str) 9 { 10 Console.WriteLine(str); 11 }
輸出 This is the first DelegateFunction! 對委托進行實例化后,委托會將對其進行的方法調用傳遞到該方法。 調用方傳遞到委托的參數將傳遞到該方法,並且委托會將方法的返回值(如果有)返回到調用方, 這被稱為調用委托。 實例化的委托可以按封裝的方法本身進行調用。
2.使用匿名方法
1 public delegate void Printf(string str); 2 static void Main(string[] args) 3 { 4 Printf printf = delegate (string str) 5 { 6 Console.WriteLine(str + "the first DelegateFunction!"); 7 }; 8 printf("This is "); 9 Console.Read(); 10 }
輸出 This is the first DelegateFunction!
3.匿名委托簡單比較
1 public delegate void Printf(); 2 static void Main(string[] args) 3 { 4 string this_is = "this is "; 5 string the_first = "the first "; 6 Printf printf = delegate () 7 { 8 Console.WriteLine(this_is + the_first + "DelegateFunction!"); 9 }; 10 printf(); 11 Console.Read(); 12 }
輸出 This is the first DelegateFunction! 但看下段代碼。
1 public delegate void Printf(); 2 static void Main(string[] args) 3 { 4 string the_first = "the first "; 5 Printf printf = delegate () 6 { 7 Console.WriteLine("this is " + the_first + "DelegateFunction!"); 8 the_first = "the second "; 9 }; 10 the_first = "the third "; 11 printf(); 12 printf(); 13 Console.Read(); 14 }
第一個printf()輸出This is the third DelegateFunction! 第二個printf()輸出This is the second DelegateFunction!
the_first作為匿名方法外部變量,在未對匿名委托進行實例化時,不執行匿名委托內部操作,所以先輸出the third,第一次實例化后執行匿名委托內部操作,the_first變為the second,即輸出the second。
4.匿名方法捕獲的變量延長其生命周期
1 public delegate void MethodInvoker(); 2 static void Main(string[] args) 3 { 4 MethodInvoker methodInvoker = CreateDelegate(); 5 methodInvoker(); 6 Console.Read(); 7 } 8 static MethodInvoker CreateDelegate() 9 { 10 int tempCount; 11 MethodInvoker method = delegate 12 { 13 tempCount = 1; 14 Console.WriteLine("This tempCount is {0}", tempCount); 15 tempCount++; 16 }; 17 method(); 18 return method; 19 }
輸出This tempCount is 1
This tempCount is 1
第一次調用method();之后返回method(),主程序運行至methodInvoker();時,實際上並未執行static MethodInvoker CreateDelegate()中tempCount變量定義,實際上tempCount並不在棧上,編譯器創建了一個額外的類來存儲變量,CreateDelegate()方法對該類有一個實例引用,所以它可以使用tempCount,而委托也對該實例有一個引用,除非委托准備好被GC回收。
5.匿名方法中局部變量的實例化
1 public delegate void MethodInvoker(); 2 static void Main(string[] args) 3 { 4 MethodInvoker newDelegate = CreateDelegate(); 5 newDelegate(); 6 newDelegate(); 7 Console.Read(); 8 } 9 static MethodInvoker CreateDelegate() 10 { 11 int tempOtherCount = 1; 12 MethodInvoker method = delegate 13 { 14 int tempCount = 1; 15 Console.WriteLine("This tempCount is {0}", tempCount); 16 Console.WriteLine("This tempOtherCount is {0}", tempOtherCount); 17 tempCount++; 18 tempOtherCount++; 19 }; 20 method(); 21 return method; 22 }
輸出 This tempCount is 1
This tempOtherCount is 1
This tempCount is 1
This tempOtherCount is 2
This tempCount is 1
This tempOtherCount is 3
CreateDelegate()內部method();先輸出,執行第一個newDelegate();tempCount又被實例化一次賦值為1,執行第二個newDelegate();tempCount再次被實例化一次賦值為1。而tempOtherCount一直是同一實例,所以值++。