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()私が抱えている問題は、メソッドが結果として a を返すことを確認していない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を期待しています。また、IObject の 1 つの実装は、IObject の別の実装に依存するべきではありません。DeepClone()BObjectImposter


たぶんIObject、抽象クラスを作成しDeepClone()てそこで宣言できます。ObjectAこれは、コンストラクターで設定する前に設定する必要がある実装 ( と呼ぶ) と、コンストラクターでName設定する前に設定する必要がSalesある別の実装 ( と呼ぶObjectB) がある場合、設計が壊れる可能性があるようです。SalesName

4

2 に答える 2

5

質問で示唆したように、IObjectIDeepClonable< IObject > を実装しているため、そのDeepClone()メソッドは を返す必要があり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>されているためDeepCloneIObject. 以下が機能するはずです。

    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 に答える