ConditionRacer
ConditionRacer

Reputation: 4498

Why doesn't this method invocation invoke the derived class?

I have an interface IDeepCloneable, that I'm using to implement generic deep copying. I have a base class and a derived class as well, each implementing IDeepCloneable. I'm running into issues with derived classes.

Here is the code:

public class Program
{
    public static void Main()
    {
        var a = new BaseClass();
        var ac = a.DeepClone();

        var b = (BaseClass)(new DerivedClass());
        var bc = b.DeepClone();
    }
}

public interface IDeepCloneable<T>
{
    T DeepClone();
}

public class BaseClass : IDeepCloneable<BaseClass>
{
    public string Value { get; set; }

    public BaseClass(){}
    public BaseClass(BaseClass copy)
    {
        Value = copy.Value;
    }

    public BaseClass DeepClone()
    {
        Console.WriteLine("BLAH1");
        return new BaseClass(this);
    }
}

public class DerivedClass : BaseClass, IDeepCloneable<DerivedClass>
{
    public string SomeOtherValue { get; set; }

    public DerivedClass(){}
    public DerivedClass(DerivedClass copy)
        : base(copy)
    {
        SomeOtherValue = copy.SomeOtherValue;
    }

    public new DerivedClass DeepClone()
    {
        Console.WriteLine("BLAH2");
        return new DerivedClass(this);
    }
}

This outputs:

BLAH1
BLAH1

I understand why it outputs BLAH1 twice, I'm just not sure how to fix it..

Upvotes: 1

Views: 63

Answers (2)

John Feminella
John Feminella

Reputation: 311476

Your derived class needs to override the DeepClone() method, and your DeepClone method in the base class needs to be virtual.

Right now, your DeepClone method in the derived class is unrelated (other than having the same name) to the base class. See Interface Implementation Inheritance in the C# standard.

That said, it looks like you're trying to do deep copies. Have you considered using a BinaryFormatter to serialize and de-serialize your data?

Upvotes: 2

Steve
Steve

Reputation: 11963

since that base class or yours implements the interface already, so you can either make the base class's DeepClone method as virtual and override it, or you can do

public abstract class BaseClass : IDeepCloneable<T>
...
public abstract T DeepClone(){}

and in your DerivedClass do

public class DerivedClass : BaseClass<DerivedClass>

Upvotes: 1

Related Questions