c# – 可以多次重复使用IEnumerable集合吗?

前端之家收集整理的这篇文章主要介绍了c# – 可以多次重复使用IEnumerable集合吗?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
基本上我想知道如果可以在代码中多次使用枚举.无论你是否早点休息,枚举总是会在下面的每个foreach案例中重置,所以给我们从效果集合的开始到结束一致的列举?
var effects = this.EffectsRecursive;

foreach (Effect effect in effects)
{
...
}

foreach (Effect effect in effects)
{
    if(effect.Name = "Pixelate")
        break;
}

foreach (Effect effect in effects)
{
...
}

编辑:EffectsRecursive的实现是这样的:

public IEnumerable<Effect> Effects
{
    get
    {
        for ( int i = 0; i < this.IEffect.NumberOfChildren; ++i )
        {
            IEffect effect = this.IEffect.GetChildEffect ( i );
            if ( effect != null )
                yield return new Effect ( effect );
        }
    }
}

public IEnumerable<Effect> EffectsRecursive
{
    get
    {
        foreach ( Effect effect in this.Effects )
        {
            yield return effect;
            foreach ( Effect seffect in effect.ChildrenRecursive )
                yield return seffect;
        }
    }
}

解决方法

消耗序列的代码很好.正如花费者指出的那样,如果树很深,产生枚举的代码可能会有性能问题.

假设在最深处,你的树是四深;想想在四深的节点上会发生什么.要获取该节点,您将遍历根,调用一个迭代器,该迭代器调用一个迭代器,该迭代器将节点传递回传递节点的代码返回到传递节点的代码.将节点传递给调用者,您已经在其中配置了一个小桶旅,其中有四个人,他们正在将数据从对象转到对象,然后才能到达需要的循环.

如果树只有四深,大概不大.但是假设树是一万个元素,并且有一千个节点在顶部形成一个链表,底部剩下的九千个节点.现在,当您重复这九千个节点时,每个节点必须通过一千个迭代器,总共有900万个拷贝来获取9000个节点. (当然,你可能已经收到了一个堆栈溢出错误,并且崩溃了这个进程.)

处理这个问题的方法是自己管理堆栈,而不是在栈上推新的迭代器.

public IEnumerable<Effect> EffectsNotRecursive() 
{     
    var stack = new Stack<Effect>();
    stack.Push(this);
    while(stack.Count != 0)
    {
        var current = stack.Pop();
        yield return current;
        foreach(var child in current.Effects)
            stack.Push(child);
    }
}

原始实现具有O(nd)的时间复杂度,其中n是节点数,d是树的平均深度;因为在最坏的情况下d可以是O(n),并且在最好的情况下是O(lg n),这意味着算法在时间上在O(n lg n)和O(n ^ 2)之间.在堆空间(对于所有迭代器)和O(d)在堆栈空间中(对于所有递归调用)为O(d).

新实现具有O(n)的时间复杂度,在堆空间中为O(d),在堆栈空间中为O(1).

这一点的一个不足之处在于订单是不同的;在新算法中,树从上到下,从右到左遍历,而不是从上到下,从左到右.如果这样麻烦你就可以说

foreach(var child in current.Effects.Reverse())

代替.

有关这个问题的更多分析,请参阅我的同事Wes Dyer关于这个问题的文章

http://blogs.msdn.com/b/wesdyer/archive/2007/03/23/all-about-iterators.aspx

原文链接:https://www.f2er.com/csharp/94342.html

猜你在找的C#相关文章