简体   繁体   English

为什么我的克隆代码无法编译?

[英]Why doesn't my clone code compile?

I have this simple clone interface that I'd like to use. 我有一个想要使用的简单克隆界面。 It looks like it should compile, but it doesn't. 看起来它应该编译,但不是。 I get a message saying that my BObject class doesn't implement DeepClone() . 我收到一条消息,说我的BObject类未实现DeepClone() I don't understand this because I have a DeepClone() method and my BObject class implements IObject . 我不明白这一点,因为我有一个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 };
    }
}

Am I declaring my interfaces wrong? 我在声明接口错误吗?


Or maybe the DeepClone implementation? 还是DeepClone实现? I could use this code: 我可以使用以下代码:

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

The problem I have is that there's no check that the BObject.DeepClone() method returns a BObject as a result. 我的问题是没有检查BObject.DeepClone()方法是否返回BObject作为结果。 I could have a class that looks like this: 我可以有一个看起来像这样的课:

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 };
    }
}

Using this class, I could write this: 使用此类,我可以这样写:

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

I might expect that copy is an implementation of BObjectImposter , but it's actually an implementation of an unrelated class BObject that happens to also implement IObject . 我可能希望该copyBObjectImposter的实现,但实际上是不相关的类BObject的实现,而该类恰好也实现了IObject I understand that the point of interfaces is that it shouldn't matter which implementation I use, but this doesn't seem like good code to me. 我知道接口的意义在于我使用哪种实现都无关紧要,但这对我来说似乎不是好的代码。 Maybe somewhere in my BObjectImposter implementation I expect DeepClone() to return a BObjectImposter object. 也许在我的BObjectImposter实现中的某个地方,我希望DeepClone()返回一个BObjectImposter对象。 Also, one implementation of IObject shouldn't depend on another implementation of IObject. 同样,IObject的一种实现不应依赖于IObject的另一种实现。


Maybe I could make IObject an abstract class and declare DeepClone() there. 也许我可以将IObject DeepClone()抽象类,然后在其中声明DeepClone() This seems like it might break my design if I have one implementation (call it ObjectA ) where I need to set Name before setting Sales in the constructor, and another implementation (call it ObjectB ) where I need to set Sales before setting Name in the constructor. 如果我有一个实现(称为ObjectA ),需要在构造函数中设置Sales之前先设置Name ,而另一个实现(称为ObjectB ),则需要在其中设置Name之前设置Sales ,这似乎可能会破坏我的设计。构造函数。

As you've hinted at in your question, IObject implements IDeepClonable< IObject >, so its DeepClone() method must return IObject . 正如您在问题中所暗示的那样, IObject实现了IDeepClonable < IObject >,因此其DeepClone()方法必须返回IObject

You need to use the CRTP all the way: 您需要完全使用CRTP

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

(you also ought to add where T : IDeepCloneable<T> to IDeepCloneable ) (你也应当添加where T : IDeepCloneable<T>IDeepCloneable

Its because IObject is inheriting IDeepCloneable<IObject> so DeepClone will return an IObject . 这是因为IObject继承了IDeepCloneable<IObject>所以DeepClone将返回IObject The following should work: 以下应该工作:

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

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

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

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM