Vă mulțumim pentru susținere

Pot avea o metodă de returnare a IEnumerator <T> și o folosesc într-o buclă foreach?

Trebuie să reglez înălțimea fiecărui câmp text pe formularul meu, dintre care unele sunt imbricate în cadrul altor controale. Am crezut că pot face așa ceva:

private static IEnumerator 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;
        }
    }
}

Folosindu-l astfel:

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

Însă, desigur, compilatorul își scutește manechinul, deoarece foreach se așteaptă la un IEnumerabil , nu la un IEnumerator .

Există o modalitate de a face acest lucru fără a trebui să creați o clasă separată cu o metodă GetEnumerator () ?

0
adăugat editat
De fapt, foreach nu așteaptă deloc IEnumerable (nici un IEnumerable ). Se așteaptă numai ceva care are o metodă GetEnumerator . Această metodă, la rândul său, nu trebuie neapărat să returneze IEnumerator sau IEnumerator ? trebuie doar să returneze ceva care are o metodă MoveNext () și o proprietate Curentă .
adăugat autor Timwi

5 răspunsuri

Doar pentru a clarifica

private static IEnumerator FindTextBoxes(Control rootControl)

Schimbări la

private static IEnumerable FindTextBoxes(Control rootControl)

Ar trebui sa fie totul :-)

0
adăugat
// Generic function that gets all child controls of a certain type, 
// returned in a List collection
private static List GetChildTextBoxes(Control ctrl) where T : Control{
    List tbs = new List();
    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(ctrl)) {
        t.Height = height;
    }
}
0
adăugat

Dacă vi se dă un enumerator și trebuie să-l utilizați într-o buclă pentru fiecare buzunar, puteți folosi următoarele pentru ao înfășura:

static public class enumerationHelper
{
    public class enumeratorHolder
    {
        private T theEnumerator;
        public T GetEnumerator() { return theEnumerator; }
        public enumeratorHolder(T newEnumerator) { theEnumerator = newEnumerator;}
    }
    static enumeratorHolder toEnumerable(T theEnumerator) { return new enumeratorHolder(theEnumerator); }
    private class IEnumeratorHolder:IEnumerable
    {
        private IEnumerator theEnumerator;
        public IEnumerator GetEnumerator() { return theEnumerator; }
        System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { return theEnumerator; }
        public IEnumeratorHolder(IEnumerator newEnumerator) { theEnumerator = newEnumerator; }
    }
    static IEnumerable toEnumerable(IEnumerator theEnumerator) { return new IEnumeratorHolder(theEnumerator); }
}

The toEnumerable method will accept anything that or would regard an acceptable return type from GetEnumerator, and return something that can be used in foreach. If the parameter is an IEnumerator<> the response will be an IEnumerable, though calling GetEnumerator on it once will likely yield bad results.

0
adăugat

Dacă întoarceți IEnumerator, va fi un obiect enumerator diferit de fiecare dată când apelați această metodă (acționând ca și cum ați restabili enumeratorul pe fiecare iterație). Dacă reveniți la IEnumerable atunci un foreach poate enumera pe baza metodei cu declarația de randament.

0
adăugat

După cum vă spune compilatorul, trebuie să modificați tipul de retur la IEnumerable. Așa funcționează sintaxa returnării randamentului.

0
adăugat
sau IEnumerator . Este doar în bucla foreach unde IEnumerator nu poate fi folosită.
adăugat autor Timwi