2015-04-02 115 views
0

我可以知道IEnumerable(或IQueryable)的延期評估是否已經發生?也就是說,是否曾經調用過GetEnumerator().MoveNext()。有沒有辦法?如何判斷IEnumerable是否已經過評估?

我如何在以下示例中編碼HasBeenEvaluated()

private void Example() 
{ 
    IEnumerable<Thing> things = _Repository.GetObjects<Thing>(); 

    bool x = HasBeenEvaluated(things); // returns false 

    foreach (var thing in things) 
    { 
     x = HasBeenEvaluated(things); // returns true 
    } 
} 
+1

http://stackoverflow.com/questions/19518859/how-to-determine-if-an-ienumerable-has-been-evaluated – Habib 2015-04-02 15:34:53

+1

also http://stackoverflow.com/questions/9624805/is-it-possible-to - 確定-IF-AN-ienumerablet-HAS-deffered-正在執行中 – Habib 2015-04-02 15:35:24

回答

1

您可以創建一個IEnumerable的是,迭代時,翻轉一個布爾值,表明它已被重複的包裝:

//TODO come up with a better name 
public class Foo<T> : IEnumerable<T> 
{ 
    private IEnumerable<T> wrapped; 
    public Foo(IEnumerable<T> wrapped) 
    { 
     this.wrapped = wrapped; 
    } 
    public bool HasBeenIterated { get; private set; } 
    public IEnumerator<T> GetEnumerator() 
    { 
     HasBeenIterated = true; 
     foreach (var item in wrapped) 
      yield return item; 
    } 

    IEnumerator IEnumerable.GetEnumerator() 
    { 
     return GetEnumerator(); 
    } 
} 

你的方法,現在可以變爲:

private void Example() 
{ 
    var things = new Foo<Thing>(_Repository.GetObjects<Thing>()); 

    bool x = things.HasBeenIterated;//is false 

    foreach (var thing in things) 
    { 
     x = things.HasBeenIterated;//is true 
    } 
} 
+0

這個問題的最初動機是我試圖編寫一個單元測試以確保評估不會很早發生。這符合法案。 – shamp00 2015-04-07 12:24:07

1

一般來說,沒有。界面IEnumerable<>不支持。

另外,如果你有一個IEnumerator<>,你不能說一般是否曾經調用過MoveNext()

有時IEnumerator<>將支持Reset()方法,但這不是你要求的。當您嘗試Reset()時,許多統計員只會拋出異常。

0

也許你可以從類型繼承並向它添加一個方法來返回狀態。

在這種情況下,您會向該類中添加一個屬性,該屬性將反映被調用操作的狀態。

public class StatefulThings : IEnumerable<Thing> 
{ 
    bool _moveNextExecuted = false; 

    public override bool MoveNext() 
    { 
     // Perform next pointer 

     // Set state of hasBeenEnumerated in here... 
     _moveNextExecuted = true; 
    } 
} 
相關問題