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はIEnumeratorではなくIEnumerableを想定しているため、コンパイラはダミーを吐き出します。

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 ループで使用する必要がある場合は、次を使用してラップできます。

static public class enumerationHelper
{
    public class enumeratorHolder<T>
    {
        プライベート 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); }
    プライベート クラス IEnumeratorHolder<T>:IEnumerable<T>
    {
        プライベート 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); }
}

このtoEnumerableメソッドは、またはが からの許容可能な戻り値の型と見なすものをすべて受け入れGetEnumerator、 で使用できるものを返しますforeach。パラメータが の場合IEnumerator<>、応答は になりますがIEnumerable<T>、一度呼び出すとGetEnumerator悪い結果が生じる可能性があります。

于 2011-07-14T19:09:39.747 に答える