我有一个工作正常的课程Record
:
public class Record
{
protected string table;
protected string idcolumn;
public Record(string _table, string _idcol, int _id)
{
table = _table;
idcolumn = _idcol;
Id = _id;
}
}
我还有一个派生自Order
的类Record
,它实现了额外的方法,仅适用于某种类型的记录:
class Order : Record
{
public void Start()
{
}
}
在我的应用程序中,我有一个类型为theRecord
的对象Record
我想要转换为Order
,以便我可以在其上调用Start
方法。
我试图施展它:
Order r = (Order)theRecord;
但会引发InvalidCastException
。
我在想我可以为Order
创建一个带Record
的新构造函数,但我已经拥有了该对象(通过从数据库中获取记录来构建)。
我怎样才能正确实现?
答案 0 :(得分:5)
如果您获得InvalidCastException
,那么theRecord
不是Order
而您无法投放它。如果它是作为Order
或Order
的子类创建的,则只能将其强制转换。
我的猜测是,无论从数据库中获取数据,只要它可以创建Record
(并将其作为Order
返回),就会创建Record
。类似的东西:
public Record Fetch(int id)
{
// ... get data from db
Record rec;
if(data.Type = "Order")
rec = new Order();
else
rec = new Record();
return rec;
}
答案 1 :(得分:4)
正如我在评论中所说的
你可以将狗投入动物而不是动物投入狗(除非该动物是狗)。更清晰的所有狗都是动物,但不是所有动物都是狗
Record record = new Record();
Order order = (Order)record;//wont work since record is some record not an Order
为了让它发挥作用你必须做这样的事情
Record record = new Order();
然后你可以像这样投射
Order order = (Order)record;//works since record is Order
答案 2 :(得分:0)
您可以使用is
和as
运算符在实际尝试投射之前确定某些类型是某种类型的,例如:
Record objectToHoldCastedObject;
if(theRecord is Order)
{
objectToHoldCastedObject = theRecord as Order;
}
is
将检查对象是否是确切类型或是继承链的一部分。
as
将尝试将对象强制转换为该类型,如果不能,则它将返回null而不是异常。
注意:as
仅适用于引用类型,而不适用于值类型;而is
将适用于引用类型和值类型。因此,您可以is
一个整数,但不能as
整数,例如。
答案 3 :(得分:0)
你必须转换成一个新对象,而不是转换它。要在不将映射代码一次写入一个属性的情况下执行此操作,最简单的方法是序列化Record
对象,然后将其反序列化为Order
。您可以使用您喜欢的任何序列化技术(XmlSerializer
,JavaScriptSerializer
,JSON.NET等。)
这假设所有数据都可以使用普通的getter / setter在公共属性中访问(在您的示例中不是这样,但您应该这样做)。如果您不想这样做,可以使用反射循环遍历Record
的字段,从中获取值,并使用反射填充Order
的字段。