繁体   English   中英

IEnumerable 的早期执行

[英]Early execution of IEnumerable

所以我有两种方法都通过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的情况下,该方法会在创建迭代器时立即调用。

var iterator = GetRangeFunction(0, 5);

为什么会出现这种行为? 我也在想GetRangeFunction ,在请求项目之前不会执行。

编辑

我的问题表述不清,让我再解释一次。

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

根据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 版本将立即执行,而不是等到第一次迭代。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM