zoukankan      html  css  js  c++  java
  • 匿名方法、迭代器

    匿名方法的由来:
    A。没有匿名方法的时候
    (C# 1.0)
     addButton.Click += new EventHandler(AddClick);
     void AddClick(object sender,EventArgs e)
     {
      listBox.Items.Add(textBox.Text);
     }
    B。有了匿名方法之后(C# 2.0)
     addButton.Click += delegate
     {
      listBox.Items.Add(textBox.Text);
     }; //最后要加分号
    语法省略了方法名,因为一般情况下,在别的地方都不需要用到AddClick(包括方法名和原型)。

    匿名方法简介:
    匿名方法允许我们以一种“内联”的方式来编写方法代码,将代码直接与委托实例相关联,从而使得委托实例化的工作更加直观和方便。

    匿名方法的几个相关问题:
    A。匿名方法的参数:
     匿名方法可以在delegate关键字后跟一个参数列表(可以不指定),后面的代码块则可以访问这些参数:
     addButton.Click += delegate(object sender,EventArgs e){ MessageBox.Show(((Button)sender).Text); };
     注意“不指定参数列表”与“参数列表为空”的区别。
     addButton.Click += delegate { ... } //正确
     addButton.Click += delegate() { ... } //错误
    B。匿名方法的返回值:
     如果委托类型的返回值类型为void,匿名方法里便不能返回任何值;
     如果委托类型的返回值类型不为void,匿名方法里返回的值必须和委托类型的返回值兼容
     (1) delegate void MyDelegate();
       MyDelegate d = delegate{ ... return; };
     (2) delegate int MyDelegate();
       MyDelegate d = delegate{ ... return 1; };
    C。匿名方法的外部变量:
     一些局部变量和参数有可能被匿名方法所使用,它们被称为“匿名方法的外部变量”。
     外部变量的生存期会由于“匿名方法的捕获效益”而延长,一直延长到委托实例不被引用为止。
     static void Foo(double factor)
     {
      Function f = delegate(int x)
      {
       factor += 0.2; //factor为外部变量,在匿名方法内部访问(外部变量被捕获)
       return x*factor;
      };
      Invoke(f); //factor的生存期被延长
     }
     void Invoke(Fuction f)
     {
      for(int i=0;i<5;i++) f(i);
     }

    委托类型的推断:
    C# 2.0允许我们在进行委托实例化时,省略掉委托类,而直接采用方法名,C#编译器会做合理的推断。
    C# 1.0中的做法:
     addButton.Click += new EventHandler(AddClick);
     Apply(a,new Function(Math.Sin));
    C# 2.0中的做法:
     addButton.Click += AddClick;
     Apply(a,Math.Sin);

    匿名方法机制:
    C# 2.0中的匿名方法仅仅是通过编译器的一层额外处理,来简化委托实例化的工作。它与C#1.0的代码不存在根本性的差别。

    通过ILDsam.exe反汇编工具,可以获得对匿名方法的深入了解:
    A。静态方法中的匿名方法
     public delegate void D();
     static void F()
     {
      D d = delegate { Console.WriteLine("test"); };
     }
     上面的代码被编译器转换为:
     static void F()
     {
      D d = new D(MethodName); //MethodName代表编译器产生的名字
     }
     static void MethodName()
     {
      Console.WriteLine("test");
     }
    B。实例方法中的匿名方法
     class Test
     {
      int x;
      void F()
      {
       D d = delegate { Console.WriteLine(this.x); };
      }
     }
     上面的代码被编译器转换为:
     void F()
     {
      D d = new D(MethodName);
     }
     void MethodName()
     {
      Console.WriteLine(this.x);
     }
    C。匿名方法中的外部变量
     void F()
     {
      int y = 123;
      D d = delegate { Console.WriteLine(y); };
     }
     上面的代码被编译器转换为:
     class ClassName
     {
      public int y;
      public void MethodName()
      {
       Console.WriteLine(y);
      }
     }
     void F()
     {
      ClassName t = new ClassName();
      t.y = 123;
      D d = new D(t.MethodName);
     }

    迭代器(省略)

  • 相关阅读:
    BadUSB 利用
    java 将函数作为参数传递
    odoo12 修行提升篇之 常用的高阶函数 (二)
    odoo12 修行提升篇之 异步定时任务 (一)
    odoo12 修行基础篇之 利用kanban做分析 点击跳转分析模型列表 (九)
    odoo12 修行基础篇之 kanban (八)
    odoo12 修行基础篇之 记录批处理 (七)
    odoo12 修行基础篇之 列表的筛选和分组 (六)
    odoo12 修行基础篇之 添加记录编码 (五)
    odoo12 修行基础篇之 添加工作流和操作记录 (四)
  • 原文地址:https://www.cnblogs.com/vipcjob/p/1558223.html
Copyright © 2011-2022 走看看