匿名方法(Anonymous Method)
程序员文章站
2022-03-27 21:45:45
匿名方法是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 }
总结:
匿名方法简化了委托类型实例的声明和初始化。 出现匿名方法的地方,编译器将自动为该匿名方法所在类型的内部生成一个密封的嵌套类,用于封装委托字段和与该委托字段绑定的方法。 匿名方法不能被其它委托变量直接引用,即:不能被绑定到多个委托变量。