繁体   English   中英

如何显式转换类型(自定义类)

[英]How to explicitly cast types (custom class)

我有以下学习的代码。 我知道我不能将“父母”隐式转换为“孩子”(但反之亦然)。 但是,我正在尝试显式转换,但无法正常工作。 我认为孩子转换为父母时应该会丢失数据。

class Parent
{
    int A=5;
}

class Child:Parent
{
    int B=5;
    int C=2;
}

Parent parent = new Parent();
Child ch = new Child();

ch=ch as Parent //or (Parent)ch;

为什么需要这样做? 由于继承关系, Child Parent 在您需要Parent任何地方,您都可以生育一个Child ,这个Child应该工作(如果不这样做,您就违反了《 里斯科夫替代原则》 )。

您可以像Parent一样看Child

 Child ch = new Child();
 Parent childAsParent = ch as Parent;

但这是毫无意义的...

使用“ as Parent和“ (父项)”之间的区别在于是否会出错。 如果ch不是Parent的实例,则'safe'强制转换(使用as )只会使您保持null,在这种情况下,它将始终存在。 如果无法完成转换 ,另一个将抛出InvalidCastException

ch Parent ,不需要做演员

如果您测试此表达式

bool isParent = ch is Parent

您会看到isParent = true 您可以在任何地方使用ch作为Parent ,而无需使用任何强制转换

投放时需要将类型设置为正确的类型...

Child ch = child as Parent; //Wrong
Child ch = (Parent)child;   //Wrong
Parent p = child as Parent; //Correct
Parent p = (Parent)child;   //Correct
var p = child as Parent;    //Correct (var will end up being a Parent)
var p = (Parent)child;      //Correct (var will end up being a Parent)

可以在此处解释不同类型的类型转换(StackOverflow问题)。


我认为孩子转换为父母时应该会丢失数据。

这是一个错误的假设。 " data, but you're changing the type, which changes what members you can access. 您并不是在“ ”数据,而是在更改类型,这将更改您可以访问的成员。 将其更改回Child ,成员BC仍然保留其值。

问题是chChild ,而您正在尝试为其分配Parent 您是否尝试过将最后一行替换为

Parent pa = ch as Parent;

更改

Parent parent = new Parentk(); 
Child ch = new Child(); 
ch=ch as Parent //or (Parent)ch; 

通过

Parent parent = new Parent(); 
Child ch = new Child(); 
parent=ch as Parent //or (Parent)ch; 

您将一个孩子投射给父母,但结果是一个子对象

修改最后一行

Parent castRef = ch as Parent; 
Parent castRef = (Parent)ch;

前者是“安全强制转换”,它将检查ch是否实际上是Parent类型(或其后代),如果是,则返回对Parent类的引用,否则返回null。 这与as运算符并驾齐驱(就像(ch是Parent)...一样)

后者是一个显式的强制转换,并且不会进行检查,可能会给您带来某种与之无关的东西(该东西不是(或由Parent推定的)东西),当您使用它时会出现奇怪的错误。

我总是喜欢以前的版本。

并明确回答您的查询; 您需要一个新的Parent类型变量ref来将演员表分配给它。

注意对象实例和引用之间的区别。

new Child();

实例化(创建实例)类Child。 这意味着现在有一个对象(在“堆”中),但是您没有直接访问该对象的权限,可以通过对它的引用进行间接访问。 实例化对象后,就无法更改其类型。

Child ch;

定义具有子接口的引用,默认情况下不引用任何对象(IE:null)

Parent parent;

定义具有父接口的引用。

一旦存在这些引用,您就可以使用以下行将它们分配给对象:

parent = new Parent();

要么

ch = new Child();

因为Child继承自Parent(就像其他人所说的,它是“父”),所以Parent引用也可以引用Child对象。 IE浏览器:

parent = new Child();

要么

parent = ch;

但您只能通过父级引用访问父级定义的子级对象部分。 请注意,此操作不是必需的。 但是,您将需要进行另一方向的转换。 也就是说,如果它仍然是Child对象,但是到目前为止您只有Parent引用,则需要强制转换以获取Child引用:

ch = (Child)parent;

要么

ch = parent as Child;

如果无法执行转换,则前者将引发异常。 如果无法执行转换,则后者将为ch分配null。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM