C#是跟著楊老師的教程走的,在這裡感謝一下老師的無私奉獻,他的cnblog地址:>cgzl,他的B站地址:>solenovex。 進入正題: Delegate表示委托,委托是一種數據結構,它引用靜態方法或引用類實例及該類的實例方法。(引用官方文檔的英文原話) Represents a delegat ...
C#是跟著楊老師的教程走的,在這裡感謝一下老師的無私奉獻,他的cnblog地址:>cgzl,他的B站地址:>solenovex。
進入正題:
Delegate表示委托,委托是一種數據結構,它引用靜態方法或引用類實例及該類的實例方法。(引用官方文檔的英文原話)
Represents a delegate, which is a data structure that refers to a static method or to a class instance and an instance method of that class.
看不懂沒關係,我也看不懂,哈哈哈。
直接拿兩個例子看一下,第一個是楊老師提供的。
1 using System; 2 3 namespace Demo 4 { 5 class Program 6 { 7 // 定義一個名為Transformer的delegate類,參數類型int,返回類型int。 8 delegate int Transformer(int x); 9 // 定義一個靜態類Square,這裡用了Lambda表達式,同樣的,參數類型為int,返回類型也是int。 10 static int Square(int x) => x * x; 11 static void Main(string[] args) 12 { 13 Transformer t = Square; //把Square方法當作變數傳入委托變數t,這時創建了委托實例。 14 int result = t(3); // 調用委托方法。 15 Console.WriteLine(result); // 輸出結果:9 16 } 17 } 18 }
這裡的 Transformer t= Square; 簡寫了,等效於Transformer t= new Transformer(Square);
也就是當調用t(3)(委托實例)時,先調用了委托,委托再去調用目標方法。畫個圖應該很好理解。
優點:解耦。
應用:編寫插件式的方法
·方法是在運行時才賦值給委托變數的
1 using System; 2 3 namespace Demo 4 { 5 public delegate int Transformer(int x); // 定義委托類要註意傳入的類型和返回類型。 6 7 class Util 8 { 9 public static void Transform(int[] values, Transformer t) 10 { 11 for (int i = 0; i < values.Length; i++) 12 { 13 values[i] = t(values[i]); // 委托實例t 14 } 15 } 16 } 17 class Program 18 { 19 static int Square(int x) => x * x; 20 public static void Main(string[] args) 21 { 22 int[] values = { 1, 2, 3 }; 23 Util.Transform(values, Square); // 這裡調用Util的靜態方法Transform,並傳入參數。目標函數為Square 24 foreach (int i in values) 25 { 26 Console.WriteLine(i); 27 } 28 } 29 } 30 }
接下來看一下官方文檔給的例子:>Delegate
1 using System; 2 3 namespace Demo 4 { 5 public delegate String myMethodDelegate(int myInt); 6 7 public class mySampleClass 8 { 9 public String myStringMethod(int myInt) 10 { 11 if (myInt>0) 12 { 13 return ("positive"); 14 } 15 if (myInt<0) 16 { 17 return ("negative"); 18 } 19 return ("zero"); 20 } 21 public static String mySignMethod(int myInt) 22 { 23 if (myInt > 0) 24 { 25 return ("+"); 26 } 27 if (myInt < 0) 28 { 29 return ("-"); 30 } 31 return (""); 32 } 33 } 34 35 class Program 36 { 37 public static void Main(string[] args) 38 { 39 // Creates one delegate for each method. For the instance method, an 40 // instance (mySC) must be supplied. For the static method, use the 41 // class name. 42 mySampleClass mySC = new mySampleClass(); 43 myMethodDelegate myD1 = new myMethodDelegate(mySC.myStringMethod); 44 myMethodDelegate myD2 = new myMethodDelegate(mySampleClass.mySignMethod); 45 46 // Invokes the delegates. 47 Console.WriteLine("{0} is {1}; use the sign \"{2}\".", 5, myD1(5), myD2(5)); 48 Console.WriteLine("{0} is {1}; use the sign \"{2}\".", -3, myD1(-3), myD2(-3)); 49 Console.WriteLine("{0} is {1}; use the sign \"{2}\".", 0, myD1(0), myD2(0)); 50 } 51 } 52 }
運行結果:
畫個圖分析一下:
多播委托
委托按著我自己的理解就是把別人的方法放到我這兒,要用的時候去拿,但是不是在我這兒拿,而是到別人那去。em
多播委托就是可以利用操作符+,-來創建新的委托實例,並賦值給當前的委托變數。
using System; namespace Demo { public delegate int Transformer(int x); class Program { static int Square(int x) { var result = x * x; Console.WriteLine(result); return result; } static int Cube(int x) { var result = x * x * x; Console.WriteLine(result); return result; } public static void Main(string[] args) { Transformer t = null; t += Square; t += Cube; t(3); } } }
輸出結果:
Square在先,它就先執行。
假如都進行-=移除,最後會報空指針異常。
委托實例里至少要有一個靜態對象或者是實例對象,不然會拋出空指針異常。
A combining operation returns
null
when the result of the operation is a delegate that does not reference at least one method.
“委托是不可變的“
”Combine 和Remove實際上是創建新的委托實例,並把它賦給當前的委托變數”。
感覺自己理解有不對的地方,就先這樣吧。