c# - 您如何处理具有不同类型结果的重写函数?

标签 c# polymorphism overriding

问题最明显的例子是函数 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 和 ICloneable 是两个不同的东西。

让函数仅在返回类型上有所不同是“技术上可能的”,事实上 CLR 允许这样做,但 C# 不允许,这可能是因为不可能始终猜测要调用的正确重载。 (实际上,在 C# 中,您可以使用隐式转换运算符执行此操作:它们被编译为名称为 op_Implicit 且返回类型不同的函数)。

关于c# - 您如何处理具有不同类型结果的重写函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6134811/

相关文章:

c# - 为不可修改的类型实现类似 IConvertible 的功能

C++ 函数重写

javascript - Typescript 中的抽象内部类

c++ 将 vector<Inherited*> 转换为 vector<abstract*>

java - 数组列表中的子类元素不会使用 Java 中的重写方法

python - 继承:更改子方法的签名

javascript - 网络表格 : add dynamically in javascript option to a dropdownlist

c# - 如何使用 ReactiveUI 在 ViewModel 停用时正确取消任务?

c# - web api .net 核心获取 nginx connect() 失败 (111 : Connection refused)

Android Linkify 链接 textColor 被忽略,css 样式是否可以覆盖?