I have a code like:
class T : IEnumerable, IEnumerator
{
private int position = -1;
public T() { }
public IEnumerator GetEnumerator() { return this; }
public object Current { get { return position; } }
public bool MoveNext()
{
position++;
return (position < 5);
}
public void Reset() { position = -1; }
}
//Using in code:
T t = new T();
foreach (int i in t)
//to do something
In the code above all is working fine but when I use next:
foreach (int i in t)
if (i == 2)
foreach (int p in t)
//print p
else
//print i
It prints (in brackets second loop): 0 1 (3 4) 2 instead of 0 1 (0 1 2 3 4) 2 3 4 I tested It on List and Collection and they do It right. How can I to achive what I need?
You can't because you have made your code surface a single enumerator, itself a mistake IMO. A better version would be, for me:
class T : IEnumerable<int> {
public IEnumerator<int> GetEnumerator() {
int i = 0;
while(i < 5) {
yield return i;
i++;
}
}
IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); }
}
The compiler will create the right devices to achieve this with separate enumerators.
Unless you are writing for .NET 1.1, then if you find yourself manually writing an enumarator, there's a very good chance that you are doing it the hard way, and getting it wrong as a bonus.
If you really must do it the hard way:
class T : IEnumerable<int>
{
public T() { }
public IEnumerator<int> GetEnumerator() { return new TEnumerator(); }
IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); }
private class TEnumerator : IEnumerator<int>
{
private int position = -1;
public int Current { get { return position; } }
object IEnumerator.Current { get { return Current; } }
void IDisposable.Dispose() {}
public bool MoveNext()
{
position++;
return (position < 5);
}
public void Reset() { position = -1; }
}
}
The significance here is that different instances of TEnumerator
allow the same T
instance to be iterated separately.
foreach (int i in t)
if (i == 2)
foreach (int p in t)
//print p
else
//print i
First always use braces, while you indenting matches what will happen another if
in there will confuse things.
foreach (int i in t) {
if (i == 2) {
foreach (int p in t) {
//print p
}
} else {
//print i
}
}
But you problem: you only have one counter per instance of T
, and you are using the same instance. Therefore you do through once. If you want to allow concurrent enumerations the enumerator object will need to be separate with GetEnumerator
returning a new instance each time.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With