派生类中的过程不返回派生对象

本文关键字:派生 返回 对象 过程 | 更新日期: 2023-09-27 17:49:30

我在c#中有一个基类,如:

public class A{
  public A something() {
     //...
  }
}

和派生类,如:

public class B:A

当我这样做的时候:

B obj = new B();
obj = obj.something();

VS抛出错误(类似于)"A不能转换成B"它不是应该返回B而不是A吗?

更新:谢谢大家。

我把A.something(string)改成了A.something(int)。传递给它的值总是整型,所以…B类(和其他"姊妹"类)只是完整重构代码的中间步骤,因此它们将消失。

的情况是,我有4类做同样的,我改变他们为统一的一个。因此,现在需要返回"B"对象。

派生类中的过程不返回派生对象

VS抛出错误(类似于)A不能被转换成B"。它不是应该返回B而不是A吗?

因为您的父类函数something()返回类型是A,并且您正在尝试将其保存在子类引用变量obj中,如下所示:

obj = obj.something(); //something returns instance of `A`

这里的子类引用变量obj不能指向父类实例,但可以有其他方法(父类引用变量可以指向子类实例)

您应该考虑更改类中something()方法的返回类型。

  • 它应该返回void

  • 如果需要在函数

  • 中修改参数,可以通过引用传递参数。

如果需要的话,你可以重载/覆盖派生类中的方法来获得不同的行为。

现在的样子,除了reinterpret_cast之外,您可以做的不多,这将在以后引起问题

不,即使它是在基类中定义的,返回类型也不会不同,它仍然会返回一个A的实例,不一定可以转换为b。您可以这样做:

public class A{
  public virtual A something() {
     //...
  }
}
public class B:A
{
   public override A something() {
     return new B();
   }
}
B obj = new B();
obj = obj.something() as B;

当然,重写在这里并不能真正解决任何问题。你可以在基类中返回一个B,它会以同样的方式工作,但那只是尴尬。我认为您的问题是您没有遵循LISKOV替换原则:您应该能够用实现A的实例替换A的每个实例,而不会影响客户端。向下转换通常是一种代码气味。您应该将所有实例视为A,并在子类中改变行为,而不是在客户端

要么在类B中重写Something(),要么得到obj.something()的结果;