问题最明显的例子是函数 Clone(只是一个EXAMPLE 家伙)。假设您有 BaseClass 和 DerivedClass——除非我遗漏了什么,否则在两个函数(每个类的克隆)中,您分别创建 BaseClass 和 DerivedClass,但实际上返回对象。 如果您想使用“真实”类(class),这就是问题所在。
到目前为止,我只看到两个解决此问题的方法:
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”不切题。谢谢。
最佳答案
检查这两个问题:
基本上,处理这个问题的方法是定义一个具有适当返回类型的通用接口(interface),例如
interface ICloneable<T> {
T Clone();
}
但是,这不允许您将接口(interface)用作基类型,因为 ICloneable
让函数仅在返回类型上有所不同是“技术上可能的”,事实上 CLR 允许这样做,但 C# 不允许,这可能是因为不可能始终猜测要调用的正确重载。 (实际上,在 C# 中,您可以使用隐式转换运算符执行此操作:它们被编译为名称为 op_Implicit 且返回类型不同的函数)。
关于c# - 您如何处理具有不同类型结果的重写函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6134811/