将对象从派生类转换为对象

时间:2013-09-09 14:49:48

标签: c# oop

我有一个工作正常的课程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的新构造函数,但我已经拥有了该对象(通过从数据库中获取记录来构建)。

我怎样才能正确实现?

4 个答案:

答案 0 :(得分:5)

如果您获得InvalidCastException,那么theRecord不是Order而您无法投放它。如果它是作为OrderOrder的子类创建的,则只能将其强制转换。

我的猜测是,无论从数据库中获取数据,只要它可以创建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)

您可以使用isas运算符在实际尝试投射之前确定某些类型是某种类型的,例如:

Record objectToHoldCastedObject;
if(theRecord is Order)
{
    objectToHoldCastedObject = theRecord as Order;
}

is将检查对象是否是确切类型或是继承链的一部分。

as将尝试将对象强制转换为该类型,如果不能,则它将返回null而不是异常。

注意:as仅适用于引用类型,而不适用于值类型;而is将适用于引用类型和值类型。因此,您可以is一个整数,但不能as整数,例如。

答案 3 :(得分:0)

你必须转换成一个新对象,而不是转换它。要在不将映射代码一次写入一个属性的情况下执行此操作,最简单的方法是序列化Record对象,然后将其反序列化为Order。您可以使用您喜欢的任何序列化技术(XmlSerializerJavaScriptSerializer,JSON.NET等。)

这假设所有数据都可以使用普通的getter / setter在公共属性中访问(在您的示例中不是这样,但您应该这样做)。如果您不想这样做,可以使用反射循环遍历Record的字段,从中获取值,并使用反射填充Order的字段。