2013-12-17 55 views
1

下面的代码:向下转换安全

Base b = new Derived(); // Upcasting 
// Some actions 
Derived d = (Derived)b; // Downcasting 

据我了解的引用类似的模板,通过它,你正在寻找一些内存块。上传只是缩小了模板,因此您无法访问添加了Derived类的成员。而这里的下游将再次扩大该模板。

现在的问题是: 由于没有引用类型的派生部分保留,只是基地。在发生向下转换时,GC的某些动作或活动是否会擦除或覆盖用于包含派生成员的内存块?换句话说,下倾Derived d = (Derived)b失败?

+0

它可以,但只有'b'不是'派生'。 – Tony

+0

谢谢,我知道。但是Derived的类型部分可能会丢失,因为没有引用它只保留了Base类型。 –

回答

1

这是一个安全的演员在上下文中。您已创建Derived实例 这就是为什么将派生为Derived总是安全的原因;没有GC 活动可能会损坏实例的一部分。铸造是一种 治疗的(我要去治疗实际Derived istance为 Base只是:我已经答应打电话只是方法的子集,属性) 和铸造本身总是安全的

// Actual instance is derived, but I'm going to restrict 
    // my work with them: I've promissed not to call for "b" 
    // any derived methods/properties 
    Base b = new Derived(); 

    // What is the actual type of "b"? 
    String typeName = b.GetType().Name; // <- "Derived" 

    // Try to convert to Derived 
    // This's better way to cast then (Derived) b 
    Derived d = b as Derived; 

    // Since "b" is actually Derived d will ne not null 
    if (Object.RefrenceEquals(null, d)) { 
    Console.Write("b is Derived"); 
    } 

    // You can also check 
    if (b is Derived) { 
    Console.Write("b is a Derived instance."); 
    } 
+0

这就是我正在寻找的答案。非常感谢! –

2

该变量指向实际对象所在的内存位置。如果创建了Derived类型的对象,则该变量指向此类型实例所在的内存位置。即使您使用的是基本类型Base,内存中的实例也是您实例化的类型。所以只要你确定b的类型为Derived,下降不会失败。

0

不,它不会丢失信息。然而,如果这些信息从来没有出现过,那么演员阵容可能会失败。如果b从来不是派生类型或派生类型,它将抛出异常。

Base b = new b(); 
// Some actions 
Derived d = (Derived)b; // will fail, b never was of type Derived. 
0

1)的时间“GC将删除...的内存块”是存储B,代码“=(衍生)B” b在内存不再,那它当然就会失败,但是GC不应该抹掉它,除非你玩弄弱引用。

2)Base b = new Derived(); 我不明白你为什么要这样做“向上”。 你的代码已经有一个强大的参考/派生类型,也可以使用派生b = ....

+0

1)不是整个b - 而是只有Derived添加到基的成员,只要我们有只引用Base部分的变量。 2)这个问题不实际,但理论。 :) –

+0

当你将b创建为Derived时,整个成员/道具都存储在mem中。 Base类型就像面具/铸件一样工作,但在其下面实际上是Derived。 – Kelmen