匿名方法是C# 2.0引入的新特性,用來為委托實例綁定方法。 應用場景:需要為委托實例綁定一個專用方法的時候,這就意味著匿名方法不可以被其它委托實例顯式引用。 聲明語法:委托類型 變數名 = delegate ( 參數列表 ) { 代碼塊 }; 示例代碼: 示例代碼解讀: 代碼運行結果: >>Hel ...
匿名方法是C# 2.0引入的新特性,用來為委托實例綁定方法。
應用場景:需要為委托實例綁定一個專用方法的時候,這就意味著匿名方法不可以被其它委托實例顯式引用。
聲明語法:委托類型 變數名 = delegate ( 參數列表 ) { 代碼塊 };
示例代碼:
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Threading.Tasks; 6 7 namespace Demo 8 { 9 class Program 10 { 11 static void Main(string[] args) 12 { 13 Action myAction = new Action(Print); 14 myAction(); 15 16 Func<int, int, int> myFunc = delegate (int x, int y) { return x + y; }; 17 18 int sum, left, right; 19 left = 12; 20 right = 56; 21 sum = myFunc(left, right); 22 Console.WriteLine("SUM = {0}", sum); 23 24 Console.ReadKey(); 25 } 26 static void Print() 27 { 28 Console.WriteLine("Hello C#!"); 29 } 30 } 31 }
示例代碼解讀:
- 第13行:聲明Action類型委托變數myAction,並用靜態方法Print初始化該變數。
- 第14行:通過上述委托變數myAction調用為其綁定的方法。
- 第16行:聲明Func<int,int,int>類型委托變數myFunc,併為其綁定匿名方法。
- 第18-20行:聲明和初始化一些臨時變數。
- 第21行:通過委托變數myFunc調用為其綁定的匿名方法,將返回值賦給sum變數。
代碼運行結果:
>>Hello C#!
>>SUM = 68
編譯器視角的等價代碼:
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Threading.Tasks; 6 7 namespace Demo 8 { 9 internal class Program 10 { 11 public Program() { } 12 13 private static void Print() 14 { 15 Console.WriteLine("Hello C#!"); 16 } 17 18 private static void Main(string[] args) 19 { 20 Action myAction = new Action(Print); 21 myAction(); 22 23 DemoClass Dc = new DemoClass(); 24 Func<int, int, int> myFunc = DemoClass.demoFunc; 25 26 int sum, left, right; 27 left = 12; 28 right = 56; 29 sum = myFunc(left, right); 30 Console.WriteLine("SUM = {0}", sum); 31 32 Console.ReadKey(); 33 } 34 35 private sealed class DemoClass 36 { 37 public static readonly DemoClass demoAction; 38 public static Func<int, int, int> demoFunc; 39 40 static DemoClass() 41 { 42 demoAction = new DemoClass(); 43 demoFunc = demoAction.GetSum; 44 } 45 46 public DemoClass() { } 47 48 internal int GetSum(int x, int y) => (x + y); 49 } 50 } 51 }
等價代碼解讀:
- 第325行:定義嵌套類DemoClass。用於封裝Func<int, int, int>類型靜態委托欄位demoFunc,有該欄位調用為其綁定的方法。
- 第40-44行:實例化DemoClass類型的靜態只讀欄位demoAction、為委托變數demoFunc綁定GetSum方法。
- 第48行:為demoFunc委托欄位綁定的方法。
- 第23行:聲明並初始化嵌套類DemoClass的一個實例。
- 第24行:聲明Func<int, int, int>類型委托變數myFunc並將嵌套類DemoClass的demoFunc靜態欄位賦給它。
- 其它代碼與之前的含義相同,運行該代碼的輸出結果也一致。
編譯器做了什麼?
編譯器生成代碼之Program類:
1 internal class Program 2 { 3 // Methods 4 public Program(); 5 private static void Main(string[] args); 6 private static void Print(); 7 8 // Nested Types 9 [Serializable, CompilerGenerated] 10 private sealed class <>c 11 { 12 // Fields 13 public static readonly Program.<>c <>9; 14 public static Func<int, int, int> <>9__0_0; 15 16 // Methods 17 static <>c(); 18 public <>c(); 19 internal int <Main>b__0_0(int x, int y); 20 } 21 }
編譯器生成代碼之嵌套類:
1 [Serializable, CompilerGenerated] 2 private sealed class <>c 3 { 4 // Fields 5 public static readonly Program.<>c <>9; 6 public static Func<int, int, int> <>9__0_0; 7 8 // Methods 9 static <>c() 10 { 11 <>9 = new Program.<>c(); 12 } 13 14 public <>c() 15 { 16 } 17 18 internal int <Main>b__0_0(int x, int y) => (x + y); 19 }
總結:
- 匿名方法簡化了委托類型實例的聲明和初始化。
- 出現匿名方法的地方,編譯器將自動為該匿名方法所在類型的內部生成一個密封的嵌套類,用於封裝委托欄位和與該委托欄位綁定的方法。
- 匿名方法不能被其它委托變數直接引用,即:不能被綁定到多個委托變數。