【问题标题】:Is it really downcasting not possible? It is working fine for me真的不能垂头丧气吗?它对我来说很好用
【发布时间】:2013-07-31 03:47:10
【问题描述】:

我知道已经发布了一些与同一主题相关的问题,但我看到了不同的答案,所以我很困惑哪个答案是正确的。

在下面的链接中,人们提到不能向下转换 Convert/Cast base type to Derived type

在下面的这个链接中,人们提到只有派生类是基类的实例时才可能进行向下转换 downcast and upcast

我做了一个小实验,并使用直接转换在一个迷你项目(C#)上实现了向下转换,例如: DerivedClass dc = (DerivedClass) baseClass 没有检查 DerivedClass 是否是 BaseClass 的实例,令我惊讶的是,它运行良好,完全没有错误,为什么人们说向下转换是不可能的?

所以我的问题是,向下转换真的不可能吗?为什么人们似乎对这个话题有不同的答案?毕竟哪一个是真正的答案?有人可以更详细地解释一下吗?

示例代码:

public class Order {  }

public class PurchaseOrder : Order { // some new properties here for PurchaseOrder}

public static PurchaseOrder GetOrder()
{
    Order order = new Order();
    return (PurchaseOrder)order;
}

【问题讨论】:

  • 您在更新中发布的代码 compiles 没有错误,但是当 run 将失败并返回 InvalidCastException .
  • 我已经使用上面的代码很长时间了,我还没有看到任何错误。好奇怪……
  • 如果你真的使用 GetOrder() 之前它必须抛出 InvalidCastException。

标签: c# oop inheritance downcast


【解决方案1】:

当对象不是实际上您尝试转换为的类型的实例时,向下转换是不可能的 - 如果它只是基类的一个实例。

当它已经是派生类的实例时是可能的1。

例如,这很好:

object x = "hello";
string y = (string) x;

这里x 的值是对string 实例的引用,所以向下转换为string 没问题。

这不很好:

object x = new object();
string y = (string) x; // Bang!

这里x 的值是对object 实例的引用,因此转换失败。

编辑:您现在包含在问题中的代码就像我的 second 示例 - 您正在创建一个仅 Order 的实例并尝试将其转换为 PurchaseOrder。那是行不通的——它不是PurchaseOrder。但是,如果您像这样更改它:

public static PurchaseOrder GetOrder()
{
    Order order = new PurchaseOrder();
    return (PurchaseOrder)order;
}

... 没关系。 (这是奇怪的代码,但它可以工作。)

有关详细信息,请参阅 MSDN 中的 "Casting and type conversions"。


1 或者,如果您尝试转换为对象的 actual 类型层次结构中的某个其他接口或类。例如,这也可以:

object x = new MemoryStream();
Stream y = (Stream) x; // Stream is in the type hierarchy of MemoryStream

【讨论】:

  • 嗨,即使你在 Jon 之前发帖,你也不会得到任何 +1 :)
  • 我可以问一下为什么我的编辑被拒绝了,而你自己却支持了大致相同的编辑? : |
  • @DR:因为不适合你进行编辑——添加更多的材料而不是磨练现有的材料——而原作者可以这样做。
  • 好的,在阅读 stackoverflow.com/help/privileges/edit 后不知道这一点 - 是否有任何其他元常见问题解答材料我应该知道,所以我知道什么时候适合进行编辑?
  • @D.R.:该页面很好地涵盖了它。
【解决方案2】:

如果您确定自己的类型,则可以向下转换,这很好用:

class Base {}
class Derived : Base {}

Base b = new Derived();
Derived d = (Derived) b;

这不起作用:

class Other : Base {}

Base b = new Other();
Derived d = (Derived) b; // InvalidCastException

【讨论】:

  • 您的代码甚至不需要演员表。 b 已经是 Derived 类型,所以这根本没有意义。
  • BTW:此代码不反映原始问题中显示的代码!
  • 对不起,打错了,这里是正确的代码: class Base {} class Derived : Base {} Base b = new Base();派生 d = (派生) b;
  • 那行不通。 b 引用的对象是 Base 类型的对象,而不是 Derived 类型的对象。
猜你喜欢
  • 2010-12-04
  • 2018-10-31
  • 2019-02-13
  • 1970-01-01
  • 2010-11-04
  • 2021-12-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多