欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

匿名方法(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 }

  总结:

匿名方法简化了委托类型实例的声明和初始化。 出现匿名方法的地方,编译器将自动为该匿名方法所在类型的内部生成一个密封的嵌套类,用于封装委托字段和与该委托字段绑定的方法。 匿名方法不能被其它委托变量直接引用,即:不能被绑定到多个委托变量。