Is it possible to have a base class with a return type that adjusts to the type of the base class?

StackOverflow https://stackoverflow.com/questions/1246859

  •  12-09-2019
  •  | 
  •  

Question

Basically my setting is this:

public abstract class BaseObject{
    public abstract BaseObject Clone();
}

public class DerivedObject : BaseObject{
    public DerivedObject Clone()
    {
        //Clone logic
    }
}

The above code doesn't compile because it isn't possible to change the return type when overriding a method.

Is it possible to achieve that every derived type's Clone method returns an argument of it's own type (maybe through generics)?

Was it helpful?

Solution

Well, C# doesn't allow covariant return types as you've found... but you can use generics:

public abstract class BaseObject<T> where T : BaseObject<T>
{
    public abstract T Clone();
}

public class DerivedObject : BaseObject<DerivedObject>
{
    public override DerivedObject Clone()
    {
         // ...
    }
}

This solution can be a pain in various ways - not least because it's hard to understand - but it can work reasonably well in many situations.

EDIT: The reason I've included the constraint on T is so that BaseObject can call "its own" methods on instances of T, which is usually very handy. If you don't need this though, you can lose the constraint.

OTHER TIPS

You can do something like this. Instead of returning default(T), return something based on the cloning logic.

public class MyBase<T>
{
    public T Clone()
    {
        return default(T);
    }
}

public class MyDerived : MyBase<MyDerived>
{
}

By the way, for object cloning I like to serialize the current object to memory using the binary serializer, then deserialize that memory back into a new instance.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top