扫一扫
分享文章到微信
扫一扫
关注官方公众号
至顶头条
被用在匿名方法中的局部变量有着超出用到它们的外部常规方法的生命周期。这个技术,在其它语言中,就是大家都知道的closures。除去匿名方法提供的简单语法,closures是匿名方法提供给开发者的一个功能强大的技术。该技术允许委托处理器代码(匿名方法)访问在常规方法内部被定义的局部变量。这就允许out-of-band数据,除了委托参数之外还有数据将被传递到委托,以供在其方法执行时使用。没有这个技术,每个委托和其相应的处理器方法就不得不声明表示局部上下文数据的参数,随着时间的过去这(译注:指不断声明表示局部上下文数据的参数)将变得难于管理。 匿名方法的作用域和局部变量用法
我们讨论了在方法的主作用域(the main scope)中的匿名方法的实现。当一个匿名方法在一个嵌套作用域中被定义时,并且匿名方法中用到独立作用域级的局部变量,C#为每个作用域创建一个private内部类。比如,假设scope 1有局部变量iTemp,而scope 2,是scope 1的嵌套作用域,有一个局部变量jTemp。让在使用来自scope 1 和 scope 2局部变量iTemp 和 jTemp的 scope 2中,我们定义一个匿名方法。下面的代码显示了上面描述的示例:
public class Program { public delegate void MyDelegate(); public static void Main(string[] args) { MyDelegate dlg = null; int iTemp = 100; if (iTemp > 50) { int jTemp = 200; dlg = delegate { Console.WriteLine("iTemp: {0}, jTemp: {1}",iTemp,jTemp); }; } dlg(); } } |
当上面的代码被编译时,C#编译器在''Program''类中创建两个内部类。一个内部类包装局部变量iTemp作为一个public数据成员。第二个内部类包装在嵌套作用域中的局部变量,jTemp,作为一个public数据成员,同时在相同的嵌套作用域中包装匿名方法作为public实例方法。C#编译器为上面的代码生成下面的伪代码:
public class Program { //包装来自外部作用域的局部变量''iTemp''的类 private class InnerClassScope1 { public int iTemp; } //包装来自内部作用域和匿名方法的局部变量的类 private class InnerClassScope2 { public void InstanceMethod() { Console.WriteLine("iTemp: {0}, jTemp: {1}", localObjectScope1.iTemp, jTemp); } public InnerClassScope1 localObjectScope1; public int jTemp; } public delegate void MyDelegate(); public static void Main(string[] args) { MyDelegate dlg = null; InnerClassScope1 localObject1 = new InnerClassScope1(); localObject1.iTemp = 100; if (localObject1.iTemp > 50) { InnerClassScope2 localObject2 = new InnerClassScope2(); localObject2.localObjectScope1 = localObject1; localObject2.jTemp = 200; dlg = new MyDelegate(localObject2.InstanceMethod); } dlg(); } } |
正如上面的代码所示,包装匿名方法的内部类将拥有所有代表外部作用域局部变量的对象,这些变量被用在匿名方法中,像public数据成员。下图显示了C#默默创建的内部类的ILDASM视图:
如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。
现场直击|2021世界人工智能大会
直击5G创新地带,就在2021MWC上海
5G已至 转型当时——服务提供商如何把握转型的绝佳时机
寻找自己的Flag
华为开发者大会2020(Cloud)- 科技行者