C# 这真的不可能吗?这对我来说很好

C# 这真的不可能吗?这对我来说很好,c#,oop,inheritance,downcast,C#,Oop,Inheritance,Downcast,我知道已经有一些问题与这个主题相关,但我看到了不同的答案,所以我很困惑哪个答案是正确的 在下面的链接中,人们提到了下调是不可能的 在下面的链接中,人们提到,只有当派生类是基类的实例时,才能进行向下转换 我做了一个小实验,并在一个小型项目(C#)上使用直接转换实现了向下转换,例如:DerivedClass dc=(DerivedClass)baseClass,但没有检查DerivedClass是否是baseClass的实例,令我惊讶的是,它工作正常,没有任何错误,那么为什么人们说向下转换是不可

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

在下面的链接中,人们提到了下调是不可能的

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

我做了一个小实验,并在一个小型项目(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;
}

如果您确定自己的类型,则可以进行向下投射,这很好:

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

如果您确定自己的类型,则可以进行向下投射,这很好:

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

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

当它是派生类already1的实例时,这是可能的

例如,这很好:

object x = "hello";
string y = (string) x;
这里,
x
的值是对
string
实例的引用,因此向下转换到
string
是可以的

这不好:

此处
x
的值是对
对象的实例的引用,因此强制转换失败

编辑:您现在在问题中包含的代码与我的第二个示例类似-您正在创建一个仅
Order
的实例,并尝试将其强制转换为
PurchaseOrder
。这行不通-它不是
采购订单
。但是,如果您这样更改它:

public static PurchaseOrder GetOrder()
{
    Order order = new PurchaseOrder();
    return (PurchaseOrder)order;
}
。。。很好。(这是一个奇怪的代码,但它可以工作。)

有关更多信息,请参阅MSDN中的


1,或者如果您试图转换为对象实际类型层次结构中的其他接口或类。例如,这也没关系:

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

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

当它是派生类already1的实例时,这是可能的

例如,这很好:

object x = "hello";
string y = (string) x;
这里,
x
的值是对
string
实例的引用,因此向下转换到
string
是可以的

这不好:

此处
x
的值是对
对象的实例的引用,因此强制转换失败

编辑:您现在在问题中包含的代码与我的第二个示例类似-您正在创建一个仅
Order
的实例,并尝试将其强制转换为
PurchaseOrder
。这行不通-它不是
采购订单
。但是,如果您这样更改它:

public static PurchaseOrder GetOrder()
{
    Order order = new PurchaseOrder();
    return (PurchaseOrder)order;
}
。。。很好。(这是一个奇怪的代码,但它可以工作。)

有关更多信息,请参阅MSDN中的


1,或者如果您试图转换为对象实际类型层次结构中的其他接口或类。例如,这也没关系:

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


嗨,即使你在Jon之前发布,你也没有得到任何+1:)我可以问一下,为什么我的编辑被拒绝了,而你自己做了大致相同的编辑|@D.R.:因为你不适合进行编辑-添加更多的材料,而不仅仅是磨练现有的材料-而原著作者这样做是可以的。好的,我在阅读后不知道-有没有其他我应该知道的元FAQ材料,所以我知道什么时候进行编辑是合适的?@D.R:那个页面覆盖得很好。嗨,即使你在Jon之前发表文章,你也没有得到任何+1:)我可以问一下,为什么我的编辑被拒绝了,而你自己做了大致相同的编辑|@D.R.:因为你不适合进行编辑-添加更多的材料,而不仅仅是磨练现有的材料-而原著作者这样做是可以的。好的,我在阅读后不知道-有没有其他我应该知道的元FAQ材料,所以我知道什么时候进行编辑是合适的?@D.R:那个页面覆盖得很好。你在更新中发布的代码编译没有错误,但运行时会出现
InvalidCastException
。我已经使用上面的代码很长时间了,我还没有看到任何错误。太奇怪了…如果你真的在GetOrder()抛出InvalidCastException之前使用它,那么它一定会抛出一个InvalidCastException。你在更新中发布的代码编译没有错误,但是运行时会失败,出现一个
InvalidCastException
。我已经使用上述代码很长时间了,我还没有看到任何错误。太奇怪了……如果你真的在GetOrder()抛出InvalidCastException之前使用它,你的代码甚至不需要强制转换。b已经是派生类型,因此这毫无意义。顺便说一下:此代码没有反映原始问题中显示的代码!抱歉,这是输入错误,下面是正确的代码:类Base{}class派生:Base{}Base b=new Base();派生d=(派生)b;这是行不通的。b引用的对象是Base类型的对象,而不是派生类型的对象。您的代码甚至不需要强制转换。b已经是派生类型,因此这毫无意义。顺便说一下:此代码没有反映原始问题中显示的代码!抱歉,这是输入错误,下面是正确的代码:类Base{}class派生:Base{}Base b=new Base();派生d=(派生)b;这是行不通的。b引用的对象是Base类型的对象,而不是派生类型的对象。