简体   繁体   English

IEnumerable 的早期执行

[英]Early execution of IEnumerable

So I have two methods both performing iteration through IEnumerable collection.所以我有两种方法都通过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;
            }
        }
    }

I recently came to know method returning IEnumerable will not execute until enumerated.我最近才知道返回IEnumerable方法在枚举之前不会执行。

So I created two blocks of code to call each method所以我创建了两个代码块来调用每个方法

Calling GetRange调用 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获取范围函数

But, in the case of GetRangeFunction , the method is called right away on creating the iterator.但是,在GetRangeFunction的情况下,该方法会在创建迭代器时立即调用。

var iterator = GetRangeFunction(0, 5);

Why is this behaviour?为什么会出现这种行为? I was thinking GetRangeFunction also, won't execute until an item is requested.我也在想GetRangeFunction ,在请求项目之前不会执行。

EDIT编辑

My question is poorly stated, let me try to explain it one more time.我的问题表述不清,让我再解释一次。

Both the enumerators are returning items via yield one after other.两个枚举器都通过 yield 一个接一个地返回项目。 But in the case of GetRange , no statement ( not even checking count is less than zero ) is executed until any operation is done on the enumerator.但是在GetRange的情况下,在枚举器上完成任何操作之前,不会执行任何语句( not even checking count is less than zero )。 But, in case of GetRangeFunction the condition check is executed when the method is called to create the iterator.但是,在GetRangeFunction的情况下,在调用该方法以创建迭代器时执行条件检查。

According to MSDN , local function can allow exceptions to surface immediately.根据MSDN ,本地函数可以允许异常立即浮出水面。 For example, consider the following code.例如,请考虑以下代码。

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

To make sure local method version can get exception quickly, GetNumberByLocalMethod version will execute immediately and not wait until the first iterate.为了确保本地方法版本可以快速获取异常,GetNumberByLocalMethod 版本将立即执行,而不是等到第一次迭代。

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

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