1

我有一个我想使用的简单克隆界面。看起来它应该编译,但它没有。我收到一条消息,说我的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();

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


也许我可以创建IObject一个抽象类并DeepClone()在那里声明。ObjectA如果我有一个实现(调用它)我需要在构造函数中设置Name之前设置Sales,而另一个实现(调用它ObjectB)我需要在构造函数中设置Sales之前设置,这似乎可能会破坏我Name的设计。

4

2 回答 2

5

正如您在问题中暗示的那样,IObject实现了 IDeepClonable< IObject >,因此它的DeepClone()方法必须 return IObject

您需要一直使用CRTP

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

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

于 2013-06-13T14:44:07.750 回答
1

因为 IObject 是继承的IDeepCloneable<IObject>,所以DeepClone会返回一个IObject. 以下应该有效:

    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 };
    }
}
于 2013-06-13T14:45:42.673 回答