2010-10-19 99 views
3

在下面的代碼混亂......關於值類型的拳擊

int i=5; 
object o = 5; 
Console.WriteLine(o); //prints 5 

我有三個問題:

1)什麼額外的/有用的功能是由5居住在收購變量o表示變量i所代表的5沒有?

2)如果一些代碼期待值類型,那麼我們就可以通過它的INT i,但如果期望引用類型,它可能不會在o盒裝反正5感興趣。那麼,什麼時候在代碼中顯式使用裝箱轉換?

3)Console.WriteLine(o)怎麼會打印出5而不是System.Object?

回答

5

位於變量o中的5獲得了什麼額外的/有用的功能,即由變量i表示的5沒有?

這是罕見的,你框的東西,但有時它是必要這樣做。在老版本的.NET中,裝箱往往是必要的,因爲有些方法只能用於object(例如ArrayList的方法)。這是現在有一個問題,因爲有泛型,所以在較新的代碼中,拳擊發生的頻率較低。

如果某些代碼需要值類型,那麼我們可以將它傳遞給int i,但是如果它期待引用類型,它可能對o中的5個盒子不感興趣。那麼,什麼時候在代碼中顯式使用裝箱轉換?

在實踐中拳擊通常會自動發生在你身上。如果你想讓代碼的讀者更清楚地知道裝箱正在發生,你可以明確地設置一個變量。如果表現可能成爲問題,這可能是相關的。

Console.WriteLine(o)怎麼會打印出5而不是System.Object?

由於ToString是,這意味着被調用的實現依賴於運行時類型,而不是靜態類型上object一個虛擬方法。由於int覆蓋了ToString自己的實現,因此調用int.ToString,而不是由object提供的默認實現。

object o = 5; 
Console.WriteLine(o.GetType()); // outputs System.Int32, not System.Object 
0

什麼額外的/有用的功能是由駐留在變量o由變量表示的5我不具有5獲取?

除了它可以通過引用傳遞給需要的代碼外,沒有通過裝箱值類型獲得的附加功能。

那麼,什麼時候在代碼中顯式使用裝箱轉換?

我不能自發地想到一個場景,當你需要明確框中intobject,因爲總是在這個方向的隱式轉換(但如果有些時候情況下,我也不會感到驚訝一個明確的轉換是必需的)。

Console.WriteLine(o)怎麼會打印出5而不是System.Object?

它在傳遞的對象上調用ToString。實際上,它首先嚐試將對象轉換爲IFormattable,如果成功(它將在int的情況下),然後調用ToString overload that is defined in that interface。這將返回「5」。

0

1)本身沒有多少意義。但想象一下,你希望以一種通用的方式存儲某些東西,而你不知道這件事是價值還是對象。通過裝箱,您可以將該值轉換爲對象,然後將所有對象視爲對象。無論如何,你需要一個特殊的情況下能夠保存一個值的一個對象。 (這在像列表這樣的容器中最爲有用,可以將像5一樣的值與FileStream等對象的引用混合使用)。

2)拳擊轉換通常只會隱式發生,除了舉例說明拳擊的示例代碼。

3)WriteLine代碼可能調用虛擬Object.ToString()方法。如果它調用的對象的類不覆蓋ToString,那麼它將調用基類(對象)實現,但大多數類型(包括System.Int,儘管int是一個值類型,它仍然是從System.Object派生的)重寫這個以提供更有用的特定於上下文的結果。

0

附加功能:該對象是一個完整的對象。你可以調用方法上,並使用它,就像任何其他對象:

System.Console.WriteLine("type: {0}", o.GetType()); 
System.Console.WriteLine("hash code: {0}", o.GetHashCode()); 

int變量是值類型,而不是對象。

XXX:這是不正確的;看評論。我會冒昧地說,你如何使用這兩者的一個區別是,object o = 5是可以爲空(你可以設置o = null),而值類型不是 - 如果int i = 5,那麼i總是一個整數。

顯式裝箱:正如你所說,盒裝版本是通過編碼操作對象作爲對象而不是整數特別使用的。這是啓用非類型安全的通用數據結構的原因。既然類型安全的通用數據結構可用,那麼您不太可能進行大量的投射和裝箱/拆箱。

爲什麼「5」:因爲對象知道如何使用ToString()打印自己。

+0

這是一個有點誤導。你可以在Int32類型的變量上調用GetType()和GetHasCode()等。這與正在裝箱或未裝箱的值類型無關。 – KeithMahoney 2010-10-19 22:59:59

+0

@KeithMahoney你是對的:我錯了。我拿出了C#3.0語言規範,並且類型系統很好地統一。中心差異 - 價值對比參考類型 - 涉及對象如何與其數據相關聯。 – 2010-10-20 00:39:38