Generic Vererbung



  • Aloha liebe C# Gemeinschaft

    Ich habe grade ein kleines Problem mit Vererbung von Generics.

    Folgende Klassenstruktur liegt vor:

    public abstract class Agent
    public abstract class AbstractAction<A>  where A : Agent
    abstract class AbstractActor : Agent
    public class WalkDownAction : AbstractAction<AbstractActor>
    

    So, das Problem ist jetzt das folgende... am besten auch nochmal in Form von Code:

    AbstractAction<AbstractActor> aa = new WalkDownAction();
    

    Funktioniert, klar, ist ja auch direkt gegeben.

    AbstractAction<Agent> aa2 = (AbstractAction<Agent>)aa;
    

    Klappt nicht... und ich frage mich warum.
    aa ist vom Typ "AbstractAction<AbstractActor>", warum kann ich das nicht auf "AbstractAction<Agent>" casten? "AbstractActor" ist von "Agent" abgeleitet, dass sollte doch eigentlich ohne Probleme gehen.

    Die genaue Fehlermeldung ist

    Error	10	Cannot convert type 'AbstractAction<AbstractActor>' to 'AbstractAction<Agent>'
    

    Mir fällt nicht mehr ein, was ich probieren soll. Höchstens noch, dass ich den generischen Parameter bis zum Ende der Klassenhierarchie durchschleife, was ich aber eigentlich vermeiden wollte. Fällt euch noch irgendwas auf, was mir entgeht?

    Danke schonmal im voraus.

    Shelling


  • Administrator

    Lies dir mal das hier durch und ff:
    http://msdn.microsoft.com/en-us/library/ee207183.aspx

    Dies wurde ganz bewusst verhindert. Hier mal ein kurzes Beispiel wieso:

    public class Base
    {
    }
    
    public class Left
      : Base
    {
    }
    
    public class Right
      : Base
    {
    }
    
    public class Container<TValue>
    {
      public TValue Value { get; set; }
    }
    
    var containerRight = new Container<Right>();
    var containerBase = (Container<Base>)containerRight;
    containerBase.Value = new Left();
    
    Right right = containerRight.Value; // <- Würde undefiniertes Verhalten auslösen
    // Schliesslich ist in Value ein Left Objekt gespeichert, welches hier plötzlich
    // als Right Objekt interpretiert wird.
    

    Unter gewissen Umständen ist es erlaubt, allerdings muss dann eben ein Interface vorliegen, damit keine Daten gehalten werden und zudem müssen die Daten nur in eine Richtung fliessen. So kann man dann die Generics mit in oder out kennzeichnen. Aber alles weitere steht im oben erwähnten Link.

    Grüssli



  • Wow, ich bin immer wieder erstaunt, an was die Sprachentwickler alles denken. An so einen Fall habe ich gar nicht gedacht. Vielen Dank dafür 🙂


Anmelden zum Antworten