21

我需要设置表单上每个文本框的高度,其中一些嵌套在其他控件中。我以为我可以做这样的事情:

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;
        }
    }
}

像这样使用它:

foreach(TextBox textBox in FindTextBoxes(this))
{
    textBox.Height = height;
}

但是编译器当然会吐出它的假人,因为foreach需要一个IEnumerable而不是IEnumerator

有没有办法做到这一点而不必使用GetEnumerator()方法创建一个单独的类?

4

5 回答 5

14

正如编译器告诉您的,您需要将返回类型更改为 IEnumerable。这就是 yield return 语法的工作原理。

于 2008-08-06T12:19:57.367 回答
10

只是为了澄清

private static IEnumerator<TextBox> FindTextBoxes(Control rootControl)

更改为

private static IEnumerable<TextBox> FindTextBoxes(Control rootControl)

这应该是全部:-)

于 2008-08-08T23:34:44.237 回答
3

如果您返回 IEnumerator,则每次调用该方法时它将是一个不同的枚举器对象(就像您在每次迭代时重置枚举器一样)。如果您返回 IEnumerable,则 foreach 可以根据使用 yield 语句的方法进行枚举。

于 2008-08-06T13:04:33.487 回答
1
// 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;
    }
}
于 2008-08-06T12:32:59.353 回答
0

如果你有一个枚举器,并且需要在 for-each 循环中使用它,你可以使用以下内容来包装它:

静态公共类枚举Helper
{
    公共类 enumeratorHolder<T>
    {
        私人 T theEnumerator;
        public T GetEnumerator() { return theEnumerator; }
        公共 enumeratorHolder(T newEnumerator) { theEnumerator = newEnumerator;}
    }
    静态 enumeratorHolder<T> toEnumerable<T>(T theEnumerator) { return new enumeratorHolder<T>(theEnumerator); }
    私有类 IEnumeratorHolder<T>:IEnumerable<T>
    {
        私人 IEnumerator<T> theEnumerator;
        public IEnumerator<T> GetEnumerator() { return theEnumerator; }
        System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { return theEnumerator; }
        公共 IEnumeratorHolder(IEnumerator<T> newEnumerator) { theEnumerator = newEnumerator; }
    }
    静态 IEnumerable<T> toEnumerable<T>(IEnumerator<T> theEnumerator) { return new IEnumeratorHolder<T>(theEnumerator); }
}

toEnumerable方法将接受认为可接受的返回类型 from 的任何内容GetEnumerator,并返回可以在foreach. 如果参数是 anIEnumerator<>响应将是 an IEnumerable<T>,尽管调用GetEnumerator它一次可能会产生不好的结果。

于 2011-07-14T19:09:39.747 回答