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一致。我需要一个类而不是接口来实现一些基本逻辑。