1

我有一堂课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.

我在想我可以为它创建一个新的构造函数OrderRecord但是我已经有了这个对象(它是通过从数据库中获取一条记录来构建的)。

我怎样才能正确实施呢?

4

4 回答 4

5

如果你得到一个InvalidCastExceptionthentheRecord不是 anOrder并且你不能施放它。只有当它被创建OrderOrder.

我的猜测是,从数据库中获取数据的任何东西都会Record在它可以创建时创建 a Order(并将其返回为 a 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;
}
于 2013-09-09T14:52:34.223 回答
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
于 2013-09-09T14:55:05.953 回答
0

在实际尝试强制转换之前,您可以使用isandas运算符来确保它属于某种类型,如下所示:

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

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

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

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

于 2013-09-09T15:00:50.213 回答
0

您必须转换为新对象,而不是强制转换它。要做到这一点而无需一次编写一个属性的映射代码,最简单的方法是序列化Record对象,然后将其反序列化为Order. 您可以使用任何您喜欢的序列化技术(XmlSerializer、、、JavaScriptSerializerJSON.NET 等)。

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

于 2013-09-09T15:01:40.060 回答