Frage

Ich fühle mich meine Frage ziemlich dumm ist, oder eine andere Weise zu setzen ist: auch ich in meinem Code bin verloren eine Abhilfe für jetzt zu sehen. Bleiben Sie zu lange auf ein Problem, und Ihre Vision wird enger und enger> <. Plus Ich bin nicht gut genug, um mit Vererbung, Polymorphismus und so

Hier ist die Idee: Ich habe mehrere Liste der abgeleiteten Klasse, und ich möchte auf diesen Listen generische Funktionen aufzurufen (accesing und die Mitglieder der Basisklasse zu ändern). Ich fühle mich etwas mit Vererbung zu tun ist, aber ich schaffte es nicht, um es, wie ich jetzt wollen arbeiten.

Hier ist ein sehr einfaches Beispiel, was ich zu tun werde Absicht:

class Baseclass
{
    public int ID;
    public string Name;
}
class DerivedClass1 : Baseclass
{
}

private void FuncOnBase(List<Baseclass> _collection)
{
    // ...

    foreach (Baseclass obj in _collection)
    {
        ++obj.ID;
    }

    // ...
}
private void FuncTest()
{
    List<DerivedClass1> collection1 = new List<DerivedClass1>();
    collection1.Add(new DerivedClass1() { ID = 1 });
    collection1.Add(new DerivedClass1() { ID = 2 });
    collection1.Add(new DerivedClass1() { ID = 3 });

    FuncOnBase(collection1);   //  ==> forbidden, cannot convert the derived class list to the base class list
}
War es hilfreich?

Lösung

Gotta love Varianz. Ein List<DerivedClass1> ist nicht ein List<Baseclass> -. Andernfalls FuncOnBase eine Baseclass zur Liste hinzuzufügen versuchen könnte, und der Compiler würde es nicht beschmutzen

Ein Trick ist, eine generische Methode zu verwenden:

private void FuncOnBase<T>(List<T> _collection) where T : Baseclass
{
    // ...

    foreach (T obj in _collection)
    {
        obj.ID++;
    }

    // ...
}

In Bezug auf das Beispiel, das ich oben dargestellt - beachten Sie, dass wir eine T zur Liste hinzufügen können; insbesondere dann nützlich, wenn wir die T : new() Constraint hinzufügen oder in übergeben (zum Beispiel) ein params T[].

Beachten Sie auch, dass wird IEnumerable<T> kovariant in C # 4.0 / .NET 4.0, wenn Sie also in nur einen IEnumerable<Baseclass> bestanden (statt einer Liste), es würde funktionieren "wie":

private void FuncOnBase(IEnumerable<Baseclass> _collection)
{
   ///...
}

Andere Tipps

Wenn Sie nur eine foreach tun, erklären FuncOnBase(IEnumerable<Baseclass> collection), die Sie von FuncTest wie folgt aufrufen können:

FuncOnBase(collection1.Cast<Baseclass>());

Wenn Sie eine Methode mit einem List<T> Parameter erklären, sondern nur seine IEnumerable<T> Funktionen verwenden, die Sie hinzufügen API Einschränkungen, die nichts in Ihrem Code bedeuten.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top