2010-10-12 139 views
7

今天我遇到了一個問題,我不完全確定它爲什麼不起作用。在c中鑄造對象類型#

下面的代碼示例會崩潰:

static void Main(string[] args) 
{ 
    int i32 = 10; 
    object obj = i32; 
    long i64 = (long)obj; 
} 

這將導致一個InvalidCastException。爲什麼這不起作用? C#沒有足夠的智能來知道對象實際上是int類型的嗎?

我已經想出了一個解決方法,但我很好奇爲什麼上面的代碼示例不起作用。

感謝, 添

+1

我注意到這是許多以前的問題的重複,包括最近http://stackoverflow.com/questions/3911293 – 2010-10-13 05:18:47

回答

9

沒有爲Int64沒有可用的鑄從盒裝的Int32。 使中間投地int應該工作,因爲編譯器是願意產生這樣的:

// verify obj is a boxed int, unbox it, and perform the *statically* 
// known steps necessary to convert an int to a long 
long i64 = (long) ((int)obj); 

但不是(假設)這樣的:

// Find out what type obj *actually* is at run-time and perform 
// the-known-only-at-run-time steps necessary to produce 
// a long from it, involving *type-specific* IL instructions 
long i64 = (long)obj; 

這裏有一個blog post通過埃裏克利珀這一點。

1

你的意思是編譯器或運行時?

運行時足夠智能,所以它會拋出InvalidCastException。然而編譯器無法確定你的對象是什麼類型,因爲你裝了你的int。

裝箱和拆箱啓用值類型 被視爲對象。裝箱 值類型將其打包在對象參考 類型的 實例中。

因此,由於它作爲一個對象裝箱,編譯器不會抱怨它。

參見裝箱和拆箱這裏的更多信息:

http://msdn.microsoft.com/en-us/library/yz2be5wk%28VS.80%29.aspx

3

退房this blog post通過埃裏克利珀的血淋淋的細節。

它的要點是編譯器會很慢(通過試驗和錯誤,因爲object可以是任何東西)哪種類型已被裝箱以及它是否可以安全地投射。