扫一扫
分享文章到微信
扫一扫
关注官方公众号
至顶头条
对于我们到现在为止对匿名方法已了解的内容来说,这段代码不应该编译。因为我们没有使用如何实例数据成员,C#编译器应该在''Program''类中创建一个private静态方法来包装这个匿名方法。但是新的方法如何访问局部变量呢?这让我们相信该代码将不能被编译。但是令人惊讶的是,C#编译器成功编译了这个代码而没有任何错误或报警。而且,当你执行这个示例时,在控制台屏幕上输出打印出iTemp变量的正确的值。现在让我们进入匿名方法的高级话题。一个匿名方法有封装在其方法体中使用了的环境变量的值的能力。这个封装应用于匿名方法被定义的方法中的所有局部变量。当C#编译器在一个匿名方法的方法体中识别出用到一个局部变量,它就会做如下事情:
1. 创建一个新的private类作为匿名方法被定义的类的一个内部类。
2. 在新类(译注:即内部类)中创建一个公共数据成员,使用与用在匿名方法体中的局部变量相同的类型和名称。
3. 在包装匿名方法的新类中创建一个public实例方法。
4. 用新类中的声明替代局部变量的声明。创建该新类的一个实例代替局部变量的声明。
5. 用新类实例的数据成员替代在匿名方法体内部和外部使用的局部变量。
6. 用在新类中定义的实例方法的地址取代匿名方法的定义。
因此在编译时,上面的代码将被C#编译器翻译为如下代码:
public class Program { private class InnerClass { private void InstanceMethod() { Console.WriteLine(iTemp); } public int iTemp; } public delegate void MyDelegate(); public static void Main(string[] args) { InnerClass localObject = new InnerClass(); localObject.iTemp = 100; MyDelegate dlg = new MyDelegate(localObject.InstanceMethod); dlg(); } } |
正如上面的伪代码所示,C#编译器为''Program''类生成了一个private内部类。在匿名方法中使用的局部变量作为新的已创建的内部类的一个实例数据成员而捕获。并且匿名方法本身被包装在内部类的实例方法中。最后,该实例方法在Main方法中作为一个委托处理器而使用。这样,当委托被调用时,对于在被封装入匿名方法中的局部变量将会有一个正确的值。下面图中选定的部分显示了由C#编译器默默添加到''Program'' 类的新的private内部类。
如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。
现场直击|2021世界人工智能大会
直击5G创新地带,就在2021MWC上海
5G已至 转型当时——服务提供商如何把握转型的绝佳时机
寻找自己的Flag
华为开发者大会2020(Cloud)- 科技行者