This is in C#, I have a class that I am using from some else\'s DLL. It does not implement IEnumerable but has 2 methods that pass back a IEnumerator. Is there a way I can u
The type only requires to have a public/non-static/non-generic/parameterless method named GetEnumerator
which should return something that has a public MoveNext
method and a public Current
property. As I recollect Mr Eric Lippert somewhere, this was designed so as to accommodate pre generic era for both type safety and boxing related performance issues in case of value types.
For instance this works:
class Test
{
public SomethingEnumerator GetEnumerator()
{
}
}
class SomethingEnumerator
{
public Something Current //could return anything
{
get { }
}
public bool MoveNext()
{
}
}
//now you can call
foreach (Something thing in new Test()) //type safe
{
}
This is then translated by the compiler to:
var enumerator = new Test().GetEnumerator();
try {
Something element; //pre C# 5
while (enumerator.MoveNext()) {
Something element; //post C# 5
element = (Something)enumerator.Current; //the cast!
statement;
}
}
finally {
IDisposable disposable = enumerator as System.IDisposable;
if (disposable != null) disposable.Dispose();
}
From 8.8.4 section of the spec.
Something worth noting is the enumerator precedence involved - it goes like if you have a public GetEnumerator
method, then that is the default choice of foreach
irrespective of who is implementing it. For example:
class Test : IEnumerable
{
public SomethingEnumerator GetEnumerator()
{
//this one is called
}
IEnumerator IEnumerable.GetEnumerator()
{
}
}
(If you don't have a public implementation (ie only explicit implementation), then precedence goes like IEnumerator
> IEnumerator
.)