C#yield

王朝学院·作者佚名  2016-08-28
窄屏简体版  字體: 小  |  中  |  大  |  超大  

C#中的yield可以应用在一个可迭代的方法中,我们必须真正理解此关键词,才能将它正确的应用到实际生产中。为了说明yield会出现让我们迷惑的结果,下面先定义一个MyObject类:

1classMyObject2{3publicintValue{get;set;}4}

MyObject类用于存放一个值,下面定义一个IEnumerable<MyObject>的方法:

1IEnumerable<MyObject>GetYieldObjects()2{3for(inti =0; i <10; i++)4{5Console.WriteLine("GetObjects() i="+i.ToString());6yieldreturnnewMyObject() { Value =i };7}8}

方法中用yield return返回实例化的MyObject对象,为了便于记录GetYieldObjects()方法实际调用的过程,这里用Console.WriteLine来记录每次调用的过程。下面声明一个objects对象,然后进行第一次迭代,在第一次迭代过程中,对每个迭代项目的值进行+10处理,然后进行第2此迭代,看看是否会将处理后的值进行输出:

1//此时不调用GetObjects()的内部循环2varobjects =GetYieldObjects();3//每次迭代会调用GetObjects()对应i的内容4foreach(variteminobjects)5{6Console.WriteLine("1 foreach (var item in objects) item.Value="+ item.Value.ToString());//0..97item.Value +=10;8}9//每次迭代会调用GetObjects()对应i的内容10foreach(variteminobjects)11{12Console.WriteLine("2 foreach (var item in objects) item.Value="+ item.Value.ToString());//0..913Console.WriteLine(item.Value.ToString());//0..914}

在第2次迭代时,输出的还是0到9,并不是10到19.请看下面的迭代过程:

当第一次迭代时候,每次迭代会调用GetObject()方法中的yield return语句,而不是在var objects=GetObjects()进行实例化。当yield取到一个MyObject对象后立刻返回给迭代器,并将其值进行输出,然后继续调用GetObjects方法中的yield return语句,

因此每次循环时,实际上都是一个新的对象。如下图所示:

[flash=500,400]http://s1.knowsky.com/20160211/k3qdgs1d04500.png[/flash]

[flash=500,400]http://s1.knowsky.com/20160211/ytva1gvaw1n00.png[/flash]

当然如果将上面的代码稍作修改,用objects=GetYieldObjects().ToArray()的话,那么第二次输出的就是10到19:

1objects =GetYieldObjects().ToArray();2foreach(variteminobjects)3{4item.Value +=10;5}67foreach(variteminobjects)8{9Console.WriteLine(item.Value.ToString());//10..1910}

 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
 
© 2005- 王朝網路 版權所有 導航