1

次の継承が必要です。

public class Persistent
{
    public virtual Persistent Clone() { ... }
}

public class Animal : Persistent
{
    public override Animal Clone() { ... }
}

これは、ジェネリック クラスを使用して実装できます。

public class Persistent<T>
{
    public virtual T Clone() { ... }
}

public class Animal : Persistent<Animal>
{
    public override Animal Clone() { ... }
}

ただし、Animal からさらに継承することはできません。

public class Pet : Animal
{
    public override Pet Clone() // return type is Animal
}

明らかに、これが機能するには Pet が Persistent<Pet> から派生する必要がありますが、従来の継承が必要です。残念ながら、C# は多重継承もミックスインもサポートしていません。回避策はありますか?

4

5 に答える 5

0

メソッド隠蔽あり

    public class Persistent
    {
        public Persistent Clone() { ... }
    }

    public class Animal : Persistent
    {
        public new Animal Clone() { ... }
    }

あなたのコードから、クローン作成のためにそれを行っていると思います。クローンを作成できます

public class Persistent
{
    public virtual Dictionary<string, object> GetCloneDictionary()
    {
        return //dictionary containning clonning values.
    }
    public void SetValues( Dictionary<string, object> objects)
    {
       //set values from dictionary
    }

}

public class Animal : Persistent
{
    public override Dictionary<string, object> GetCloneDictionary()
    {
        return //dictionary containning clonning values.
    }
    public override void SetValues( Dictionary<string, object> objects)
    {

    }
}

public class Animal2 : Animal
{
    public override Dictionary<string, object> GetCloneDictionary()
    {
        return //dictionary containning clonning values.
    }
    public override void SetValues( Dictionary<string, object> objects)
    {

    }
}


public class PersistentClonner<T> where T : Persistent
{
    public virtual T Clone(T obj)
    {
        obj.GetCloneDictionary();
        //create new and set values
        return //new clone
    }
}

public class AnimalClonner : PersistentClonner<Animal>
{
    public override Animal Clone(Animal obj)
    {
        obj.GetCloneDictionary();
        //create new and set values
        return //new clone
    }
}
于 2013-09-18T11:45:59.097 に答える
0

ジェネリックを使用しない簡単なソリューションを次に示します。

public class Persistent
{
    protected virtual object CloneOverride()
    {
        return new Persistent();
    }

    public Persistent Clone()
    {
        return (Persistent)CloneOverride();
    }
}

public class Animal : Persistent
{
    protected override object CloneOverride()
    {
        return new Animal();
    }

    public new Animal Clone()
    {
        return (Animal)CloneOverride();
    }
}

public class Pet : Animal
{
    protected override object CloneOverride()
    {
        return new Pet();
    }

    public new Pet Clone()
    {
        return (Pet)CloneOverride();
    }
}

良い点は、先祖のClone()メソッドを期待どおりに非表示にすることであり、パターンは常に同じです。

CloneOverride()欠点は、タイプ セーフではないため、間違いを犯しやすいことです。

(ジェネリックに関する私の他の回答も参照してください)

于 2013-09-18T11:39:03.343 に答える
0

ジェネリックを使用した簡単なソリューションを次に示します。

public abstract class Persistent<T>
{
    protected abstract T CloneOverride();

    public T Clone()
    {
        return CloneOverride();
    }
}

public class Animal : Persistent<Animal>
{
    protected override Animal CloneOverride()
    {
        return new Animal();
    }

    public new Animal Clone()
    {
        return CloneOverride();
    }
}

public class Pet : Persistent<Pet>
{
    protected override Pet CloneOverride()
    {
        return new Pet();
    }

    public new Pet Clone()
    {
        return CloneOverride();
    }
}

(ジェネリックなしの私の他の回答も参照してください)

于 2013-09-18T11:53:08.390 に答える
0

Persistent がインターフェイスではなくクラスである必要がある理由を尋ねたいと思いますが、これはあなたが望むように機能します。

public class Persistent
{
    public virtual Persistent Clone() { return null; }
}

public class Animal : Persistent<Animal>
{
    public override Animal Clone() { return null; }
}

public class Persistent<T>
{
    public virtual T Clone() { return default(T); }
}

public class Animal : Persistent<Animal>
{
    public override Animal Clone() { return null; }
}

public class Pet : Animal
{
    public new Pet Clone()
    {
        return null;
    }
}
于 2013-09-18T11:47:15.223 に答える