【整理】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. 参数列表必须与 使用匿名方法的委托的参数列表完全相同。
ContractedBlock.gif ExpandedBlockStart.gif 带参数的匿名方法
    public partial class _Default : System.Web.UI.Page
    {
        
protected void Page_Load(object sender, EventArgs e)
        {
            
//delegate void EventHanddler(object sender,EventArgs e);
            
//注意委托与匿名方法的参数列表
            addButton.Click += delegate(object sender1,EventArgs e1) {
                listBox.Items.Add(textBox.Text);
            };


            
//如果方法体中没有用到参数列表的参数的话,一般省略不写,如下:
            addButton.Click += delegate
            {
                listBox.Items.Add(textBox.Text);
            };

            
//下面的写法是错误的,除非委托本身没有参数列表
            addButton.Click += delegate()
            {
                listBox.Items.Add(textBox.Text);
            };
        }
    }
    -匿名方法的返回值
         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的集合,如下做法
ContractedBlock.gif ExpandedBlockStart.gif 2.0以前版本实现可foreach的集合
    public class MyCollections : IEnumerable
    {
        
public MyEnumerator GetEnumerator()
        {
            
return new MyEnumerator();
        }

        
public class MyEnumerator : IEnumerator
        {
            
public void Reset()
            {
                
//dot.gifdot.gif
            }

            
public bool MoveNext()
            {
                
//dot.gifdot.gif
            }

            
public int Current
            {
                
get
                {
                    
//dot.gifdot.gif
                }
            }

            
object IEnumerator.Current
            {
                
get
                {
                    
//dot.gifdot.gif
                }
            }
        }
    }
    C#2.0中使用迭代器定义可foreach的集合
ContractedBlock.gif ExpandedBlockStart.gif 用迭代器生成可foreach的集合
    public class Stack : IEnumerable
    {
        
int[] item = { 4,1,9,7,6,8,10};
        
public IEnumerator GetEnumerator()
        {
            
for (int i = 0; i < item.Length; i++)
            {
                
//用yield return语句产生枚举元素
                yield return item[i];

            }
        }
    }
ContractedBlock.gif ExpandedBlockStart.gif 用迭代器生成可foreach的集合(含中断迭代)
    public class Stack : IEnumerable
    {
        
int[] item = { 4,1,9,7,6,8,10};
        
public IEnumerator GetEnumerator()
        {
            
for (int i = 0; i < item.Length; i++)
            {
                
//用yield break语句中断迭代
                if (item[i] > 8)
                {
                    
yield break;
                }

                
yield return item[i];

            }
        }
    }
ContractedBlock.gif ExpandedBlockStart.gif 测试实例
    public partial class Demo1 : System.Web.UI.Page
    {
        
        
protected void Page_Load(object sender, EventArgs e)
        {
            Stack stack 
= new Stack();
            
foreach (int i in stack)
            {
                Response.Write(i);
            }
        }
    }
    注意上图中含有yield break;语句的测试结果为
    4,1

转载于:https://www.cnblogs.com/jewleo/archive/2009/06/09/06091630_1.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值