我有一个想要使用的简单克隆界面。看起来它应该编译,但不是。我收到一条消息,说我的BObject类未实现DeepClone()。我不明白这一点,因为我有一个DeepClone()方法,而我的BObject类实现了IObject

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

interface IObject : IDeepCloneable<IObject>
{
    string Name { get; }
    double Sales { get; }
}

//'BObject' does not implement interface member
//  'IDeepCloneable<IObject>.DeepClone()'
class BObject : IObject
{
    public string Name { get; set; }
    public double Sales { get; set; }

    public BObject DeepClone()
    {
        return new BObject() { Name = this.Name, Sales = this.Sales };
    }
}


我是在声明接口错误吗?



还是DeepClone实现?我可以使用以下代码:

public IObject DeepClone() //returns an IObject instead of a BObject
{
    return new BObject() { Name = this.Name, Sales = this.Sales };
}


我的问题是没有检查BObject.DeepClone()方法是否返回BObject作为结果。我可以有一个看起来像这样的课:

class BObjectImposter : IObject
{
    public string Name { get; set; }
    public double Sales { get; set; }

    public IObject DeepClone()
    {
        //returns a BObject instead of a BObjectImposter
        return new BObject() { Name = this.Name, Sales = this.Sales };
    }
}


使用此类,我可以这样写:

BObjectImposter objImp = new BObjectImposter();
IObject copy = objImp.DeepClone();


我可能希望copyBObjectImposter的实现,但实际上是不相关的类BObject的实现,而碰巧也实现了IObject。我知道接口的意义在于我使用哪种实现都无关紧要,但这对我来说似乎不是好的代码。也许在我的BObjectImposter实现中的某个地方,我希望DeepClone()返回一个BObjectImposter对象。同样,IObject的一种实现不应依赖于IObject的另一种实现。



也许我可以将IObject设为抽象类,然后在其中声明DeepClone()。如果在构造函数中设置一个ObjectA之前需要先设置Name的实现(称为Sales),而在需要的地方实现另一个实现(称为ObjectB),这似乎可能会破坏我的设计。在构造函数中设置Sales之前先设置Name

最佳答案

正如您在问题中所暗示的那样,IObject实现IDeepClonable ,因此其DeepClone()方法必须返回IObject

您需要完全使用CRTP

interface IObject<T> : IDeepCloneable<T> where T : IObject<T>
class BObject : IObject<BObject>


(您还应该将where T : IDeepCloneable<T>添加到IDeepCloneable

关于c# - 为什么我的克隆代码无法编译?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/17089951/

10-13 06:39