好的,我不认为这是可能的,所以我想我会要求确定。我正在创建一个函数,它反映了类中的属性,并将它们添加到我拥有的数据结构中。一些属性是泛型类型。
所以说我们DataType(Of T)
的{{1}}属性类型为.Value
:
T
在原始类型的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
,Integer
等......)我只想添加类型...但在泛型的情况下我想添加String
。我希望有一些解决办法,但我认为没有办法,因为DataType(Of T).Value
的类型无法在编译时确定吗?理想情况下T
是可能的。这是你希望在.NET 4.0中出现更多动态的时候。
答案 0 :(得分: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 …
是代码气味。也许你应该重新思考你的代码并研究涉及多态的解决方案。
答案 1 :(得分:0)
首先,我对您尝试做的事情的假设:
您有一个名为poco
的对象,其类型为MyType
。
MyType
包含不同类型的字段,因此您认为需要泛型。
您有一个名为Collection
的键值对集合,可能有Dictionary(Of String, Object)
类型?
您希望将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
,尽管我强烈建议您选择一个更加不言自明的名称!),它指定了您的值可以做什么
其次,将Collection
键入Dictionary(Of String, DataType)
。这意味着只有DataType
类型的对象或从中派生的任何对象才能进入集合。
第三,派生自/实施DataType
以指定特定类型的行为。
这里有一个很好的slide show called Conditionals and Polymorphism。
旁注:最后但并非最不重要的是,您可以找出泛型类型参数的类型:
TypeOf(T)
。