C# 从派生类将对象强制转换为对象
我有一个类C# 从派生类将对象强制转换为对象,c#,oop,C#,Oop,我有一个类记录,运行良好: public class Record { protected string table; protected string idcolumn; public Record(string _table, string _idcol, int _id) { table = _table; idcolumn = _idcol; Id = _id; } } 我还有一个类Order,
记录
,运行良好:
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()
{
}
}
在我的应用程序中,我有一个类型为Record
的对象Record
,我想将其转换为Order
,这样我就可以在其上调用Start
方法
我试着投下它:
Order r = (Order)theRecord;
但这会引发一个无效的异常
我想我可以为Order
创建一个新的构造函数,它接受一条记录
,但是我已经拥有了这个对象(它是通过从数据库中获取一条记录构建的)
我如何才能正确地执行此操作?如果您得到一个无效的castedException
,则记录
不是命令,您无法强制执行它。只有将其创建为Order
或Order
的子类时,才能对其进行强制转换
我的猜测是,从数据库中获取数据的任何东西都会创建一个记录,而它可以创建一个订单
(并将其作为记录
)返回)。比如:
public Record Fetch(int id)
{
// ... get data from db
Record rec;
if(data.Type = "Order")
rec = new Order();
else
rec = new Record();
return rec;
}
如果您得到一个无效的castedException
,则记录
不是一个订单
,您不能强制转换它。只有将其创建为Order
或Order
的子类时,才能对其进行强制转换
我的猜测是,从数据库中获取数据的任何东西都会创建一个记录,而它可以创建一个订单
(并将其作为记录
)返回)。比如:
public Record Fetch(int id)
{
// ... get data from db
Record rec;
if(data.Type = "Order")
rec = new Order();
else
rec = new Record();
return rec;
}
正如我在评论中所说的
你可以用狗对动物,但不能用动物对狗(除非那个动物是狗)。更清楚的是,所有的狗都是动物,但并非所有的动物都是狗
为了让它发挥作用,你必须这样做
Record record = new Order();
Order order = (Order)record;//works since record is Order
然后你可以这样投
Record record = new Order();
Order order = (Order)record;//works since record is Order
正如我在评论中所说的
你可以用狗对动物,但不能用动物对狗(除非那个动物是狗)。更清楚的是,所有的狗都是动物,但并非所有的动物都是狗
为了让它发挥作用,你必须这样做
Record record = new Order();
Order order = (Order)record;//works since record is Order
然后你可以这样投
Record record = new Order();
Order order = (Order)record;//works since record is Order
您可以使用is
和as
操作符,在实际尝试强制转换某个对象之前,确保该对象属于特定类型,如下所示:
Record objectToHoldCastedObject;
if(theRecord is Order)
{
objectToHoldCastedObject = theRecord as Order;
}
is
将检查对象是否为该确切类型或是继承链的一部分
as
将尝试将对象强制转换为该类型,如果不能,则将返回null而不是异常
注意:as
仅适用于引用类型,而不适用于值类型;而is
将同时适用于引用类型和值类型。例如,您可以将is
作为整数,但不能将作为整数。您可以使用is
和as
运算符,在实际尝试强制转换之前,确保某个对象属于特定类型,如下所示:
Record objectToHoldCastedObject;
if(theRecord is Order)
{
objectToHoldCastedObject = theRecord as Order;
}
is
将检查对象是否为该确切类型或是继承链的一部分
as
将尝试将对象强制转换为该类型,如果不能,则将返回null而不是异常
注意:as
仅适用于引用类型,而不适用于值类型;而is
将同时适用于引用类型和值类型。例如,您可以将转换为一个整数,但不能将转换为一个整数。您必须转换为一个新对象,而不是强制转换它。要做到这一点,无需一次编写一个属性的映射代码,最简单的方法是序列化记录
对象,然后将其反序列化为顺序
。您可以使用任何喜欢的序列化技术(XmlSerializer
、JavaScriptSerializer
、JSON.NET等)
这假设所有数据都可以通过普通的getter/setter在公共属性中访问(在示例中没有,但应该这样做)。如果不想这样做,可以使用反射在记录
的字段中循环,从中获取值,并使用反射填充顺序
的字段,您必须转换为新对象,而不是强制转换它。要做到这一点,无需一次编写一个属性的映射代码,最简单的方法是序列化记录
对象,然后将其反序列化为顺序
。您可以使用任何喜欢的序列化技术(XmlSerializer
、JavaScriptSerializer
、JSON.NET等)
这假设所有数据都可以通过普通的getter/setter在公共属性中访问(在示例中没有,但应该这样做)。如果您不想这样做,您可以使用反射在记录
的字段中循环,从中获取值,并使用反射填充顺序
的字段您不能将狗
投射到动物
,但不能将动物
投射到狗
(除非该动物是狗
). 更清楚的是,所有的狗都是动物
,但并非所有的动物都是狗
作为操作员怎么样?我的意思是记录为Order
@vladimirflov,它无法将你尝试过的错误代码发布到铸造代码中。你不能将狗
铸造到动物
,但不能动物
至狗
(除非该动物是狗
)。更清楚的是,所有的Dogs
都是Animal
,但并非所有的Animals
都是Dogs
操作符呢?我的意思是theRecord as Order
@VladimirFrolov,它不会发布您尝试过的铸造代码,并且出现错误。或者提供多种数据获取方法,例如Order FetchOrder Order(int-id)
,Foobar FetchFoobar(int-id)
等,或