2010-09-09 60 views
0

好吧,我不認爲這是可能的,所以我想我會問,以確保。我現在在creating which反映了在a類的屬性,並將它們添加到這個數據結構我有a功能的過程。一些屬性是通用類型。轉換爲普通類型在運行時

所以說,我們有DataType(Of T)T類型的.Value屬性:

Dim properties = GetType(MyType).GetFields(Reflection.BindingFlags.Public Or _ 
              Reflection.BindingFlags.Instance) 
For Each prop As fieldinfo In properties 
    Collection.Add(prop.Name,prop.GetValue(poco)) 
Next 

collection.Add基本類型(IntegerString等…)我只是要添加的類型.. ,但在一般的情況下我想補充的DataType(Of T).Value。我希望有一些變通,但我不認爲有一種方法,因爲T類型不能在編譯時正確的決定?理想情況下DirectCast(prop.getvalue(poco), DataType(Of T)).Value將是可能的。這是當你希望在.NET 4.0中出現更多的動態變化時。

+0

所以我想它不可能? – coding4fun 2010-09-10 12:56:03

+0

你的答案在這裏:http://stackoverflow.com/questions/2891797/typecasting-generic-parameters – pylover 2012-05-12 04:52:00

回答

1

剛纔我發現我可能誤讀了你的問題。因此,我的另一個答案。

你可以不用通過引入新的接口,允許訪問某些Value屬性在運行時轉換爲普通型(你不知道類型參數):

Public Interface IHasValue 
    Public ReadOnly Property Value As Object 
End Interface 

接下來,確保你的DataType(Of T)類實現這個接口。這意味着每個DataType(Of T)對象(無論T是什麼具體類型)也是IHasValue,你將能夠與TypeOf(…) Is IHasValue進行檢查:

Public Class DataType(Of T) : Implements IHasValue 

    Public Value As T 

    Public ReadOnly Property UntypedValue As Object Implements IHasValue.Value 
     Get 
      Return Me.Value 
     End Get 
    End Property 

End Class 

(的Value這種重複是必要的,原因有二:一是有必要時DataType(Of T).Value是一個場,而不是一個屬性,第二是因爲他們不具有相同的類型。)

然後,在你的字段填寫您的收藏,您可以檢查一個特定的字段是DataType(Of T)(如果是這樣,從它打開Value)通過執行以下操作:

Dim value As Object = prop.GetValue(poco) 

If TypeOf(value) Is IHasValue Then   ' <- is value a DataType(Of T) ? ' 
    value = CType(value, IHasValue).Value ' <- if so, unwrap the value  ' 
End If 

Collection.Add(prop.Name, value) 

這可能是更你比我其他的答案之後在做什麼,但我要強調這一點:

If TypeOf(…) Is … Then …是一個代碼味道。也許你應該重新考慮你的代碼並研究涉及多態的解決方案。

+0

非常感謝stakx的幫助。優秀的解決方雅更好的解決方案是返回一個基本類型調用它只是基本類型和返回,而不是類型T.基本類型只會持有類型T,但你不必擔心在這種情況下投射。不幸的是,這將需要很多代碼重新訪問,因爲這個東西被全部使用,很少有人使用這個接口。無論如何非常感謝你的幫助 – coding4fun 2010-09-13 15:42:02

0

首先,我對你試圖做什麼假設:

  1. 你必須有類型MyType命名poco一些對象。

  2. MyType有不同類型的字段,因此你認爲你需要仿製藥。

  3. 您有一個名爲Collection的鍵值對集合,可能是類型Dictionary(Of String, Object)

  4. 您想將所有poco的字段(即,它們的名稱和值)轉移到Collection


側節點:你是混合領域了性能:您的代碼在運行領域(通過調用GetFields),而你的問題的文字講屬性。它們不是同一件事!


其次,關於收藏和靜態類型系統的一些基本事實:

  • 非類型化的集合(其中項目類型Object)的可存儲各種值的它。

  • 類型集合(其中,物品是一個更具體的類型,例如T)只能具有類型T或從T派生類型存儲值。


第三,結論從上面的得出:

  • 在你的情況,Collection必須是類型化的集合,如果它確實是真正poco(有型MyType)具有不同類型的字段。

  • 在這種情況下,泛型實際上並不會幫助你,因爲這不是泛型。當你想要定義操作(即方法,行爲)時,泛型是非常有用的,它們以相同的方式工作,而不管他們正在處理什麼類型的對象。

    例如,List(Of T)定義了一種集合類型,無論T是什麼類型,集合類型都是相同的。但這並不意味着您可以將任何內容放入List(Of T),因爲只要您將此類型實例化爲—與Dim xs As New List(Of String) —,T將被固定爲一個特定類型— String —,你最終得到一個類型的集合,只接受這種類型的值。

    因此,如果您需要一個存儲不同類型對象的集合,請選擇Object作爲值類型,而不是嘗試查找涉及泛型的解決方案。


話雖這麼說,有另一種解決方案:多態

如果您希望您的代碼以不同方式處理值,根據不同的類型,多態是要走的路:

  • 首先,你定義一個接口或抽象基類(如DataType,雖然我'強烈建議你選擇一個更明顯的名字!),它指定了你的值可以做什麼。

  • 二,輸入CollectionDictionary(Of String, DataType)。這意味着只有DataType類型的對象或從中派生的任何對象才能進入集合。

  • 第三,從/執行DataType來指定特定類型的行爲。

有一個很好的slide show called Conditionals and Polymorphism,可能是在這裏討論。


旁註:最後但並非最不重要的,你可以找出一個泛型類型參數的類型:TypeOf(T)