讨论交流:http://x8.maicoo.com/team/8661.html
1.匿名方法
在C#1.0中典型的给一个委托添加一个方法调用代码如下:
private void ctrl_Click (object sender,EventArgs e)
txt.Click += new MyDelegate(ctrl_Click);
private ctrl_Click(object sender,EventArgs e)
{
Message.Show(...);
}
哪怕只有这么一条语句也必须得按上面的形式给事件的调用列表添加方法,还得创建一个委托的实例
在C#2.0中引入了匿名方法,大大简化了上述操作
可以改写为
txt.Click += delegate {Message.Show();}
或是这样:
txt.Click += ctrl_Click也是允许的.
C#编译器对上述的定义自动隐式转化,只要匿名方法和委托的定义兼容.
符合下列条件可以兼容
1.参数兼容
如果匿名方法没有参数,委托中没有out参数
如果匿名方法和委托的参数在数量,类型,顺序上都一致
2.返回值兼容
如果委托没有返回值,匿名方法中也没有返回值或匿名方法中只有return不带返回值
如果两者都有返回值,并且匿名方法的返回值可以隐式转化为委托定义的类型
符合参数和返回值兼容的就可以使用匿名方法
匿名方法的捕获变量(capture variable)
如果局部变量或参数的作用范围内包含匿名方法声明,则该局部变量或参数称为该匿名方法的外部变量或捕获变量
public void method1(bool enabled)
{
string b;
this.txt.Click += delegate
{
this.txt.enabled = enabled;
this.txt.Text = b;
}
}
对于这个匿名方法来说:参数enabled和变量a是它的捕获变量或叫外部变量.
捕获变量的生命周期直到此匿名方法的资源被回收而结束
2.泛型
关于泛型的定义及如何使用网上资料已经很多,请参见MSDN
3.迭代器(iterators)
在C#1.0中若想要使得类型成为可枚举的类型(即象使用数组一样用foreach一样枚举数组中的成员),那么这个类中必须实现IEnumerable接口的GetEnumerator()方法返回IEnumerator
public IEnumerator GetEnumerator()
{..}
一般来说实现GetEnumerator是不容易的.
在C#2.0中引入了的新的语法扩充:迭代器,它能够很好的简单方便的让我们实现GetEnumerator()方法
如:
public IEnumerator GetEnumerator()
{
for ( int i = 0; i < 10; i ++)
{
yield return i;
}
}
假设类Class1中实现了上述的GetEnumertor方法
那我们就可以用foreach对类Class1进行枚举
Class1 c = new Class1;
foreach ( int i in c)
{
Console.WriteLine(i);
}
yield return产生迭代的下一个值,yield break说明迭代完成,用迭代器实现就是这么简单.
定义和使用命名迭代器
class Class1
{
public IEnumerator GetEnumerator()
{
for (int i = 0; i < 10; i++)
{
yield return i;
}
}
// 定义一个命名的迭代器,并可以提供参数
public IEnumerable MaxToMin(int min, int max)
{
for (int i = max; i >= min; i--)
{
yield return i;
}
}
// 定义一个迭代器类型的属性,
public IEnumerable MinToMax
{
// this表示该类实例,因为该类实现了GetEnumerator(),它是可枚举的
get { yield return this; }
}
【责任编辑: lanier】