C# 派生类中的过程不';t返回派生对象

C# 派生类中的过程不';t返回派生对象,c#,derived-class,base-class,C#,Derived Class,Base Class,我有一个C语言的基类,比如: 和一个派生类,如: public class B:A 当我这样做时: B obj = new B(); obj = obj.something(); VS抛出一个错误,说“A不能转换为B”。它不是应该返回B而不是A吗 更新: 谢谢大家 我更改了A.something(字符串),现在是A.something(int)。传递给它的值总是整数,所以。。。B(和其他“姐妹”类)只是代码完全重构的中间步骤,因此它们将消失 情况是,我有4个类做同样的事情,我把它们改成了一个

我有一个C语言的基类,比如:

和一个派生类,如:

public class B:A
当我这样做时:

B obj = new B();
obj = obj.something();
VS抛出一个错误,说“A不能转换为B”。它不是应该返回B而不是A吗

更新: 谢谢大家

我更改了A.something(字符串),现在是A.something(int)。传递给它的值总是整数,所以。。。B(和其他“姐妹”类)只是代码完全重构的中间步骤,因此它们将消失


情况是,我有4个类做同样的事情,我把它们改成了一个统一的类。因此现在需要返回“B”对象。

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

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;
当然,这里的覆盖并不能真正解决任何问题。您可以在基类中返回a
B
,它的工作方式也是一样的,但这太尴尬了。 我认为您的问题在于您没有遵循LISKOV替换原则:您应该能够用实现
A
的实例替换
A
的每个实例,而不会影响客户端。一般来说,向下投射是一种代码气味。您应该将所有实例视为
A
,并改变子类中的行为,而不是客户端中的行为

VS抛出一个错误,说“A不能转换为” B”。它不是应该返回B而不是A吗

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

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

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

要么必须重写类B中的某物(),要么获取obj.Something()的结果;在类的对象中,

您应该考虑在类中更改<代码>的返回类型(<)> />代码>方法。p>
  • 它应该是无效的

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

这样,如果需要,可以重载/重写派生类中的方法以获得不同的行为


从现在的外观来看,除了重新解释转换(这将在以后导致问题)之外,您无能为力。

因为您的函数something()返回类型是
a
,并且您不能将父成员保存在child中,但可以以其他方式保存(父引用变量可以指向子类实例)是可能的。看起来你正在尝试实现工厂方法模式,看看这个:我认为
覆盖
应该是
覆盖
可能是一个输入错误:)我正在工作中重构一个项目中的类,这太乱了,我不得不做一些奇怪的妥协(想象一个类有20个变量和一个名称()它会手动返回名称。或者是一个在其外部带有返回“”的开关大小写,这样“编译器不会抛出错误”。这也在代码中)。最终的代码应该更简洁,但这个解决方案是临时的)。重写并不能解决他的问题。返回类型仍然是
A
obj = obj.something(); //something returns instance of `A`