Laden...

IEnumerable<T> und IEnumerable

Erstellt von Raien vor 15 Jahren Letzter Beitrag vor 15 Jahren 2.977 Views
R
Raien Themenstarter:in
11 Beiträge seit 2007
vor 15 Jahren
IEnumerable<T> und IEnumerable

Hallihallo,

hab mich jetzt mal dazu genötigt ein bisschen in Patterns zu schnuppern, da ab einer gewissen Größe eines Projekts sonst nichts mehr geht wie ich feststellen musste. Da beim MVC-Pattern das Model die View benachrichtigen soll, wenn Daten geändert wurden, wollte ich mir eine eigen Collection schreiben, die Events anbietet wenn ein Item hinzugefügt wurde bzw. gelöscht wurde. Damit diese Auflistung auch mit foreach durchlaufen werden kann, muss man ja IEnumerable<T> implementieren und somit auch IEnumerable (also die nicht generische Variante).
Jetzt die Frage:
Wann wird die Methode GetEnumerator der nicht-generischen Variante aufgerufen, weil ich jetzt einige Situationen ausprobiert habe, aber diese Methode niemals aufgerufen wurde.

--> Muss ich diese überhaupt implementieren?

Danke schonmal...

Gruß
Raien

3.430 Beiträge seit 2007
vor 15 Jahren

Hallo Raien,

eigen Collection schreiben, die Events anbietet wenn ein Item hinzugefügt wurde bzw. gelöscht wurde

Ohne jetzt genauer auf deine Frage einzugehen, kann ich dir die ObservableCollection<T> empfehlen. Diese hat ein CollectionChanged-Event. Damit kriegst du dann schön raus ob elemente hinzugefügt oder entfernt wurden.

Ab .Net 3.0 ist die ObservableCollection dabei.
Wenn du .Net 2 verwendest dann gibts hier eine ObservableCollection für .Net 2.0

Gruss
Michael

Gelöschter Account
vor 15 Jahren

oder aber du verwendest die BindingList<t> in .net 2.0

0
767 Beiträge seit 2005
vor 15 Jahren

Wann wird die Methode GetEnumerator der nicht-generischen Variante aufgerufen, weil ich jetzt einige Situationen ausprobiert habe, aber diese Methode niemals aufgerufen wurde.

theoretisch so (code from scratch):


List<int> zahlen = new List<int>();
// nach belieben füllen
IEnumerable aufzählung = zahlen;
foreach(object obj in aufzählung) // jetzt wird die nicht generische aufgerufen

obacht, grad bei diesem Beispiel wird das weniger performant als die generische variante, weil alle ints in ein objekt gepackt werden müssen -> siehe boxing.

loop:
btst #6,$bfe001
bne.s loop
rts

49.485 Beiträge seit 2005
vor 15 Jahren

Hallo Raien,

-> Muss ich diese überhaupt implementieren?

ja, aber man kann und sollte das so tun, dass man einfach den generischen Enumerator zurückliefert.

herbivore

R
Raien Themenstarter:in
11 Beiträge seit 2007
vor 15 Jahren

Danke danke für die Antworten!!
Das mit dem foreach mit Object hatte ich schon probiert, nur ohne dabei vorher die Auflistung in die Schnittstelle IEnumerable zu casten. Wenn man foreach direkt auf die generische Auflistung aufruft, nimmt es wohl immer die generische Methode.

Also nochmals vielen Dank!

Gruß
Raien

0
767 Beiträge seit 2005
vor 15 Jahren

Liegt daran, weil die nicht generische Variante explizit implementiert ist, und daher nur sichtbar wird wenn man übers interface geht.

loop:
btst #6,$bfe001
bne.s loop
rts

O
778 Beiträge seit 2007
vor 15 Jahren

Ich denke eher, dass der Compiler wenn die generische Variante machbar ist auf die generische Variante zurückgreift. Welche von den beiden jetzt explizit oder vererbt ist, wird dem Wurscht sein.

IEnumerable macht spziell dann Sinn, wenn eine Collection hat, von der man zwar weiß, dass es eine Collection ist, aber man weiß den Typ nicht und es ist enem eigentlich auch mehr oder weniger egal, man will aber möglichst einfach an die Elemente der Collection ran. Ich denke dabei an Klassen, die x-beliebige Inhalte serialisieren oder darstellen (z.B. XmlSerializer, wenn man denn einen eigenen schreiben wölte).

O
778 Beiträge seit 2007
vor 15 Jahren

Wenn ich mit foreach über ein Objekt von Test2 gehe, dann springt der Haltepunkt bei der generischen IEnumerable<string> an, obwohl Test2 explizit IEnumerable implementiert.

public class Test1 : IEnumerable<string>
    {

        #region IEnumerable<string> Member

        public IEnumerator<string> GetEnumerator()
        {
            throw new NotImplementedException();
        }

        #endregion

        #region IEnumerable Member

        IEnumerator IEnumerable.GetEnumerator()
        {
            throw new NotImplementedException();
        }

        #endregion
    }

    public class Test2 : Test1, IEnumerable
    {

        #region IEnumerable Member

        IEnumerator IEnumerable.GetEnumerator()
        {
            throw new NotImplementedException();
        }

        #endregion
    }

Wenn ich dagegen eine x-beliebige Collection habe, brauch ich nur normal prüfen, ob die IEnumerable implementiert, caste drauf und dann hat der Compiler gar keine andere Chance als die nicht generische Variante aufzurufen, weil er selber nicht weiß, welches IEnumerable er sonst aufrufen soll.