我有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
我的代码出了什么问题?有哪些替代方案?
答案 0 :(得分:18)
这是因为Message
的真实实例不是ChildMessage
,而ChildMessage
的实例是Message
。
除非myParentClass
实际使用ChildMessage
进行实例化,否则您无法使用强制转换操作符来强制转发,因为实际的基础类型为Message
。
也就是说,可以在类型上使用implicit
和explicit
强制转换运算符,因此您可以创建一个带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术语是一个绝望的丛林。)