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

这是一个没有泛型的简单解决方案:

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 class Persistent
{
    public virtual Persistent Clone()
    {
        return new Persistent();
    }
}

public class Animal : Persistent
{
    public new Animal Clone()
    {
        return new Animal();
    }
}

public class Pet : Animal
{

}

public class Wild : Animal
{
    public new Wild Clone()
    {
        return new Wild();
    }
}

private static void Test()
{
    var p = new Persistent().Clone();
    Console.WriteLine("Type of p: {0}", p);

    var a = new Animal().Clone();
    Console.WriteLine("Type of a: {0}", a);

    var t = new Pet().Clone();
    Console.WriteLine("Type of t: {0}", t);

    var w = new Wild().Clone();
    Console.WriteLine("Type of w: {0}", w);
}
于 2013-09-18T12:09:34.837 回答
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

尽管我会问为什么 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 回答