为什么这个Upcast不起作用?

时间:2009-06-18 11:19:59

标签: c# oop

我有2个类Test(Base)和Program(child)。现在我在向下倾斜时遇到了一些问题。

        Test t = new Program();// upcasting-works
        Program p = (Program)t;//Downcasting-works
        Program q = (Program)new Test();//Downcasting -throws exception.

我想知道为什么抛出异常?可能它是非常基本的,但不知怎的,我没有得到。 是为了那个新对象吗?

感谢。

5 个答案:

答案 0 :(得分:7)

这是所有OO系统中的预期行为。简而言之,您无法向下转换为动态类型不匹配的内容。在这一行:

Program q = (Program)new Test();

您正在创建Test个实例 - 该实例显然与Program不匹配,因为Test并非来自Program。在运行时,计算机检测到这种情况并抛出异常。

另一方面,你有:

 Test t = new Program();

在这里,您要创建一个Program实例 - 实例与Test匹配,因为Program派生自Test

最后,又乱了,你有:

Program p = (Program)t;

在这种情况下,t是对Test的引用,但基础类型实际上是Program - 在运行时,计算机能够确定是这种情况所以被允许工作。

答案 1 :(得分:6)

每个方格都是矩形,但反之亦然。类似地,派生类的每个实例都是基类的有效实例,但反之亦然。在您的示例中,每个Program都是Test,但并非所有Test都是Program

注意:澄清一下,这并不意味着你应该在OOP中从Rectangle继承Square :)这只是一个类比。具有讽刺意味的是,类比是OO设计中众所周知的问题。

答案 2 :(得分:1)

问题是:Test实例不是 a Program。它适用于第一种情况,因为实例创建为Program(在第一行)。

使用强制转换,实际对象的类型(不仅仅是变量)很重要。

答案 3 :(得分:0)

可以这样想,你可以将程序转换为Test,因为Program is A Test。

您无法将Test转换为Program,因为Test不是Program。

当你确定对象是那种类型的时候,向下投射是安全的,只有在安全的情况下才能安全投射。

需要升级通常是一种代码气味,如果你发现你经常需要翻转你的物体,你的设计可能有问题。

希望这有帮助,

编辑:向下传播总是安全吗?

根据我的定义 - 根据我的定义 - 你知道对象的类型,并且你把它放在它的继承树下面。例如 Cat和Dog都继承自Animal,Oak和Birch都继承自Tree。

这样做总是安全的

public void DoThingWithCat(Cat snuggles)
{
    snuggles.Meow();
    DoThingWithAnimal(snuggles); // this is always OK, because we know 
                                 // the type of snuggles, and we know 
                                 // snuggles is an animal
}

这是一个UpCast。这样做是不安全的,这也就是代码是代码味道,如果你需要这样做,你的对象层次结构可能有问题。

public void DoSomethingElse(Animal anAnimal)
{
    DoThingWithCat(anAnimal);    // this is NOT always OK, because we
                                 // DO NOT know the type of anAnimal, 
                                 // and it may not be a Cat
}

这也是不安全的,因为它是直接铸造,不一定是向上铸造或向下铸造

public void DoSomethingDifferent(object anObject)
{
    DoThingWithAnimal(anObject); // this may or may not work, 
                                 // depending on the type passed in, 
                                 // this is a recipe for disaster, 
                                 // because may not be an Animal, 
                                 // it could be a Tree.
}

答案 4 :(得分:0)

迈赫达德给出了正确的答案。只是为了更清楚:

Test <{1}} - 反之亦然:Program在您的案例中是Program。因此,你要做的不是向上,而是不允许。