使用派生类型覆盖方法

时间:2013-09-18 11:33:47

标签: c# inheritance override

我需要以下继承:

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
}

显然宠物应来自持久性&lt;宠物&gt;为了这个工作,但我需要经典的继承。不幸的是,C#既不支持多重继承也不支持mixins。有没有解决方法?

5 个答案:

答案 0 :(得分: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()不是类型安全的。

(参见我对泛型的其他答案)

答案 1 :(得分: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
    }
}

答案 2 :(得分: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;
    }
}

答案 3 :(得分:0)

以下是一个简单的解决方案 with generics

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

(另请参阅我的其他答案,没有泛型)

答案 4 :(得分: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);
}