【发布时间】:2011-09-02 08:25:44
【问题描述】:
这个问题最明显的例子是函数克隆(只是一个EXAMPLE家伙)。假设您有 BaseClass 和 DerivedClass ——除非我错过了什么,否则在两个函数(每个类的克隆)中,您分别创建 BaseClass 和 DerivedClass 但实际上返回了对象。 如果您想使用“真实”类,这就是问题所在。
到目前为止,我只看到两个解决此问题的方法:
1.每次将函数的结果转换为适当的类
var real_stuff = (RealStuff)x.Clone(); // I want real stuff
2. 提供第二个功能,因此您将拥有 Clone(如果您在基类级别工作)和 CloneThis(如果您想在给定班级工作,结果会因班级而异等级)
public override object Clone()
{
return CloneThis();
}
public RealStuff CloneThis()
{
return new RealStuff(this);
}
第一个很丑,第二个很烦。
问题:您如何处理这个问题?
另外一件事——如果你愿意,也请评论一下——为什么在重写函数签名检查时如此严格?除了“因为它是这样设计的”或 Eric Lippert 最喜欢的“因为每个功能都需要......”;-) 我认为允许覆盖具有更改结果类型的函数没有技术(和逻辑等)问题 IF 被覆盖的函数结果派生自原始函数结果类型。
例子:
class ClassA
{
public virtual ClassA GetIt() ...
}
class ClassB : ClassA
{
public override ClassB GetIt() ...
}
目前它不是正确的代码,但我认为它在技术上可能是,因为 ClassB 是从 ClassA 派生的。无论您对输出做什么,“接收者”都需要 ClassA,所以 ClassB 满足这个要求。
所以你可以写:
ClassA class_a_b = new ClassB();
ClassB class_b_b = new ClassB();
ClassA result1 = class_b_b.GetIt();
ClassA result2 = class_a_b.GetIt();
ClassB result3 = class_b_b.GetIt();
// incorrect, derived GetIt would be called OK,
// but the signature is taken from ClassA
ClassB result4 = class_a_b.GetIt();
我也不认为拥有这样的能力任何人都会对这种行为感到惊讶,恕我直言,这是一致的。
请保持您的回答符合主题,“您不应该使用 ICloneable”不 符合主题。谢谢。
【问题讨论】:
-
您是否考虑过一个公共虚拟 T Clone
方法,该方法可以被覆盖并在没有推断出的类型的情况下调用 Clone(myObj) ? -
@Paolo Tedesco,第二个很好,谢谢。这个问题是DUPLICATE,我该如何关闭它?
-
@macias:我还是回答了,即使我认为这在某种程度上是重复的,因为我想添加一些东西(关于转换为基本接口和隐式转换运算符)。但是,我认为您不能关闭自己的问题(人们必须投票才能关闭)。
-
我相信你可以删除自己的问题,当然我已经按照一些链接找到“作者自愿删除了这个问题”或类似的内容。
标签: c# polymorphism overriding