Ich schreibe ein Programm, das C# schreibt, das schließlich in eine Anwendung kompiliert wird. Ich möchte, dass jeder der generierten Typen eine "Deep Clone" -Funktion bereitstellt, die den gesamten Baum der Daten kopiert. Das heißt, ich jemand möchte in der Lage sein zu tun:Ist es möglich, das Muster "virtuelles Konstruktor" in C# ohne Umwandlungen zu implementieren?
var x = new Base(); // Base has public virtual Base DeepClone() { ... }
var y = new Derived(); // Derived overrides DeepClone
Base a = x.DeepClone();
Base b = y.DeepClone();
// Derived c = x.DeepClone(); // Should not compile
Derived d = y.DeepClone(); // Does not compile, DeepClone returns Base
statt
var x = new Base();
var y = new Derived();
Base a = x.DeepClone();
Base b = y.DeepClone();
// Derived c = x.DeepClone(); // Should not compile
Derived d = (Derived)y.DeepClone();
Allerdings ist C# nicht zulassen, dass Sie dies in einer einfachen Überschreibung tun; Die Außerkraftsetzungen müssen den gleichen Typ wie den deklarierten Typ auf der Basis zurückgeben.
Da ich Code schreibe, der sowieso boilerplate stempelt, gibt es etwas, das ich erzeugen kann, damit der erste Block kompilieren kann? Ich habe etwas wie das Folgende versucht:
abstract class Base
{
public abstract Base DeepClone();
}
class Base2 : Base
{
int Member { get; set; }
public Base2() { /* empty on purpose */ }
public Base2(Base2 other)
{
this.Member = other.Member;
}
public override Base2 DeepClone()
{
return new Base2(this);
}
}
sealed class Derived : Base2
{
string Member2 { get; set; }
public Derived() { /* empty on purpose */ }
public Derived(Derived other)
: base(other)
{
this.Member2 = other.Member2;
}
public override Derived DeepClone()
{
return new Derived(this);
}
}
aber das kompiliert nicht, weil die Überschreibungen nicht übereinstimmen. Ich habe auch versucht, die Methode von der Basis zu überschreiben und sie mit dem Schlüsselwort "new" zu verstecken, aber das hat auch nicht funktioniert.
In C# gibt es keine Möglichkeit, dass eine Klasse sich unglücklicherweise auf ihren eigenen Typ bezieht. Es gibt hacky Wege wie das seltsam wiederkehrende Vorlagenmuster, das Ihnen die Standardarbeit erspart, aber nicht idiotensicher ist. –
@Asad: Hier sind keine Generika beteiligt. –
"Es gibt keine Generika hier beteiligt" Ja, aber dieses Problem ist konzeptionell einer der Generika. Sie möchten eine 'DeepClone'-Methode, die einen beliebigen von 'Base' abgeleiteten Typ akzeptiert, einige Operationen darauf ausführt und denselben Typ zurückgibt. –