Ich habe dieses Setup, und es hat nicht funktioniert, wie ich erwartet hatte. Es scheint mir, dass ein generisches T in einer Basisklasse nicht dasselbe ist wie das generische T in seiner Unterklasse.C# und Vererbungskette von mehreren Typen mit Generics
namespace StackOverflowQuestion
{
public class Poco1
{
public string Data { get; set; }
}
public class Poco2 : Poco1
{
public string ExtraData { get; set; }
}
public class Poco3 : Poco2
{
public string EvenMoreData { get; set; }
}
public class Base<T> where T: Poco1
{
public virtual void Method(T parameter)
{
// Do something even more general with Data...
parameter.Data = "Test";
}
}
public class FirstLevel<T> : Base<Poco2> where T:Poco2
{
public override void Method(Poco2 parameter)
{
// Do something general with ExtraData...
base.Method(parameter);
}
}
public class SecondLevel<T> : FirstLevel<Poco3> where T: Poco3
{
public override void Method(Poco2 parameter) // <-- Why not Poco3?
{
// Do something with EvenMoreData...
base.Method(parameter);
}
}
}
Was ich eigentlich war zu erwarten, dass die Method
Überschreibung in Art SecondLevel<T>
Poco3
sagen sollte und nicht Poco2
. Zumal ich eine Einschränkung für T auf den Typ Poco3
gesetzt habe.
Kann dies auf andere Weise erreicht werden? Es scheint mir, dass die generische T nicht "" überschrieben werden kann, wie ich wollte. Ich vermute T in Base<T>
ist nicht das gleiche wie T in FirstLevel<T>
und dass T in FirstLevel<T>
ist nicht das gleiche wie T in SecondLevel<T>
?
Wenn SecondLevel<T>
erbt von Base<T>
dann bekomme ich Poco3
im Method
überschreiben, aber nicht, wenn ich von FirstLevel<T>
erben.
Ich kann mit diesem Problem leben, aber dann muss ich den poco-Parametertyp in Level-Typ-Unterklassen (ab Level 2 und höher). Meiner Meinung nach sollte das unnötig sein, solange ich die Beschränkung festlege. Aber, natürlich, könnte es einen guten Grund für dieses Verhalten geben, das ich im Moment nicht sehe.
Verwenden Sie diese Signatur für alle erbenden Typen: öffentliche Überschreibung void Methode (T-Parameter) – AndyJ
@AndyJ Du bist mein Held! Natürlich, warum habe ich das nicht gesehen? Wenn Sie meinen Code einfügen und jede Poco-Referenz (außer in den Constraints) durch T ersetzen, werde ich das sofort als Antwort markieren :) – Frode