VB.NET如何从可空类型中获取底层系统类型?

10

我正在尝试根据对象的属性创建一个数据集。例如,我有一个Person类的实例,其中包括ID、名字、姓氏、出生日期等属性。使用反射,我正在基于对象属性向新的数据集添加列:

For Each pi As PropertyInfo In person.GetType().GetProperties()
    Dim column As New DataColumn(pi.Name, pi.PropertyType)
    table.Columns.Add(column)
Next
我的问题是,其中一些属性是可空类型,而数据集不支持这些类型。有没有办法从可空类型中提取底层的系统类型?
谢谢。
5个回答

16

以下是你需要的VB代码。这可能对你来说有些复杂,但对其他人也可能有用。

首先,下面是用于查找是否正在处理可空类型的代码:

Private Function IsNullableType(ByVal myType As Type) As Boolean
    Return (myType.IsGenericType) AndAlso (myType.GetGenericTypeDefinition() Is GetType(Nullable(Of )))
End Function

请注意GetType中的不寻常语法。这是必要的。像某些评论者建议的那样只使用GetType(Nullable)并不适用于我。
因此,有了这个,你可以做出像这样的事情... 在ORM工具中,我正在尝试将值传递到一个可能是可空类型的泛型类型中:
If (Not value Is Nothing) AndAlso IsNullableType(GetType(T)) Then
    Dim UnderlyingType As Type = Nullable.GetUnderlyingType(GetType(T))
    Me.InnerValue = Convert.ChangeType(value, UnderlyingType)
Else
    Me.InnerValue = value
End If

请注意,我在第一行检查了Nothing,因为Convert.ChangeType会对其产生影响...您可能没有这个问题,但我的情况非常开放。
希望如果我没有直接回答您的问题,您可以利用这个并达到您需要去的地方-但我刚刚实现了这个,我的测试都通过了。

他所要求的只是基础类型,所以你只需要使用Nullable.GetUnderlyingType。 - Bryan Anderson
我猜他最终会需要其中的大部分。 :) - Brian MacKay
非常棒的帖子,救了我的命! - tbone
非常高兴听到这个消息,tbone。 - Brian MacKay

4
Nullable.GetUnderylingType(myType)

如果它不是可空类型,将返回基础类型或null。


太棒了,谢谢!在C#中,我无法编译... is typeof(Nullable<>)(稍后我会找出原因),所以这个解决方案完全避免了我反复撞墙的尴尬。而且比其他解决方案更简单。 - Groxx

1

我猜问题在于识别属性是否可为空。在C#中,您可以使用以下代码来实现:

if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>))

...但我不确定在VB.NET中相应的最后一个从句是什么。


如果 (type.IsGenericType AndAlso type.GetGenericTypeDefinition Is GetType(Nullable)) - Jonathan Allen
这实际上不是VB的正确翻译,出乎意料的。看看我的答案。 - Brian MacKay
是的,NullableNullable<> 是两种不同的类型。 - Christian Hayter

1

你还可以在该类型上使用GetGenericParameters()方法。myNullableObject.GetType().GetGenericParameters()[0]应该会给你它是哪种可空类型(比如GuidInt32等)的类型。


0

@Mendelt Siebenga:只有在变量未设置为null时,才能调用值属性上的GetType;否则,您将会得到一个异常。

您想要做的是使用“GetValueOrDefault”属性,并在其上调用GetType,因为您保证它不会为null。例如:

Dim i As Nullable(Of Integer) = Nothing
Dim t As Type = i.GetValueOrDefault().GetType()

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接