Reputation: 93444
I have some code i'd like to refactor that uses a C# iterator (ie IEnumerable). Unfortunately, I can't see to quite figure out the best way to allow other functions to work with the iterator without causing it to restart the iterator.
For example:
NewLineEnumerator nle = new NewLineEnumerator();
while (bytesRead > 0)
{
var nlenum = nle.Process(inputData, bytesRead);
foreach (string block in nlenum)
{
DoSomething(nlenum);
}
}
void DoSomething(IEnumerable<string> myiter)
{
foreach (var s in myiter)
{
// myiter is restarted, and begins at the start of the iterator again
}
}
You might be asking why i would want to do this. The reason is that I have a stream of data, surrounded by "command blocks". Depending on the command, I send it to a different subfunction to process. So I want to keep iterating where i left off in the stream either at the start, or at the end.
Any suggestions here?
Upvotes: 0
Views: 188
Reputation: 28207
As Nick said, create one IEnumerator<string>
and pass it between methods. The code would look something like:
NewLineEnumerator nle = new NewLineEnumerator();
while (bytesRead > 0)
{
var nlenum = nle.Process(inputData, bytesRead);
using (var enumerator = nlenum.GetEnumerator())
{
while (enumerator.MoveNext())
{
DoSomething(enumerator);
Console.WriteLine(enumerator.Current);
}
}
// ensure that bytesRead is decremented by the code that runs above
}
void DoSomething(IEnumerator<string> myenum)
{
while (myenum.MoveNext())
{
if (ShouldProcess(myenum.Current))
{
// process it
}
else
{
// return to outer loop
break;
}
}
}
(Note that if you're using .NET 1.0, and IEnumerable
, not IEnumerable<string>
, the using
statement may not compile.)
Upvotes: 2
Reputation: 724
Pass an IEnumerator<string> rather than the IEnumerable<string>, by calling GetEnumerator(). It will retain the state across calls.
Upvotes: 5