Reputation: 11326
Can I know whether the deferred evaluation of an IEnumerable
(or IQueryable
) has already happened? That is, whether GetEnumerator().MoveNext()
has ever been called. Is there a way?
How would I code HasBeenEvaluated()
in the following example?
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
}
}
Upvotes: 0
Views: 391
Reputation: 11570
Perhaps you can inherit from the type and add a method to it to return the state.
In this case you would add a property to this class that would reflect the state of an operation being called.
public class StatefulThings : IEnumerable<Thing>
{
bool _moveNextExecuted = false;
public override bool MoveNext()
{
// Perform next pointer
// Set state of hasBeenEnumerated in here...
_moveNextExecuted = true;
}
}
Upvotes: 1
Reputation: 203847
You can create a wrapper for an IEnumerable
that, when iterated, flips a boolean to indicate that it has been iterated:
//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();
}
}
Your method can now become:
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
}
}
Upvotes: 1
Reputation: 62002
In general, no. The interface IEnumerable<>
does not support that.
Also, if you have an IEnumerator<>
, you cannot tell in general if MoveNext()
was ever called.
Sometimes an IEnumerator<>
will support the Reset()
method, but this is not what you ask. Many enumerators will just throw an exception when you try to Reset()
.
Upvotes: 1