I'm writing a program that writes C# that eventually gets compiled into an application. I would like each of the generated types to provide a "deep clone" function which copies the entire tree of data. That is, I want someone to be able to do:
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
instead of
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();
However, C# doesn't allow you to do this in a simple override; the overrides must return the same type as the declared type on the base.
Since I'm writing code that stamps out boilerplate anyway, is there something I can generate to allow the first block to compile? I tried something similar to the following:
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);
}
}
but this does not compile because the overrides don't match. I also tried overriding the method from the base and hiding it with the "new" keyword, but this didn't work either.