将父类强制转换为子类

时间:2012-03-07 08:58:19

标签: c# .net casting

我有Message类,我已经扩展并添加了新属性。

class ChildMessage: Message 
{
prop...
}

在尝试将Message Class添加到ChildMessage列表时,我获得了添加类的Null引用。

var myChildList =new List<ChildMessage> ();
var myParentClass = new Message();
myChildList.add(myParentClass as ChildMessage)

myChildList[0] == null //Always return null 

我的代码出了什么问题?有哪些替代方案?

4 个答案:

答案 0 :(得分:18)

这是因为Message的真实实例不是ChildMessage,而ChildMessage的实例是Message

除非myParentClass 实际使用ChildMessage进行实例化,否则您无法使用强制转换操作符来强制转发,因为实际的基础类型为Message

也就是说,可以在类型上使用implicitexplicit强制转换运算符,因此您可以创建一个带Message并输出ChildMessage的运算符。

http://msdn.microsoft.com/en-us/library/85w54y0a.aspx


知道你有这些类型,你别无选择,只能使用它们,你有两个选择来扩展这种类型。

第一个选项

使用装饰器/包装器模式将Message包裹在ChildMessage内:

class ChildMessage
{
    private Message _innerMessage;

    public ChildMessage(Message innerMessage)
    {
        _innerMessage = innerMessage;
    }
}

然后,您通过Message类公开ChildMessage或其属性。

第二个选项

这是可行的,继承自Message,但是当您想要从ChildMessage创建Message时,您需要转换它 ,不是投了它:

class ChildMessage : Message
{
    public ChildMessage(Message m)
    {
        // Instantiate properties by copying from m
    }
}

答案 1 :(得分:3)

我认为你以某种方式得到了错误的方式 - 通常你可能想要这样的东西:

var myList =new List<Message> ();
var myChildObject = new ChildMessage();
myList.add(myChildObject)

myList[0] as ChildMessage == null // should not return null

答案 2 :(得分:2)

如果您以这种方式更改代码

var myChildList =new List<Message> (); 
var myChildClass = new ChildMessage(); 
myChildList.add(myChildClass as Message) 

现在您有一个List,其中对象的类型为ChildMessage或 从Message派生的其他类型。 您可以在以后使用列表中存储的对象时检查正确的类型。

答案 3 :(得分:2)

对象上的强制转换不能用于更改其类型:它不是转换。 它仅用于告诉对象的类型:您解释了您希望将该对象用作该类型的对象;并且该对象必须已经是该类型,否则您将收到错误(至少使用C#等正确的语言)。

转换对象很有意义,因为由于继承,对象可能同时具有多种类型。

在您的代码中,每个ChildMessage都是Message,但您创建的Message不是ChildMessage,因此尝试使用它们会失败。< / p>

相比之下,从整数到实数的“强制转换”,反之亦然,实际上可能是转换。 (IT术语是一个绝望的丛林。)