早期执行IEnumerable

问题描述 投票:2回答:1

所以我有两种方法都通过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;
            }
        }
    }

我最近知道返回IEnumerable的方法在枚举之前不会执行。

所以我创建了两个代码块来调用每个方法

调用GetRange

var iterator = GetRange(0, 10); // This does not start the execution of `GetRange` method. Instead, it waits till any item is requested
foreach(var item in iterator) //Now the GetRange method is called
{

}

GetRangeFunction

但是,在GetRangeFunction的情况下,在创建迭代器时立即调用该方法。

var iterator = GetRangeFunction(0, 5);

为什么会这样?我也在考虑GetRangeFunction,在请求项目之前不会执行。

编辑

我的问题很难说,让我再试一次解释。

两个枚举器都是一个接一个地通过yield返回项目。但是在GetRange的情况下,在枚举器上执行任何操作之前不会执行任何语句(not even checking count is less than zero)。但是,在GetRangeFunction的情况下,在调用方法来创建迭代器时执行条件检查。

c# .net .net-core ienumerable
1个回答
2
投票

根据MSDN,本地函数可以允许异常立即浮出水面。例如,请考虑以下代码。

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

为了确保本地方法版本能够快速获得异常,GetNumberByLocalMethod版本将立即执行,而不是等到第一次迭代。

© www.soinside.com 2019 - 2024. All rights reserved.