2010-02-25 108 views
4

我想獲得類型轉換方法之間的區別。不同類型的轉換方式。有什麼區別

例如。

方法1

public byte fun() 
{ 
    object value=1; 
    return (byte)value; // this gives me error 
} 

方法2

public byte fun() 
{ 
    object value=1; 
    return byte.Parse(value.ToString()); // this runs 
} 

方法3

public byte fun() 
{ 
    object value=1; 
    return Convert.ToByte(value); // this runs 
} 

是什麼區別所有這三個。 他們是如何在內部工作的。 這是什麼值類型和引用類型。 哪個函數可以值類型轉換爲引用類型,反之亦然

編輯2

當我寫這行有什麼數據類型「1」,將默認INT32,字節或別的東西來處理。

對象值= 1;

+0

此外,還有'布爾byte.TryParse(字符串,出雙值)' – AxelEckenberger 2010-02-25 17:37:36

+0

@Obalix:應該是byte.TryPase(字符串,出字節值) – 2010-02-25 17:40:21

回答

8

有很多的問題在這裏。

方法1,因爲你不能做一個拆箱,並在一次操作中轉換失敗。您將「值」設置爲裝箱的整數。當您嘗試執行轉換時,您將拆開整數並嘗試在單個操作中轉換爲一個字節,該轉換失敗。這並不工作,順便說一句:

return (byte)((int)value)); // Unbox, then cast, in two operations 

方法2級的作品,因爲你的整數轉換成字符串,然後使用byte.Parse將其轉換爲一個字節。這是非常昂貴的,因爲它是從字符串中去除。

方法3家中使用,因爲它看到在值的對象是IConvertible(INT),並且使用適當的轉換操作,以轉換成字節。在這種情況下,這可能是更有效的方法。由於「價值」是存儲一個int,和INT支持IConvertible,Convert.ToByte基本上都會做一個空檢查,然後調用Convert.ToByte(INT),這是相當快的(它確實邊界檢查,並直接投)。

我建議你閱讀埃裏克利珀的題爲Representation and Identity博客文章。它涵蓋了鑄件的細節,並解釋了爲什麼方法1會失敗...

1
// This is a direct cast. It expects that the object 
// in question is already allocated as the data type 
// indicated in the cast 
(byte)value; 

// This is a direct code conversion. It takes the argument 
// and runs through code to create a new variable of the 
// type byte. You'll notice if you include this in different 
// code that value will still be an object but your new 
// data will be a byte type 
byte.Parse(value.ToString()); 

// This will convert any object similarly to the byte.Parse. 
// It is not as fast because it does not have a definitely 
// typed parameter (as parse has string). So it must go 
// through a couple of extra steps to guarantee the conversion 
// is smooth. 
Convert.ToByte(value); 

直接鑄造總是最快的。它假定類型已經建立和分配,所以它只需將其引用類型切換到內存中。轉換方法是代碼轉換,因此它們需要更多時間。我不知道基準,但Parse稍微快一點,因爲它處理特定的輸入和特定輸出(字符串 - >字節)。轉換是轉換方法中速度最慢的方法,因爲它缺少相同的特性。

+0

他的方法之一不是直接投,然而......這是一個unbox + cast,會失敗。 – 2010-02-25 17:41:57

+0

此外,轉換速度更快,因爲它可以直接使用int.ToByte(來自IConvertible.ToByte)。 – 2010-02-25 17:42:50

+0

@Reed Copsey:如果最初實例化爲一個字節,它將被拆箱。它不是,它開始把它作爲一個對象分配。爲了將其「解除盒裝」,必須首先從字節到對象進行裝箱。在這種情況下,這是一個直接轉換,這就是爲什麼它失敗。參見:http://msdn.microsoft.com/en-us/library/b95fkada(VS.80).aspx和http://msdn.microsoft.com/en-us/library/ms173105(VS.80)。 aspx – 2010-02-25 17:59:00

0

那麼這裏是我的鏡頭吧:

方法1

這是一個類型轉換,即值必須是一個類型,可以是implcitly或明確地轉換成字節。此外,值不得超出字節的範圍。

調用失敗,因爲編譯器沒有任何信息應該拋出什麼類型的對象,因此不能執行隱式或顯式轉換。這樣做

int obj = 1; 
byte b = (byte) obj; 

byte b = (byte) (int) obj; 

作品。第二個選項使用expicit拆箱(從而提供所需信息),如Reed Copsey的評論和帖子中所述。 Reed Copsey的評論提供的link詳細解釋了這一點。

對於自定義對象強制轉換使用隱式轉換和顯式轉換是在類上定義的靜態方法的運算符。對於object不存在隱式或顯式操作(請參閱link,原因爲何),而對於int存在這些操作。

方法2

這裏你解析字符串字符串的值必須是一個數字,它是結合一個字節的內部。在這裏,您還可以使用TryParse,它允許您檢查轉換是否成功。

方法3

採用Convert類的類型轉換。這是支持大多數常見類型的最靈活的方法。這裏,該值必須可以轉換爲數字,並且該值必須在字節的邊界內。 Convert類使用IConvertible在不同類型之間進行轉換,因此是可擴展的。

+1

您的「方法1」解釋不正確。這是拆箱的一個特殊限制-ie:拆箱類型T只能直接拆箱到T。請參閱:http://blogs.msdn.com/ericlippert/archive/2009/03/19/representation-and-identity.aspx – 2010-02-25 17:55:44

+0

不確定那個鏈接是否與我的陳述相矛盾...我猜'int jjj =(int)(short)ooo;'是你想要的陳述。正如我對它的解釋,它相當於'short s =(short)ooo; int i =(int)short;'。這種行爲與我寫的一致。 – AxelEckenberger 2010-02-25 18:03:59

+0

這不是編譯器的問題,「沒有關於應該投射什麼類型的對象的任何信息」,而是當你拆箱時類型不同,並且你不能在一個操作中取消箱子投射。 – 2010-02-25 18:48:06

相關問題