
Can I have a method returning IEnumerator
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | 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; } } } |
像这样使用它:
1 2 3 4 | foreach(TextBox textBox in FindTextBoxes(this)) { textBox.Height = height; } |
但是,当然编译器会吐出它的虚拟对象,因为foreach期望使用IEnumerable而不是IEnumerator。
有没有一种方法可以不必使用GetEnumerator()方法创建单独的类?
正如编译器告诉您的那样,您需要将返回类型更改为IEnumerable。 这就是yield return语法的工作方式。
只是为了澄清
1 | private static IEnumerator<TextBox> FindTextBoxes(Control rootControl) |
更改为
1 | private static IEnumerable<TextBox> FindTextBoxes(Control rootControl) |
那应该是全部:-)
如果返回IEnumerator,则每次调用该方法都将是一个不同的枚举器对象(就像在每次迭代中重置枚举器一样)。 如果返回IEnumerable,则可以使用yield语句基于该方法枚举foreach。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | // Generic function that gets all child controls of a certain type, // returned in a List collection private static List< T > GetChildTextBoxes< T >(Control ctrl) where T : Control{ List< T > tbs = new List< T >(); foreach (Control c in ctrl.Controls) { // If c is of type T, add it to the collection if (c is T) { tbs.Add((T)c); } } return tbs; } private static void SetChildTextBoxesHeight(Control ctrl, int height) { foreach (TextBox t in GetChildTextBoxes<TextBox>(ctrl)) { t.Height = height; } } |
如果为您提供了枚举器,并且需要在for-each循环中使用它,则可以使用以下代码对其进行包装:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | static public class enumerationHelper { public class enumeratorHolder< T > { private T theEnumerator; public T GetEnumerator() { return theEnumerator; } public enumeratorHolder(T newEnumerator) { theEnumerator = newEnumerator;} } static enumeratorHolder< T > toEnumerable< T >(T theEnumerator) { return new enumeratorHolder< T >(theEnumerator); } private class IEnumeratorHolder< T >:IEnumerable< T > { private IEnumerator< T > theEnumerator; public IEnumerator< T > GetEnumerator() { return theEnumerator; } System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { return theEnumerator; } public IEnumeratorHolder(IEnumerator< T > newEnumerator) { theEnumerator = newEnumerator; } } static IEnumerable< T > toEnumerable< T >(IEnumerator< T > theEnumerator) { return new IEnumeratorHolder< T >(theEnumerator); } } |