在多个基类上实现复制/深度复制

时间:2014-07-09 10:03:16

标签: c# inheritance copy polymorphism

不确定这可能是一个codeReview帖子,但我们在这里:

我的目标是重新实现在应用程序中复制对象的方式。我们有多个基类:

CoreList<T> // for all list classes
BasicReference // for all reference classes
CoreObject // for all "normal" domain objects

所有类都继承自这些基类。现在,复制方法在CoreObject类上实现,并将通过反射遍历对象树,查看每个属性类型并选择正确的方式来复制类型,最后总是返回CoreObject。 / p>

我不喜欢这种方法的问题,这就是为什么我要改变它:

  • 复制域对象后,您总是需要将其转换为&#34;返回&#34;到原始类型,例如:Animal = animal.Copy() as Animal;
  • 复制每种类型的所有逻辑都在CoreObject类中,即使它不应该知道其他基类。

所以我的第一次尝试是介绍一个界面:

public interface IObjectCopy<out T>
{
  T Copy();
}

然后应该在所有基类上实现。然后每个班级负责复制的方式。例如(伪代码):

public class CoreObject : IObjectCopy<CoreObject>
{
  public virtual GerCoreObject Copy() 
  { 
    foreach (var prop in properties)
    {
      if (prop.IsNoSimpleType)
      {
        (prop as IObjectCopy).Copy()
    }
  }
}

这解决了复制责任问题,此外,继承的类可以自己处理复制逻辑。

不幸的是,这并没有解决返回类型,我仍然需要将它转换为正确的类型。我没有想到一个更好的解决方案来解决这个问题。有什么想法吗?

2 个答案:

答案 0 :(得分:1)

可以使用covariant return types在OO中解决此问题。不幸的是,C#不支持协变返回类型,如Java和C ++,要求它始终打破类型安全。

在C#中没有打破类型安全(铸造),遗憾的是这是不可能的。

以下是两种可能的选择:

//explicit interface implementation
public class Animal : CoreObject, IObjectCopy<Animal>
{
    Animal IObjectCopy<Animal>.Copy()
    {
        return (Animal) base.Copy();
    }
}
//does not require an explicit cast
IObjectCopy<Animal> animalCopy = myAnimal;
Animal copiedAnimal = animalCopy.Copy();

//second option: shadow the original method and cast inside the object
public class Animal : CoreObject, IObjectCopy<Animal>
{
    public new Animal Copy()
    {
        return (Animal) base.Copy();
    }
}
Animal copy = myAnimal.Copy();

使用有限量化的另一种选择:

public class CoreObject : IObjectCopy<CoreObject>
{
    public CoreObject Copy()
    {
        return Copy<CoreObject>();
    }

    protected T Copy<T>()
        where T : CoreObject, new()
    {
        T t = new T();
        //implement copy logic:
        return t;
    }
}

public class Animal : CoreObject, IObjectCopy<Animal>
{
    public new Animal Copy()
    {
        return Copy<Animal>();
    }
}

答案 1 :(得分:1)

如果我理解正确,您需要Curiously recurring template pattern

public class BaseClass<T> where T : BaseClass<T>
{
     public virtual T Clone()
     {
         // Perform cloning with reflection.
         return clone as T;
     }
}

然后你只需将你的班级定义为:

public class EndObject : BaseClass<EndObject>
{
}

EndObject e;
e.Clone() // Will return EndObject type