I need to set the height of every textbox on my form, some of which are nested within other controls. I thought I could do something like this:
private static IEnumerator<TextBox> FindTextBoxes(Control rootControl)
{
foreach (Control control in rootControl.Controls)
{
if (control.Controls.Count > 0)
{
// Recursively search for any TextBoxes within each child control
foreach (TextBox textBox in FindTextBoxes(control))
{
yield return textBox;
}
}
TextBox textBox2 = control as TextBox;
if (textBox2 != null)
{
yield return textBox2;
}
}
}
Using it like this:
foreach(TextBox textBox in FindTextBoxes(this))
{
textBox.Height = height;
}
But of course the compiler spits its dummy, because foreach expects an IEnumerable rather than an IEnumerator.
Is there a way to do this without having to create a separate class with a GetEnumerator() method?
As the compiler is telling you, you need to change your return type to IEnumerable. That is how the yield return syntax works.
Just to clarify
Changes to
That should be all :-)
If you return IEnumerator, it will be a different enumerator object each time call that method (acting as though you reset the enumerator on each iteration). If you return IEnumerable then a foreach can enumerate based on the method with the yield statement.
If you are given an enumerator, and need to use it in a for-each loop, you could use the following to wrap it:
The
toEnumerable
method will accept anything that c# or vb would regard an acceptable return type fromGetEnumerator
, and return something that can be used inforeach
. If the parameter is anIEnumerator<>
the response will be anIEnumerable<T>
, though callingGetEnumerator
on it once will likely yield bad results.