2012-11-05 50 views
2

不多說了, 這是問題:(T)retObject [參數]無法拆箱 'retObject [參數]' 作爲 'T'

public static T WriteIfNotNull<T>(ManagementObject retObject, string parameter) 
    { 
     return retObject[parameter] != null ? (T)retObject[parameter] : default(T); 
    } 

它打破時TintretObject[parameter]是一個對象。奇怪的部分(至少對我來說)是,如果T不是T並且實際上是一個指定的int,它確實有效。

它說它不能被鑄造到T(即使在這種情況下,Tint)。

@Edit:@dtb這裏不言而喻:

Specified cast is not valid. 
(T)(object)retObject[parameter] Cannot unbox 'retObject[parameter]' as a 'T' int   

而值:

參數:"ProcessId"

retObject [參數]:4

默認(T): 0

@@編輯:下面是電話太多

pr.ProcessId = Util.WriteIfNotNull<int>(retObject, "ProcessId"); 
+0

(很抱歉,但沒有...問題是T,而不是對象。=( 它仍然拋出這個錯誤。) – apacay

+0

請添加完整的錯誤消息。 – dtb

+0

當你說「休息」,你說編譯或運行? –

回答

2

在我看來,那發生的事情是,retObject[parameter]並不是真正的int不過是另一種數字型(uint對於一般的進程ID),在這種情況下,你會想使用Convert真正改變的值:

return retObject[parameter] != null 
    ? (T)Convert.ChangeType(retObject[parameter], typeof(T)) 
    : default(T); 

一個簡單的轉換並不在這裏工作的原因是因爲如果它實際上是一個盒裝intobjectint鑄造纔有效。由於沒有從object轉換爲int的轉換,您無法在一次操作中進行投射和轉換投射。因此,從object開始鑄造需要轉換爲確切類型的確切類型或有效的超類型,接口等。

所以,一個盒裝uint轉換爲int我們就必須要麼拆箱作爲int第一(有問題),或者使用的Convert方法之一改變的類型(如上所示)。

Convert.ChangeType()適用於在兼容類型之間轉換,即使它們是裝箱的。例如,如果retObject[parameter]返回long,那麼這將允許它被轉換爲的int

我在這個here有一個博客文章,更詳細的,希望這是有道理的。其要點在於,object的鑄造屬於沮喪(沒有轉換鑄造被定義爲object),因此您必須將其轉換爲精確類型(或有效的子類型)。

+0

這也適用於字符串嗎? – apacay

+0

是的,幾乎所有實現'IConvertible'的東西都可以和'Convert.ChangeType()'一起使用,因此:'int x =(int)Convert.ChangeType(「13」,typeof(int));'works ... –

+1

事實上,你可以限制你的通用'其中T:IConvertible'如果你想強制只有可兌換類型可以使用這種方法... –