C# 早期执行IEnumerable

C# 早期执行IEnumerable,c#,.net,.net-core,ienumerable,C#,.net,.net Core,Ienumerable,因此,我有两种方法都通过IEnumerable集合执行迭代 public static IEnumerable<int> GetRange(int start, int count) { if (count < 0) throw new ArgumentOutOfRangeException(nameof(count)); var end = start + count; for (in

因此,我有两种方法都通过
IEnumerable
集合执行迭代

    public static IEnumerable<int> GetRange(int start, int count)
    {
        if (count < 0)
            throw new ArgumentOutOfRangeException(nameof(count));

        var end = start + count;

        for (int value = start; value < end; value++)
        {
            yield return value;
        }
    }


    public static IEnumerable<int> GetRangeFunction(int start, int count)
    {
        if (count < 0)
            throw new ArgumentOutOfRangeException(nameof(count));

        var end = start + count;
        return RangeEnumeration();

        //Using local function
        IEnumerable<int> RangeEnumeration()
        {
            for (var value = start; value < end; value++)
            {
                yield return value;
            }
        }
    }
获取范围函数

但是,对于
GetRangeFunction
,在创建迭代器时会立即调用该方法

var iterator = GetRangeFunction(0, 5);
为什么会有这种行为?我在想,
GetRangeFunction
也不会执行,直到请求一个项

编辑

我的问题陈述得很糟糕,让我再解释一遍

两个枚举数都通过yield一个接一个地返回项。但是在GetRange的情况下,在对枚举数执行任何操作之前,不会执行任何语句(
甚至不检查计数是否小于零)。但是,在GetRangeFunction的情况下,当调用该方法以创建迭代器时,将执行条件检查。

根据,局部函数可以允许立即出现异常。例如,考虑下面的代码。

var iterator = GetRangeFunction(0, 5);
        static void Main()
        {            
            IEnumerable<int> ienum = GetNumber(50, 110);
            //below line will not execute if use GetNumberByLocalMethod
            Console.WriteLine("Retrieved enumerator...");

            foreach (var i in ienum)
            {
                Console.Write($"{i} ");
            }
        }

        public static IEnumerable<int> GetNumberByLocalMethod(int start, int end)
        {
            throw new Exception("deliberately exception");
            return InnerGetNumberByLocalMethod();
            IEnumerable<int> InnerGetNumberByLocalMethod()
            {
                for (int i = start; i <= end; i++)
                {                    
                        yield return i;
                }
            }
        }

        public static IEnumerable<int> GetNumber(int start, int end)
        {
            throw new Exception("deliberately exception");

            for (int i = start; i <= end; i++)
            {                
                    yield return i;
            }
        }
static void Main()
{            
IEnumerable ienum=GetNumber(50110);
//如果使用GetNumberByLocalMethod,则不会执行下面的行
WriteLine(“检索的枚举器…”);
foreach(ienum中的变量i)
{
Console.Write($“{i}”);
}
}
公共静态IEnumerable GetNumberByLocalMethod(int开始,int结束)
{
抛出新异常(“故意异常”);
返回InnerGetNumberByLocalMethod();
IEnumerable InnerGetNumberByLocalMethod()
{

对于(int i=start;i
,在枚举之前不会执行它-它将执行到返回枚举器对象的点。对于普通迭代器函数,您可能会认为它是“未执行”的。是否只有在编译时才做出这些决定?如果我错了,请纠正我。在迭代器循环之前和yield返回之前添加
Console.WriteLine
。看看会发生什么。@Steve,@GSerg这实际上不是真的。使用
yield
的整个方法只会在enumeration@RudreshaParameshappa请看.compiler将整个
IEnumerable GetRange
转换为状态机,因此在枚举之前不会执行其中的代码。但是
IEnumerable GetRange函数
根本不会转换为状态机,只有
IEnumerable RangeEnumeration()
是。我认为这只是因为局部方法被视为一个单独的方法体,并且只有在计算所有捕获的变量时才能工作。因为
GetNumberByLocalMethod
的外部方法体没有
yield
语句,所以可以立即对其进行计算。@ChaosPandion是的,你是对的,我也这么认为.