Simulating covariant return types in C#

This post was imported from blogspot.

For several years, Microsoft engineers have refused to add support for covariant return types, a trivially simple feature that should have been in the CLR from the beginning.

Suppose you want to write a Clone() method that returns a copy of the current object. Naturally you want to write the following, but it is illegal:
class MyStuff : ICloneable {
    public MyStuff Clone() { ... }
}

Since you are implementing an interface, you can use this workaround that uses explicit interface implementation:
class MyStuff : ICloneable {
    public MyStuff Clone() { ... }
    object ICloneable.Clone() { return Clone(); }
}

The above workaround is okay for implementing an interface, but what if you are writing a class hierarchy, and you want a Clone() method that is virtual but has the appropriate return type?
class BaseNode : ICloneable
{
    object ICloneable.Clone() { return Clone(); }
    public virtual BaseNode Clone() { ... }
}
class ComplexNode : BaseNode
{
    override BaseNode BaseNode.Clone() { return Clone(); } // Error!
    public ComplexNode Clone() { ... }
}

Oops, the workaround that you use for interfaces is illegal for class inheritance. There is still a solution, though:
class BaseNode : ICloneable
{
    object ICloneable.Clone() { return Clone(); }
    public BaseNode Clone() { BaseNode c; Clone(out c); return c; }
    protected virtual void Clone(out BaseNode clone) { ... }
}
class ComplexNode : BaseNode
{
    public new ComplexNode Clone() { ComplexNode c; Clone(out c); return c; }
    protected override void Clone(out BaseNode clone) { clone = Clone(); }
    protected virtual void Clone(out ComplexNode clone) { ... }
}

That's right. You need six Clone() methods. The last method is virtual in case you want to make a class derived from ComplexNode, e.g. VeryComplexNode:
class VeryComplexNode : ComplexNode
{
    public new VeryComplexNode Clone() { VeryComplexNode c; Clone(out c); return c; }
    protected override void Clone(out BaseNode clone) { clone = Clone(); }
    protected override void Clone(out ComplexNode clone) { clone = Clone(); }
    protected virtual void Clone(out VeryComplexNode clone) { ... }
}

Without covariant return types, you have to to define an additional virtual function for each additional derived class.