分享
 
 
 

C# 2.0 匿名方法、迭代器

王朝c#·作者佚名  2006-01-10
窄屏简体版  字體: |||超大  

匿名方法的由来

没有匿名方法的时候(C# 1.0)

addButton.Click += new EventHandler(AddClick);

void AddClick(object sender,EventArgs e)

{

listBox.Items.Add(textBox.Text);

}

有了匿名方法之后(C# 2.0)

addButton.Click += delegate

{

listBox.Items.Add(textBox.Text);

}

匿名方法简介

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

匿名方法的几个相关问题

- 参数列表

- 返回值

- 外部变量

匿名方法的参数

匿名方法可以在delegate关键字后跟一个参数列表(可以不指定),后面的代码块则可以访问这写参数:

addButton.Click += delegate(object sender,EventArgs e)

{

MessageBox.Show((Button)sender).Text);

}

注意:不指定参数列表与参数列表为空的区别

addButton.Click += delegate{...} // 正确

addButton.Click += delegate(0{...} // 错误

匿名方法的返回值

如果委托类型的返回值类型为void,匿名方法的便不能返回任何值;

如果委托类型的返回值类型为void,匿名方法里的返回的值必须和委托类型的返回值兼容:

delegate void MyDelegate();

MyDelegate d = delegate

{

...

return;

}

delegate int MyDelegate();

MyDelegate d = delegate

{

...

return 100;

}

匿名方法的外部变量

一些局部变量和参数有可能被匿名方法所使用,它们被称为“匿名方法的外部变量”。

外部变量的生存周期会由于“匿名方法的捕获效益”而延长 - 一直延长到委托实例不被引用为止。

static void Foo(double factor)

{

Function f = delegate(int x)

{

facator += 0.2; // factor为外部变量

return x*factor;

};

Invoke(f); // factor的生存周期被延长

}

委托类型的推断

C# 2.0允许我们在进行委托实例化时,省略掉委托类型,而直接采用方法名,C#编译器会做合理的推断。

C# 1.1中的做法:

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的代码不存在根本性的差别。

通过ILDasm.exe反汇编工作,我们可以获得对匿名方法的深入了解:

- 静态方法中的匿名方法

- 实例方法中的匿名方法

- 匿名方法中的外部变量

静态方法中的匿名方法

public delegate void D();

static void F()

{

D d = delegate{Console.WriteLine("text");};

}

上面的代码被编译器转换为:

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);

}

C# 1.0中的foreach

没有迭代器的时候,创建一个可用于foreach的集合(C# 1.0):

public class MyCollection : IEnumerable

{

public MyEnumerator GetEnumerator()

{

return new MyEnumerator(this);

}

public class MyEnumerator : IEnumerator

{

public void Reset(){...}

public bool MoveNext(){...}

public int Current{ get{...} }

object IEnumerator.Current{ get{...} }

}

}

对集合使用foreach语句:

foreach(int i in col){...}

相单于:

IEnumerator etor = ((IEnumerable)col).GetEnumerator();

try

{

while(etor.MoveNext())

{

ElementType clem (ElementType)etor.Current;

...;

}

}

finally{(IDisposable)enumerator).Dispose();}

C# 2.0 中的迭代器

使用迭代器创建于foreach的集合(C# 2.0):

public class Stack<T>:IEnumerable<T>

{

T[] items;

int count;

public void Push(T data){...}

public T Pop(){...}

public IEnumerator<T> GetEnumerator()

{

for(int i=count-1;i>=0;--i)

{

yield return items[i];

}

}

}

使用foreach语句:

Stack<int> stack = new Stack<int>();

foreach(int i in statck){...}

使用迭代器创建倒序遍历:

public IEnumerable<T> BottomToTop

{

get

{

for(int i=0;i<count;i++)

{

yield return items[i];

}

}

}

迭代器中的yield语句

使用yield return 产生枚举元素:

for(int i=count-1;i>=0;--i)

{

yield return items[i];

}

使用yield break中断迭代:

for(int i=count-1;i>=0;--i)

{

yield return items[i];

if(items[i]>10)

yield break;

}

迭代器的机制

C# 2.0中的迭代器同样是通过编译器的一层额外处理,来简化创建可用于foreach的枚举集合的工作。

通过ILDasm.exe反汇编工作,我们可以获得对迭代器的深入理解:

- 迭代器中的GetEnumerator()方法

- 迭代器中的嵌套类

- 迭代器中的yield语句

总结

匿名方法允许我们以一种“内联”的方式将代码直接与委托实例相关联,从而使得委托实例化的工作更加直观和方便。迭代器允许我们更加方便地编写应用于foreach语句的枚举集合。

对于类似于C#这样的高级语言,掌握好它一个很重要的地方就是掌握编译器在背后为我们做了哪些工作。C# 2.0中的匿名方法和迭代器都是用国在编译层面进行一些额外的处理,进而来简化程序员的工作。

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有