[英]Cast an object into an object from a derived class
I have a class Record
that works fine: 我有一个很好的班级
Record
:
public class Record
{
protected string table;
protected string idcolumn;
public Record(string _table, string _idcol, int _id)
{
table = _table;
idcolumn = _idcol;
Id = _id;
}
}
I also have a class Order
that is derived from Record
, that implements extra methods, only applicable on a certain type of record: 我也有一个从
Record
派生的Order
类,该类实现了额外的方法,仅适用于某种记录类型:
class Order : Record
{
public void Start()
{
}
}
In my application, I have an object theRecord
of type Record
that I want to cast to Order
, so that I can call the Start
method on it. 在我的应用程序中,我有一个想要转换为
Order
Record
类型的对象theRecord
,以便可以在其上调用Start
方法。
I tried to cast it: 我试图投下:
Order r = (Order)theRecord;
but that throws an InvalidCastException
. 但这会引发
InvalidCastException
。
I am thinking that I could create a new constructor for Order
that takes a Record
, but I already have the object (which is built by fetching a record from the database). 我在想可以为
Order
创建一个带有Record
的新构造函数,但是我已经有了对象(通过从数据库中获取记录来构建该对象)。
How could I implement this correctly? 我该如何正确实施?
If you get an InvalidCastException
then theRecord
is not an Order
and you can't cast it. 如果收到
InvalidCastException
则theRecord
不是Order
,则无法InvalidCastException
。 You could only cast it if it were created as an Order
or a subclass of Order
. 您只能投它,如果它被作为创建
Order
或子类Order
。
My guess is that whatever fetches the data from the database creates a Record
when it could create an Order
(and return it as a Record
). 我的猜测是,无论从数据库中提取数据创建一个
Record
时,它可以创建一个Order
(并返回它作为一个Record
)。 Something like: 就像是:
public Record Fetch(int id)
{
// ... get data from db
Record rec;
if(data.Type = "Order")
rec = new Order();
else
rec = new Record();
return rec;
}
As I said in comments 正如我在评论中所说
You can cast a Dog to Animal but not Animal to Dog(unless that animal is Dog).
您可以将一只狗投向动物,但不能将动物投向狗(除非该动物是狗)。 More clearer All Dogs are Animal but not all Animals are Dogs
更清晰所有的狗都是动物,但并非所有的动物都是狗
Record record = new Record();
Order order = (Order)record;//wont work since record is some record not an Order
To make it work you've to do something like this 要使其正常工作,您必须执行以下操作
Record record = new Order();
Then you can cast it like this 然后你可以像这样投
Order order = (Order)record;//works since record is Order
You can use the is
and as
operators to make sure something is of a certain type before actually trying to cast it, like this: 您可以使用
is
和as
运算符在实际尝试进行强制转换之前确保某种类型的东西,如下所示:
Record objectToHoldCastedObject;
if(theRecord is Order)
{
objectToHoldCastedObject = theRecord as Order;
}
The is
will check to see if the object is that exact type or is part of the inheritance chain. is
将检查对象是否为该确切类型或是否属于继承链。
The as
will attempt to cast the object to the type, if it cannot then it will return null instead of an exception. as
将尝试将对象转换为类型,如果不能,则它将返回null而不是异常。
Note: as
will only work on reference types, not value types; 注意:
as
仅适用于引用类型,不适用于值类型; while is
will work on both reference types and value types. while
is
同时适用于引用类型和值类型。 So you can is
an integer, but not as
an integer, for example. 所以,你可以
is
一个整数,而不是as
一个整数,例如。
You'll have to convert into a new object, rather than cast it. 您将不得不转换为新对象,而不是强制转换它。 To do this without writing the mapping code one property at a time, the easiest way would be to serialize the
Record
object, then deserialize it as an Order
. 要做到这一点而无需一次编写一个属性的映射代码,最简单的方法是序列化
Record
对象,然后将其反序列化为Order
。 You can use whatever serialization technique you like ( XmlSerializer
, JavaScriptSerializer
, JSON.NET, etc.). 您可以使用喜欢的任何序列化技术(
XmlSerializer
, JavaScriptSerializer
,JSON.NET等)。
This assumes that all the data is accessible in public properties with plain getters/setters (which you don't in your example, but you should do). 假设所有数据都可以使用简单的getter / setter方法在公共属性中访问(在示例中您没有,但是应该这样做)。 If you don't want to do that, you can use reflection to loop through the fields of
Record
, getting the values from there, and using reflection to populate the fields of Order
. 如果您不想这样做,则可以使用反射来遍历
Record
的字段,从中获取值,然后使用反射来填充Order
的字段。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.