【整理】C#2.0特性之匿名方法和迭代器

匿名方法的由来

    我们在这里用事件的定义来举例,没有匿名方法的时候

public partial class _Default : System.Web.UI.Page
{
    
protected void Page_Load(object sender, EventArgs e)
    {
        addButton.Click 
+=new EventHandler(addClick);
    }

    
protected void addClick(object sender, EventArgs e)
    {
        listBox.Items.Add(textBox.Text);
    }
}

    有了匿名方法以后

public partial class _Default : System.Web.UI.Page
{
    
protected void Page_Load(object sender, EventArgs e)
    {
        addButton.Click 
+= delegate {
            listBox.Items.Add(textBox.Text);
        };
    }
}
匿名方法的简介
    1.匿名方法允许我们以一种"内联"的方式编写方法代码,将代码直接与委托实例相关联,从而使得委托实例化的工作变得更加直观和方便
    2.匿名方法的几个相关问题
    -匿名方法的参数
        a.匿名方法可以在delegate关键字后跟一个参数列表(如果方法体没用到参数可以不指定),后面的代码块则可以访问这些参数。
        b.参数列表必须与使用匿名方法的委托的参数列表完全相同。
带参数的匿名方法
    -匿名方法的返回值
         a.如果委托类型的返回值为void,那么匿名方法就不能有返回值
         b.如果委托类型的返回值不为void,那么匿名方法的返回值就必须与委托类型的返回值类型一致。
         如下示例
         delegate void MyDelegate();
         MyDelegate g = delegate{
                 ......
                 return;//也可忽略不写
         }
         delegate int MyDelegate();
         MyDelegate g= delegate{
                 ......
                 return 100;
         }
    -外部变量
         a.一些局部变量和参数有可能被匿名方法所使用,它们被称为"匿名方法的外部变量"。
         b.外部变量的生存期会由于匿名方法"捕获效应"而延长,一直延长到委托实例不被引用为止。
        delegate double Function();
        
static void CustomFunction(double data)
        {
            Function f 
= delegate {
                data 
+= 0.2;
                
return data;
            };
        }
委托类型的推断
    1.C#2.0允许我们在进行委托实例化时,省略掉委托类型,而直接采用方法名,C#编译器会做合理的推断
    2.由于C#2.0有了委托类型推断功能,所以2.0针对1.0有如下改变
    在1.0中
    addButton.Click += new EventHanddler(AddClick);
    Apply(a,new Function(Math.Sin));
    在2.0中
    addButton.Click += AddClick;
    Apply(a,Math.Sin);
匿名方法机制
    1.C#2.0中的匿名方法仅仅是通过编译器的一层而外处理,来简化委托实例化的工作。它与以前版本不存在根本性的差别。
    2.深入了解匿名方法机制
    -静态方法中的匿名方法
     public delegate void D();
     static void F(){
         D d = delegate{
             Console.WriteLine("test");
         }
     }
     上面的代码将被编译器转换为如下代码
     static void F(){
         D d = new D(_Method1);
     }
     static void _Method1(){
         Console.WriteLine("test");
     }
    -实例化方法中的匿名方法
     class Test
     {
          int x;
          void F()
          {
               D d = delegate{Console.WriteLine(this.x);};
          }
     }
     上面的代码被编译器转换为
     void F()
     {
           D d = new D(_Method1);
     }
     void _Method1()
     {
          Console.WriteLine(this.x);
     }
    -匿名方法中的外部变量
     void F()
     {
           int y = 123;
           D d = delegate{Console.WriteLine(y)};
     }
     上面的代码被编译器转换为
     class _Temp
     {
          public int y;
          public void _Method1()
          {
                Console.WriteLine(y);
          }         
     }
     void F()
     {
           _Temp t = new _Temp();
           t.y=123;
           D d = new D(t._Method1);
     }
迭代器
     在没有迭代器之前,创建一个可用于foreach的集合,如下做法
2.0以前版本实现可foreach的集合
    C#2.0中使用迭代器定义可foreach的集合
用迭代器生成可foreach的集合
用迭代器生成可foreach的集合(含中断迭代)
测试实例
    注意上图中含有yield break;语句的测试结果为
    4,1
posted @ 2009-06-09 17:28  网络渔夫  阅读(339)  评论(0编辑  收藏  举报