MyCollection<MyClass> als ICollection<MyBaseClass>



  • Moin,

    wie der Titel schon sagt: Wie erhalte ich ein MyCollection<MyClass> als ICollection<MyBaseClass>

    Wieso geht sowas nicht? Ich muss per Reflection eine Collection auslesen von der ich nur weiß dass ich das ICollection Interface mit meiner Basisklasse ansprechen kann. Aber ich kann weder casten noch den as Operator verwenden (weil null bzw exception)
    Nichtmal ICollection<Object> geht - wieso? 😕



  • Das darf doch gar nicht funktionieren! ICollection<MyBaseClass> erlaubt es, beliebige Instanzen von (Subtypen von) MyBaseClass hinzuzufügen - MyCollection<MyClass> kann damit aber nicht umgehen!



  • Guter Einwand! Und wenn ich was readonly artiges hätte wie IEnumerable <>? (kann ich grad nicht testen, Sorry :D)



  • Das einfachste was mir jetzt einfallen würde, wäre in der MyCollection<MyClass> eine Methode zum Abrufen der ICollection zu implementieren.

    Quasi etwas wie:

    public class MyCollection<T> : ICollection<T>
    {
        // ..
    
        public ICollection<TBase> GetBaseCollection<TBase>()
        {
             List<TBase> baseCollection = new List<TBase>();
             foreach(T item in this)
             {
                 baseCollection.Add(item);
             }
             return baseCollection;
        }
    }
    

    Jetzt nach dem ich es hier vorgetippt habe erscheint es mir aber doch nicht mehr optimal. - Aber bleibt wohl nur etwas in der Richtung übrig.



  • Nach längerem Nachdenken find ich die Idee auch nicht mehr so super 😃 Aber irgendeinen Mechanismus muss es für sowas geben - Es ist mir gerade in diesem PropertyGrid im VisualStudio Form-Editor aufgefallen: Wenn da eine List/Array/Collection Eigenschaft auftaucht erkennt der das und zeigt dann "(Auflistung)" an mit dem "..." Button und über den kann man die Elemente durchbrowsen. Der wird ja nichts anderes machen als das Ding per Reflection auslesen und interpretieren. Oder meint ihr der hat da jeweils eine explizite Implementierung für den jeweiligen Typ? 😕



  • Ich kann dir nicht sagen wie das im Forms-Editor aussieht. Ich würde jedoch abraten irgendetwas mit Reflection zu frickeln.

    Für die Umwandlung in IEnumerable<MyBaseClass> würde mir folgendes einfallen:

    MyCollection<MyClass> collection = new MyCollection<MyClass>();
    //... collection füllen
    
    IEnumerable<MyBaseClass> baseCollection = collection.Cast<MyBaseClass>();
    

    // EDIT: Gerade beim Probieren noch was ähnliches gefunden:

    ICollection<MyBaseClass> baseList = collection.ConvertAll<MyBaseClass>(new Converter<MyClass, MyBaseClass>((x) => x));
    

    Außerdem nochmal für IEnumerable<T>:

    IEnumerable<MyBaseClass> baseList = collection.OfType<MyBaseClass>();
    


  • Mit readonly-Interfaces geht die Zuweisung ja problemlos:

    var list = new List<MyDerived>();
    IEnumerable<MyBase> e = list; // kein problem
    

    C# unterstützt ja generic type paraemter variance.
    Mehr Infos hier: https://msdn.microsoft.com/en-us/library/dd799517(v=vs.110).aspx

    MfG SideWinder



  • Mit IReadOnlyCollection<> und IReadOnlyList<> sollte das funktionieren.


Anmelden zum Antworten