科技行者

行者学院 转型私董会 科技行者专题报道 网红大战科技行者

知识库

知识库 安全导航

至顶网软件频道Visual C# 2.0匿名方法揭密 4

Visual C# 2.0匿名方法揭密 4

  • 扫一扫
    分享文章到微信

  • 扫一扫
    关注官方公众号
    至顶头条

     对于我们到现在为止对匿名方法已了解的内容来说,这段代码不应该编译

作者:中国IT实验室 来源:中国IT实验室 2007年9月10日

关键字: C# 编程

  • 评论
  • 分享微博
  • 分享邮件
  

  对于我们到现在为止对匿名方法已了解的内容来说,这段代码不应该编译。因为我们没有使用如何实例数据成员,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领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。

    重磅专题
    往期文章
    最新文章