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

时间:2014-03-10 13:35:59

标签: c# derived-class base-class

我在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(字符串),现在是A.something(int)。传递给它的值总是整数,所以...... B(以及其他“姐妹”类)只是代码完全重构的中间步骤,因此它们将消失。

案例是我有4个班级做同样的事情,我正在改变一个统一的班级。因此,现在需要返回“B”对象。

4 个答案:

答案 0 :(得分:0)

  

VS抛出错误说(类似)“A无法转换为   B“。它不应该返回B而不是A吗?

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

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

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

答案 1 :(得分:0)

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

  • 它应该返回void

  • 如果您需要在函数中修改参数,可以通过引用传递参数

这样,您可以重载/覆盖派生类中的方法,以便在需要时获得不同的行为。

现在它看起来的方式除了reinterpret_cast之外你没有什么可做的,这会在以后引起问题。

答案 2 :(得分:-1)

不,即使它在基类中定义,返回类型也不会有所不同,它仍然会返回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,并改变子类中的行为,而不是客户端中的行为

答案 3 :(得分:-2)

您必须覆盖B类中的Something()或获取obj.something()的结果;在A类的对象中。