0

私は自分の IEnumerable クラスを構築しようとしていました。これは、最初に何かが反復されたときにすべてのアイテムに対して何らかのアクションを実行するもので、フレームワークには既に使用できるものがありますか?

ここに私が構築していたものがあるので、私が探しているものがわかります:

public class DelayedExecutionIEnumerable<T> : IEnumerable<T>
{
    IEnumerable<T> Items;
    Action<T> Action;
    bool ActionPerformed;

    public DelayedExecutionIEnumerable(IEnumerable<T> items, Action<T> action)
    {
        this.Items = items;
        this.Action = action;
    }

    void DoAction()
    {
        if (!ActionPerformed)
        {
            foreach (var i in Items)
            {
                Action(i);
            }
            ActionPerformed = true;
        }
    }

    #region IEnumerable<IEntity> Members

    public IEnumerator<T> GetEnumerator()
    {
        DoAction();
        return Items.GetEnumerator();
    }

    #endregion

    #region IEnumerable Members

    System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
    {
        DoAction();
        return Items.GetEnumerator();
    }

    #endregion
}
4

2 に答える 2

2

あなたがやろうとしていることを正確に実行する何かがあるかどうかはわかりませんが、これにはLazy <T>を使用することをお勧めします。これにより、スレッドセーフの問題(個々のアイテムごと)が処理されます。

public class DelayedExecutionIEnumerable<T> : IEnumerable<T>
{
    List<Lazy<T>> LazyItems;

    public DelayedExecutionIEnumerable(IEnumerable<T> items, Action<T> action)
    {
        // Wrap items into our List of Lazy items, the action predicate
        // will be executed only once on each item the first time it is iterated.
        this.LazyItems = items.Select(
            item => new Lazy<T>(
                () => 
                    {
                        action(item);
                        return item;
                    }, 
                    true)).ToList(); // isThreadSafe = true 
    }

    #region IEnumerable<IEntity> Members

    public IEnumerator<T> GetEnumerator()
    {
        return this.LazyItems.Select(i => i.Value).GetEnumerator();
    }

    #endregion


    #region IEnumerable Members

    System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
    {
        return this.LazyItems.Select(i => i.Value).GetEnumerator();
    }

    #endregion
}  
于 2011-03-31T05:30:23.137 に答える
2

Iteratoryieldを使用すると、独自の遅延列挙子シーケンスを簡単に作成できます。

また、あなたの場合、LINQ の Select メソッドを簡単に悪用できます。

items.Select(i=>{DoStuff(i); return i;});

多分それをまとめる?

public static IEnumerable<T> DoStuff<T>(this IEnumerable<T> items, Action<T> doStuff)
{
    return items.Select(i=>{doStuff(i); return i;});
}

(テストされていない手書きのコード、注意して使用してください)

于 2011-03-31T06:07:53.043 に答える