派生类中的过程不返回派生对象
本文关键字:派生 返回 对象 过程 | 更新日期: 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
-
如果需要在函数
中修改参数,可以通过引用传递参数。
如果需要的话,你可以重载/覆盖派生类中的方法来获得不同的行为。
不,即使它是在基类中定义的,返回类型也不会不同,它仍然会返回一个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()的结果;