Hon*_*ney 9 c# oop inheritance upcasting
对于以下类:
public class Parent {
//Parent members
}
public class ChildA : Parent {
//ChildA members
}
public class ChildB : Parent {
//ChildB members
}
Run Code Online (Sandbox Code Playgroud)
如果我将ChildA或ChildB实例转发到Parent实例,那么我无法访问其成员,但他们的成员仍然在那里,因为如果我转发并尝试再次访问其成员,我会发现他们仍然拥有他们的数据.
我认为这意味着父实例继续为Child类分配内存.
那么这是否意味着当我实例化一个父类,它为子类成员分配内存时,还是在我投射时才发生?
如果我们使用强制转换前进和后退,父母是否可以为多个孩子分配内存?
Tim*_*ter 14
在上面描述的情况下,强制转换不会影响从基类转换为子类时分配的内存,反之亦然.
如果您实例化Parent,则内存中将包含Parent对象.如果将其强制转换为其中一个子类,它将失败InvalidCastException.
如果你实例化任一个孩子,你将在内存中有一个子对象.您可以将其强制转换为父级,然后再返回.在任何一种情况下,内存分配都不会改变.
此外,如果您实例化ChildA,强制转换为Parent,然后尝试强制转换为ChildB,您将得到一个 InvalidCastException
参考类型的"正常"向上和向下转换
对于引用类型,转换变量不会更改已在堆上分配的对象的类型,它只会影响引用该对象的变量的类型.
所以不,没有任何额外的堆开销与转换引用类型(即来自类的对象实例).
考虑以下类层次结构:
public class Fruit
{
public Color Colour {get; set;}
public bool Edible {get; set;}
}
public class Apple : Fruit
{
public Apple { Color = Green; Edible = true; KeepsDoctorAtBay = true;}
public bool KeepsDoctorAtBay{get; set;}
}
Run Code Online (Sandbox Code Playgroud)
当与向上转发和向下转发一起使用时:
堆上只有一个分配,即初始分配var foo = new Apple().
各种变量赋值后,所有三个变量,foo,bar和baz指向相同的对象(Apple在堆上实例).
Upcasting(Fruit bar = foo)将仅限制变量对Fruit方法和属性的可用访问,如果(Apple)bar向下转换成功,则向下转换类型的所有方法,属性和事件都可用于变量.如果向下转换失败,InvalidCastException将抛出一个,因为类型系统将在运行时检查堆对象的类型与变量的类型.
转换运算符
根据tolanj的评论,如果显式转换运算符替换默认的引用类型转换,那么关于堆的所有赌注都将被取消.
例如,如果我们添加一个不相关的类:
public class WaxApple // Not inherited from Fruit or Apple
{
public static explicit operator Apple(WaxApple wax)
{
return new Apple
{
Edible = false,
Colour = Color.Green,
KeepsDoctorAtBay = false
};
}
}
Run Code Online (Sandbox Code Playgroud)
可以想象,WaxApple explicit operator Apple可以做任何它喜欢的事情,包括在堆上分配新对象.
var wax = new WaxApple();
var fakeApple = (Apple)wax;
// Explicit cast operator called, new heap allocation as per the conversion code.
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1309 次 |
| 最近记录: |