请问,这是个什么怪异现象

时间:2021-05-18 23:45:40

namespace 控制台
{
    class Program
    {
        static void Main()
        {
            Person p = new Person();
            p.GetResult();
            p.GG();
            Console.ReadKey();
        }
    }
    class Person 
    {
        List<int> list = new List<int>() { 0,1,2};
        public IEnumerable<int> GetResult()
        {
            Console.WriteLine("李四");
            foreach (int i in list)
            {
                yield return i;
            }
        }
        public void GG()
        {
            Console.WriteLine("张三");
        }
    }
}

21 个解决方案

#1


p.GetResult();
->
p.GetResult().ToList();

#2


引用 1 楼 caozhy 的回复:
p.GetResult();
->
p.GetResult().ToList();
转换暂且不说,不管怎么说,输出总应该执行吧

#3


引用 2 楼 u012915261 的回复:
Quote: 引用 1 楼 caozhy 的回复:

p.GetResult();
->
p.GetResult().ToList();
转换暂且不说,不管怎么说,输出总应该执行吧

不会执行,除非执行第一次迭代

#4


该回复于2013-11-21 22:45:33被版主删除

#5


也就是调用一次MoveNext

#6


该回复于2013-11-22 08:42:16被管理员删除

#7


引用 3 楼 caozhy 的回复:
Quote: 引用 2 楼 u012915261 的回复:

Quote: 引用 1 楼 caozhy 的回复:

p.GetResult();
->
p.GetResult().ToList();
转换暂且不说,不管怎么说,输出总应该执行吧

不会执行,除非执行第一次迭代

请问,这是个什么怪异现象
yield的特性

#8


再说仔细一点吧
p.GetResult().GetEnumerator().MoveNext();

#9


看编译后的代码

#10


这个是典型的Deferred execution
"Deferred execution is supported directly in the C# language by the yield keyword "

来自msdn, lz可以读一下:
Deferred Execution and Lazy Evaluation in LINQ to XML
http://msdn.microsoft.com/en-us/library/vstudio/bb943859(v=vs.100).aspx

#11


迭代器内部是延迟执行的,其实就是你每次访问迭代器中的元素的时候,才会执行到内部的代码

#12


引用 11 楼 sj490790083 的回复:
迭代器内部是延迟执行的,其实就是你每次访问迭代器中的元素的时候,才会执行到内部的代码

楼上回答的,都不太详细,我没懂起。
执行p.GetResult(),方法都不执行吗?

#13


引用 12 楼 u012915261 的回复:
Quote: 引用 11 楼 sj490790083 的回复:

迭代器内部是延迟执行的,其实就是你每次访问迭代器中的元素的时候,才会执行到内部的代码

楼上回答的,都不太详细,我没懂起。
执行p.GetResult(),方法都不执行吗?
是的,不执行,如果你在main方法中这么写,
var result=p.GetResult();
foreach(var element in result)
{
   操作;
}

这时候访问了迭代器的结果集,就会执行到。你可以再GetResult里面打个断点看看,看是不是foreach的时候才执行,你可以把result这个变量看成一个"委托",调用的时候才执行。至于为什么延迟执行,我的理解应该是和Linq的延迟查询特性一样,越晚被执行,对业务逻辑的理解就越清晰,LINQ查询对数据的请求压力越小。编译器对LINQ查询优化可作的事情越多。

#14


我和楼主一样也想知道,楼上的人都说的不清不楚的

#15


http://www.cnblogs.com/kingcat/archive/2012/07/11/2585943.html
这个主要是对yield关键字的理解,参考下吧~

#16


使用一个 yield return 语句返回每个元素一个节点。
使用 foreach 语句或 LINQ 查询,则使用迭代器方法。 foreach 循环的每次迭代调用迭代器方法。 当 yield return 语句在迭代器方法时为止,expression 返回,并且,代码的当前位置保留。 当下次调用迭代器函数时执行从该位置重新启动。
可以使用 yield break 语句结束迭代。
http://msdn.microsoft.com/zh-cn/library/9k7k7cf0.aspx

#17


请问,这是个什么怪异现象
涨姿势了!

#18


引用 12 楼 u012915261 的回复:
Quote: 引用 11 楼 sj490790083 的回复:

迭代器内部是延迟执行的,其实就是你每次访问迭代器中的元素的时候,才会执行到内部的代码

楼上回答的,都不太详细,我没懂起。
执行p.GetResult(),方法都不执行吗?

执行p.GetResult()返回一个迭代器,但是并不执行其中的代码。

#19


引用 18 楼 caozhy 的回复:
Quote: 引用 12 楼 u012915261 的回复:

Quote: 引用 11 楼 sj490790083 的回复:

迭代器内部是延迟执行的,其实就是你每次访问迭代器中的元素的时候,才会执行到内部的代码

楼上回答的,都不太详细,我没懂起。
执行p.GetResult(),方法都不执行吗?

执行p.GetResult()返回一个迭代器,但是并不执行其中的代码。
MSDN不是说包含yield return的整个方法就叫做迭代器吗?怎么你又说执行p.GetResult()返回一个迭代器呢?

#20


引用 19 楼 u012915261 的回复:
Quote: 引用 18 楼 caozhy 的回复:

Quote: 引用 12 楼 u012915261 的回复:

Quote: 引用 11 楼 sj490790083 的回复:

迭代器内部是延迟执行的,其实就是你每次访问迭代器中的元素的时候,才会执行到内部的代码

楼上回答的,都不太详细,我没懂起。
执行p.GetResult(),方法都不执行吗?

执行p.GetResult()返回一个迭代器,但是并不执行其中的代码。
MSDN不是说包含yield return的整个方法就叫做迭代器吗?怎么你又说执行p.GetResult()返回一个迭代器呢?


这个实现比较复杂,C#编译器会将你这个方法拆开,变成3个方法,并且在内部维护一个状态机。p.GetResult()相当于初始化迭代器。

#21


var itl = p.GetResult().GetEnumerator();
itl.MoveNext();
itl.MoveNext();
itl.MoveNext();
itl.MoveNext();

        public IEnumerable<int> GetResult()
        {
            Console.WriteLine("0");
            yield return 1;
            Console.WriteLine("1");
            yield return 2;
            Console.WriteLine("2");
            yield return 3;
            Console.WriteLine("3");
            yield return 4;
            Console.WriteLine("4");
            yield break;
        }

你调试下这段代码,自己再想想

#1


p.GetResult();
->
p.GetResult().ToList();

#2


引用 1 楼 caozhy 的回复:
p.GetResult();
->
p.GetResult().ToList();
转换暂且不说,不管怎么说,输出总应该执行吧

#3


引用 2 楼 u012915261 的回复:
Quote: 引用 1 楼 caozhy 的回复:

p.GetResult();
->
p.GetResult().ToList();
转换暂且不说,不管怎么说,输出总应该执行吧

不会执行,除非执行第一次迭代

#4


该回复于2013-11-21 22:45:33被版主删除

#5


也就是调用一次MoveNext

#6


该回复于2013-11-22 08:42:16被管理员删除

#7


引用 3 楼 caozhy 的回复:
Quote: 引用 2 楼 u012915261 的回复:

Quote: 引用 1 楼 caozhy 的回复:

p.GetResult();
->
p.GetResult().ToList();
转换暂且不说,不管怎么说,输出总应该执行吧

不会执行,除非执行第一次迭代

请问,这是个什么怪异现象
yield的特性

#8


再说仔细一点吧
p.GetResult().GetEnumerator().MoveNext();

#9


看编译后的代码

#10


这个是典型的Deferred execution
"Deferred execution is supported directly in the C# language by the yield keyword "

来自msdn, lz可以读一下:
Deferred Execution and Lazy Evaluation in LINQ to XML
http://msdn.microsoft.com/en-us/library/vstudio/bb943859(v=vs.100).aspx

#11


迭代器内部是延迟执行的,其实就是你每次访问迭代器中的元素的时候,才会执行到内部的代码

#12


引用 11 楼 sj490790083 的回复:
迭代器内部是延迟执行的,其实就是你每次访问迭代器中的元素的时候,才会执行到内部的代码

楼上回答的,都不太详细,我没懂起。
执行p.GetResult(),方法都不执行吗?

#13


引用 12 楼 u012915261 的回复:
Quote: 引用 11 楼 sj490790083 的回复:

迭代器内部是延迟执行的,其实就是你每次访问迭代器中的元素的时候,才会执行到内部的代码

楼上回答的,都不太详细,我没懂起。
执行p.GetResult(),方法都不执行吗?
是的,不执行,如果你在main方法中这么写,
var result=p.GetResult();
foreach(var element in result)
{
   操作;
}

这时候访问了迭代器的结果集,就会执行到。你可以再GetResult里面打个断点看看,看是不是foreach的时候才执行,你可以把result这个变量看成一个"委托",调用的时候才执行。至于为什么延迟执行,我的理解应该是和Linq的延迟查询特性一样,越晚被执行,对业务逻辑的理解就越清晰,LINQ查询对数据的请求压力越小。编译器对LINQ查询优化可作的事情越多。

#14


我和楼主一样也想知道,楼上的人都说的不清不楚的

#15


http://www.cnblogs.com/kingcat/archive/2012/07/11/2585943.html
这个主要是对yield关键字的理解,参考下吧~

#16


使用一个 yield return 语句返回每个元素一个节点。
使用 foreach 语句或 LINQ 查询,则使用迭代器方法。 foreach 循环的每次迭代调用迭代器方法。 当 yield return 语句在迭代器方法时为止,expression 返回,并且,代码的当前位置保留。 当下次调用迭代器函数时执行从该位置重新启动。
可以使用 yield break 语句结束迭代。
http://msdn.microsoft.com/zh-cn/library/9k7k7cf0.aspx

#17


请问,这是个什么怪异现象
涨姿势了!

#18


引用 12 楼 u012915261 的回复:
Quote: 引用 11 楼 sj490790083 的回复:

迭代器内部是延迟执行的,其实就是你每次访问迭代器中的元素的时候,才会执行到内部的代码

楼上回答的,都不太详细,我没懂起。
执行p.GetResult(),方法都不执行吗?

执行p.GetResult()返回一个迭代器,但是并不执行其中的代码。

#19


引用 18 楼 caozhy 的回复:
Quote: 引用 12 楼 u012915261 的回复:

Quote: 引用 11 楼 sj490790083 的回复:

迭代器内部是延迟执行的,其实就是你每次访问迭代器中的元素的时候,才会执行到内部的代码

楼上回答的,都不太详细,我没懂起。
执行p.GetResult(),方法都不执行吗?

执行p.GetResult()返回一个迭代器,但是并不执行其中的代码。
MSDN不是说包含yield return的整个方法就叫做迭代器吗?怎么你又说执行p.GetResult()返回一个迭代器呢?

#20


引用 19 楼 u012915261 的回复:
Quote: 引用 18 楼 caozhy 的回复:

Quote: 引用 12 楼 u012915261 的回复:

Quote: 引用 11 楼 sj490790083 的回复:

迭代器内部是延迟执行的,其实就是你每次访问迭代器中的元素的时候,才会执行到内部的代码

楼上回答的,都不太详细,我没懂起。
执行p.GetResult(),方法都不执行吗?

执行p.GetResult()返回一个迭代器,但是并不执行其中的代码。
MSDN不是说包含yield return的整个方法就叫做迭代器吗?怎么你又说执行p.GetResult()返回一个迭代器呢?


这个实现比较复杂,C#编译器会将你这个方法拆开,变成3个方法,并且在内部维护一个状态机。p.GetResult()相当于初始化迭代器。

#21


var itl = p.GetResult().GetEnumerator();
itl.MoveNext();
itl.MoveNext();
itl.MoveNext();
itl.MoveNext();

        public IEnumerable<int> GetResult()
        {
            Console.WriteLine("0");
            yield return 1;
            Console.WriteLine("1");
            yield return 2;
            Console.WriteLine("2");
            yield return 3;
            Console.WriteLine("3");
            yield return 4;
            Console.WriteLine("4");
            yield break;
        }

你调试下这段代码,自己再想想