如何IEnumerable的< T>在后台工作 [英] How does IEnumerable<T> work in background

查看:115
本文介绍了如何IEnumerable的< T>在后台工作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我徘徊在的IEnumerable<的更深入的功能; T> 接口

基本上,它工作在执行一个中间步骤。例如,如果你写的:

Basically, it works as an intermediary step in execution. For example, if you write:

IEnumerable<int> temp = new int[]{1,2,3}.Select(x => 2*x);



选择函数的结果不会计算(枚举),直到一些与临时做允许它(如列表< INT>列表= temp.ToList())。

The result of the Select function will not be calculated (enumerated) until something is done with temp to allow it (such as List<int> list = temp.ToList()).

不过,令我百思不解的是,因为的IEnumerable< T> 是一个接口,它不能根据定义,进行实例化。那么,什么是实际的项目(在本例中 2 * X 项目)驻留在收藏?

However, what puzzles me is, since IEnumerable<T> is an interface, it cannot, by definition, be instantiated. So, what is the collection the actual items (in the example 2*x items) reside in?

此外,如果我们写的的IEnumerable< INT> TEMP = Enumerable.Repeat(1,10); ,这将是底层的集合,其中的1秒被存储(数组列表,别的东西)

Moreover, if we were to write IEnumerable<int> temp = Enumerable.Repeat(1, 10);, what would be the underlying collection where the 1s are stored (array, list, something else)?

我似乎无法找到一个彻底的(更深入的)解释,实际执行这个接口和功能(例如,如果有一个潜在的收集,请问收益率关键字工作)

I cannot seem to find a thorough (more in-depth) explanation as to the actual implementation of this interface and its functionality (for example, if there is an underlying collection, how does the yield keyword work).

基本上,我所要求的是在的IEnumerable<的功能的更详细的解释; T>

Basically, what I am asking for is a more elaborate explanation on the functionality of IEnumerable<T>.

推荐答案

这并不是说实现了所有对象的IEnumerable 推迟以某种方式执行。接口的API使得它的可能的推迟执行,但是它没有的需要的它。有同样的实现不的推迟以任何方式执行。

Not all objects that implement IEnumerable defer execution in some way. The API of the interface makes it possible to defer execution, but it doesn't require it. There are likewise implementations that don't defer execution in any way.

那么,什么是集合实际的项目(在本例中2 * X项目)位于?

So, what is the collection the actual items (in the example 2*x items) reside in?

有是没有的。每当请求下一个值,它计算一个数值的需求的,它给调用者,然后忘记的价值。它不存储任何其他地方。

There is none. Whenever the next value is requested it computes that one value on demand, gives it to the caller, and then forgets the value. It doesn't store it anywhere else.

此外,如果我们写的的IEnumerable< INT> TEMP = Enumerable.Repeat(1,10); ,这将是底层的集合,其中的1秒被存储(数组列表,别的东西)

Moreover, if we were to write IEnumerable<int> temp = Enumerable.Repeat(1, 10);, what would be the underlying collection where the 1s are stored (array, list, something else)?

有不会之一。这将计算出每个新值的立即当你问下一个值的,它不会记得它之后。它仅存储足够的信息,以便能够计算下一个值,这意味着只需要存储元件和值的数量向左,得到

There wouldn't be one. It would compute each new value immediately when you ask for the next value and it won't remember it afterward. It only stores enough information to be able to compute the next value, which means it only needs to store the element and the number of values left to yield.

虽然实际.NET实现将利用建立这样一个类型的更简洁的方式,创造了推迟执行不是特别难枚举。否则,即使是很长的路比困难多乏味。您只需计算的迭代器的的MoveNext 方法下一个值。在这个例子中,你问,重复的,这很容易因为你只需要计算的如果的还有另外一个价值,它不是什么:

While the actual .NET implementations will use much more concise means of creating such a type, creating an enumerable that defers execution is not particularly hard. Doing so even the long way is more tedious than difficult. You simply compute the next value in the MoveNext method of the iterator. In the example you asked of, Repeat, this is easy as you only need to compute if there is another value, not what it is:

public class Repeater<T> : IEnumerator<T>
{
    private int count;
    private T element;

    public Repeater(T element, int count)
    {
        this.element = element;
        this.count = count;
    }
    public T Current { get { return element; } }

    object IEnumerator.Current
    {
        get { return Current; }
    }

    public void Dispose() { }

    public bool MoveNext()
    {
        if (count > 0)
        {
            count--;
            return true;
        }
        else
            return false;
    }

    public void Reset()
    {
        throw new NotSupportedException();
    }
}



(我省略了一个的IEnumerable 键入刚刚返回此类型的新实例,或者创建一个枚举的新实例静态重复方法有ISN ŧ什么特别有趣的,看看那里)

(I've omitted an IEnumerable type that just returns a new instance of this type, or a static Repeat method that creates a new instance of that enumerable. There isn't anything particularly interesting to see there.)

一个稍微更有趣的例子是像计数

A slightly more interesting example would be something like Count:

public class Counter : IEnumerator<int>
{
    private int remaining;

    public Counter(int start, int count)
    {
        Current = start;
        this.remaining = count;
    }
    public int Current { get; private set; }

    object IEnumerator.Current
    {
        get { return Current; }
    }

    public void Dispose() { }

    public bool MoveNext()
    {
        if (remaining > 0)
        {
            remaining--;
            Current++;
            return true;
        }
        else
            return false;
    }

    public void Reset()
    {
        throw new NotSupportedException();
    }
}

下面我们不仅计算,如果我们有另一个值,但什么下一个值,每个新值要求我们的时间

Here we're not only computing if we have another value, but what that next value is, each time a new value is requested of us.

这篇关于如何IEnumerable的&LT; T&GT;在后台工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆