[英]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
,成员B
和C
仍然保留其值。
问题是ch
是Child
,而您正在尝试为其分配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.