2009-06-18 32 views
2

我有2類測試(基地)和計劃(兒童)。現在我在下注時遇到了一些問題。爲什麼Upcast不起作用?

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

我想知道爲什麼它的拋出異常?可能b是非常基本的,但不知何故,我沒有得到。 這是新的對象嗎?

謝謝。

+2

這是令人困惑,因爲強制轉換,既可以指「使給定類型的新的東西出來的這個老東西」,而相反的,「檢查給定的事情是否真的給定類型的」。有關此主題的更多思考,請參閱http://blogs.msdn.com/ericlippert/archive/2009/03/19/representation-and-identity.aspx。 – 2009-06-18 14:11:12

回答

7

這是預期中的所有OO系統的行爲。簡而言之,你不能倒裝成動態類型不匹配的東西。在這一行:

Program q = (Program)new Test(); 

您正在創建一個實例Test - 實例顯然不符合Program因爲Test不從Program派生。在運行時,計算機檢測到這種情況並引發異常。

在另一方面,你必須:

Test t = new Program(); 

在這裏,你正在創建一個實例Program - 實例相匹配Test因爲Program並從Test派生。

最後,亂序,您有:

Program p = (Program)t; 

在這種情況下,tTest一個參考,但潛在的類型真的是Program - 在運行時,電腦能夠判斷這是這樣的情況下,演員被允許工作。

+0

1奈斯利所示 – 2009-06-18 11:43:36

+0

這裏Console.WriteLine(t.GetType());將返回Program.so如果T的類型是程序,那麼我們爲什麼還要提它明確, 程序P =(計劃)噸; – Wondering 2009-06-18 11:52:04

+0

由於C#希望您明確表示您正在執行不保證安全的演員。 – jerryjvl 2009-06-18 11:58:03

6

每個方形都是矩形,但反之亦然。同樣,派生類的每個實例都是基類的有效實例,但反之亦然。在你的例子中,每個ProgramTest,但不是所有的Test都是Programs。

+0

*注意*:爲了澄清,這並不意味着你應該從OOP中的Rectangle繼承Square。這只是一個比喻。具有諷刺意味的是,這種類比在OO設計中是一個衆所周知的問題。 – 2010-10-27 10:28:53

0

想想這樣,您可以將程序強制轉換爲測試,因爲程序是測試。

您不能將測試轉換爲程序,因爲測試不是程序。

向下傾倒是安全的,只有在確定該類型的對象是安全的時候纔可以向上傾倒。

需要上傳通常是一種代碼氣味,如果您發現您經常需要上傳您的對象,那麼您的設計可能有問題。

希望這有助於

編輯:是否總是安全的向下轉換?

downcasting的行爲是根據定義 - 根據我 - 在哪裏你知道對象的類型,而你把它放在更低的繼承樹下。例如 貓和狗都繼承了動物,橡樹和樺木都從樹繼承。

它始終是安全的做到這一點

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 
} 

這是一個上溯造型。這樣做是不安全的,這也是一個代碼是一種代碼異味,如果你需要這樣做,你的對象層次結構可能有問題。

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. 
} 
+0

「這常是安全的,沮喪的,它只是安全的上溯造型,當你確信類型的對象是」 ..是U確定嗎?我認爲,雖然下調我們必須小心,因爲我們必須記住這種類型。 或者,我沒有得到你? – Wondering 2009-06-18 12:00:20

1

的問題是:一Test實例不是一個Program。它在第一種情況下工作,因爲實例創建爲Program(在第一行)。

隨着演員陣容,實際對象(不只是變量)的類型很重要。

0

Mehrdad給出了正確的答案。只是爲了更清楚:

Test一個Program - 正好相反:Program是,一個在你的情況Test。因此,你試圖做的事情不是一個事情,這是不允許的。