2011-12-13 39 views
4

我使用反射來遍歷對象的屬性。對於Nullable<>類型,使用PropertyType屬性正在返回類型。然而,當我調用屬性getter(通過PropertyType.GetGetMethod().Invoke(obj, new object[0])PropertyType.GetValue(obj, null),結果的類型是展開的原始的,未Nullable<>。對於原因的,我寧願去成,我需要把這個結果轉換成其Nullable<>類型,這將引發InvalidCastException在這種情況下:C#:動態轉換基元爲Nullable <>

Convert.ChangeType(property.GetValue(obj, null), property.PropertyType); 

有另一種方式,以確保該屬性值的類型總是相同屬性的類型

+0

「對於原因的,我寧願不進入」 - 完全取決於你,當然,但你問什麼**就不能存在** - 也許你可以添加一些上下文(更改名稱,如果你喜歡 - 我們不會知道或關心),我們可能會提出一個更好的選擇。 –

+0

如果您確實必須知道,我將從Java到XML的XML編碼器移植到C#中。我不會用另一個取代它們 - 兩者都會存在並得到維護,所以我試圖儘量減少它們之間的差異。我有一個'IDictionary '('IConverter'是我的),它充當屬性類型的屬性值轉換器的註冊表。由於我有這個問題,它打破了'可空'的問題。 –

+0

我使用'MakeGenericType'到所有註冊的兩倍的初始註冊後寫的代碼的簡要位 - 即,對於每個'type',添加相同的轉換器對'typeof運算(可空<>)MakeGenericType(類型)' –

回答

5

你不能這樣做,在反射的代碼,因爲在反射代碼,你說的?約object,那裏是這樣的東西作爲一個盒裝Nullable<T> - 這是盒裝基礎價值,或null

如果你知道實際的類型,你可以使用構造函數來創建一個包裹價值,但它必須只能被分配到一個類型的字段/變量是Nullable<T> - 不object - 否則CLI再次解開它。

然而,對於同樣的原因,你不需要它使用反射時,包裹;任何代碼,如SetValue將接受object,並會做正確的事情;不管它是null還是盒裝基礎值,都將被正確處理。

基本上,CLI裝箱和拆箱Nullable<T>,使問題void當有特殊處理。

+0

感謝你的回答。我仍然有一點需要了解C#中的拳擊。由於我需要的類型是一個'IDictionary <>'鍵,我知道我所有的基元都被封裝在'Nullable <>'中,所以我改變了一下設計來創建一個使用'(obj.GetType()。IsValueType?作爲關鍵字的typeof(Nullable <>)。MakeGenericType(new [] {obj.GetType()}):obj.GetType())。它現在有效。 –

+1

@SteveTaylor注意* *反射級別('MakeGenericType'等)非常慢;適用於中等使用,但如果這是一個嚴格的循環,您*可能會*想優化一下... –

+0

感謝您的提示。 dotTrace是我的朋友。 :) –

相關問題