C# 使用派生类型重写方法

C# 使用派生类型重写方法,c#,inheritance,overriding,C#,Inheritance,Overriding,我需要以下遗产: 公共类持久化 { 公共虚拟永久性克隆(){…} } 公营动物:持久性 { 公共覆盖动物克隆(){…} } 这可以使用泛型类实现: 公共类持久化 { 公共虚拟T克隆(){…} } 公营动物:持久性 { 公共覆盖动物克隆(){…} } 然而,从动物身上进一步遗传并不起作用: 公共级宠物:动物 { public override Pet Clone()//返回类型为Animal } 显然,Pet应该派生自Persistent,这样才能工作,但我需要经典继承。不幸的是,C#既不支

我需要以下遗产:

公共类持久化
{
公共虚拟永久性克隆(){…}
}
公营动物:持久性
{
公共覆盖动物克隆(){…}
}
这可以使用泛型类实现:

公共类持久化
{
公共虚拟T克隆(){…}
}
公营动物:持久性
{
公共覆盖动物克隆(){…}
}
然而,从动物身上进一步遗传并不起作用:

公共级宠物:动物
{
public override Pet Clone()//返回类型为Animal
}

显然,Pet应该派生自Persistent,这样才能工作,但我需要经典继承。不幸的是,C#既不支持多重继承,也不支持混合。有什么解决办法吗?

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

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();
    }
}
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();
    }
}
好的一点是,您可以像预期的那样隐藏祖先
Clone()
方法,并且模式总是相同的

缺点是很容易出错,因为
CloneOverride()
不是类型安全的

(另请参见我关于泛型的另一个答案)

关于方法隐藏

    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
    }
}
公共类持久化
{
公共虚拟词典GetCloneDictionary()
{
返回//包含克隆值的字典。
}
公共void集合值(字典对象)
{
//从字典中设置值
}
}
公营动物:持久性
{
公共覆盖字典GetCloneDictionary()
{
返回//包含克隆值的字典。
}
公共覆盖无效集合值(字典对象)
{
}
}
公共类动物2:动物
{
公共覆盖字典GetCloneDictionary()
{
返回//包含克隆值的字典。
}
公共覆盖无效集合值(字典对象)
{
}
}
公共类PersistentClonner,其中T:Persistent
{
公共虚拟T克隆(T obj)
{
obj.GetCloneDictionary();
//创建新值并设置值
return//newclone
}
}
公共级动物克隆人:PersistentClonner
{
公共覆盖动物克隆(动物对象)
{
obj.GetCloneDictionary();
//创建新值并设置值
return//newclone
}
}

尽管我想问为什么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;
    }
}
公共类持久化
{
公共虚拟持久性克隆(){return null;}
}
公营动物:持久性
{
公共覆盖动物克隆(){return null;}
}
公共类持久化
{
公共虚拟T克隆(){返回默认值(T);}
}
公营动物:持久性
{
公共覆盖动物克隆(){return null;}
}
公营宠物:动物
{
公共新宠物克隆()
{
返回null;
}
}

这里有一个简单的解决方案和泛型

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();
    }
}
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();
    }
}
公共抽象类持久化
{
受保护抽象T CloneOverride();
公共T克隆()
{
返回CloneOverride();
}
}
公营动物:持久性
{
受保护的动物克隆覆盖物()
{
归还新动物();
}
公共新动物克隆()
{
返回CloneOverride();
}
}
公营宠物:持久
{
受保护的超控Pet CloneOverride()
{
归还新宠物();
}
公共新宠物克隆()
{
返回CloneOverride();
}
}
(另请参见我没有泛型的其他答案)

这有帮助吗

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

Persistent
在这里有什么用处?不清楚。您可以使用C#的方法隐藏功能。为此,您甚至不需要重写该方法。在重写的方法中,您仍然可以使用动物而不是Pet,尽管您返回了Pet的实例。唯一的问题是你必须在呼叫的地方将其键入并返回给宠物。@PaoloTedesco:我相信它不是重复的,因为引用没有扩展到泛型类的直接后代之外,但是我没有仔细检查过。
((持久)myAnimal).Clone()
,你会得到一个<代码>持久性,而不是
动物
不,克隆方法只是一个例子。谢谢。在经典继承下,我的意思是宠物应该默认继承动物的行为。在你的例子中,对象类型可以替换为持久的,这样更安全。无论如何,新的修饰符会破坏多态性,例如,如果从Persistent的虚拟方法中调用[this.]Clone(),则该方法将始终调用Persistent的Clone()。编辑:Clone()实际上可能具有更多逻辑。在这里,我试图避免强制转换,否则将在重写中使用持久返回类型。这在直接调用Clone()时有效,但在任何类的虚拟方法中无效。感谢Herman的输入。让我更好地理解这一点。如果您调用Pet.Clone(),请提供一个类似于上述代码中的示例场景。您希望返回Pet对象吗?我希望持久性实例具有用于存储、克隆、序列化等的方法。事实上,持久性类有太多的方法和太多的子体,无法以这种方式重写。它很乏味,而且违反了DRY原则,因为除了参数和返回类型之外,整个层次结构的实现基本上是相同的。我可以在任何地方使用基类,比如在Object.Equals()中,但我想知道是否有更好的方法来避免双重施法。这似乎有点不规则,因为Pet在特定于T的方法上不如Animal一致。我需要一个类而不是接口来实现一些基本逻辑。