匿名方法、迭代器

匿名方法的由来:
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);
 }

迭代器(省略)

posted @ 2009-09-29 15:18  DaCHun  阅读(196)  评论(0编辑  收藏  举报