Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 从派生类将对象强制转换为对象_C#_Oop - Fatal编程技术网

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)
等,或