2011-03-31 5 views
0

뭔가 처음으로 뭔가 반복 할 때 모든 항목에 대해 몇 가지 작업을 수행하는 자체 IEnumerable 클래스를 만들려고했는데 궁금해하기 시작했습니다. 프레임 워크에 이미 사용할 수있는 항목이 있습니까? 당신은 내가 무엇을 찾고 아이디어 그래서 여기 .NET에서 실행을 지연시키는 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 
} 
+0

이의 목적은 무엇 일 것 (주의를 사용하여 코드를 테스트하지 손으로 쓴)? – FreeAsInBeer

+1

프레임 워크에 내장 된 것에 대해 잘 모르겠습니다. 구현이 원하는 것을 수행하는 것 같습니다. 내가 언급 할 수있는 유일한 것은 여러 스레드가 GetEnumerator()를 동시에 호출하면 코드가 쉽게 문제가 될 수 있다는 것입니다. – dlev

+3

왜 돌아 오기 전에 루프를 통해 모든 작업을 수행하고 싶습니까? 반복 할 때 각 항목을보다 쉽게 ​​수행 할 수 있고 각 항목을 'yield return'할 수 있으므로 반복 작업을 한 번만 수행하면 작업 실행이 지연됩니다. –

답변

2

Iteratorsyield 당신이 쉽게 자신의 게으른 열거 순서를 만들 수 있습니다.

또한 귀하의 경우에는 쉽게 LINQ 방법 선택을 남용 할 수 있습니다.

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

2

을,하지만 난 추천 이 위해 게으른 <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 
} 
관련 문제