VB.NET从可为空的类型获取基础的system.type

时间:2020-03-05 18:45:34  来源:igfitidea点击:

我正在尝试根据对象的属性创建数据集。例如,我有一个Person类的实例,该实例的属性包括ID,Forename,Surname,DOB等。使用反射,我根据对象属性将列添加到新数据集中:

For Each pi As PropertyInfo In person.GetType().GetProperties()
    Dim column As New DataColumn(pi.Name, pi.PropertyType)
    table.Columns.Add(column)
Next

我的问题是其中一些属性是可为空的类型,数据集不支持这些类型。有什么方法可以从可为空的类型中提取基础系统类型?

谢谢。

解决方案

回答

我猜问题出在识别该属性是否可为空。在Cyou中,使用以下代码执行此操作:

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

...但是我不确定VB.NET中最后一个子句的等效形式是什么。

回答

@Mendelt Siebenga:如果变量未设置为null,则只能在value属性上调用GetType。否则,我们将获得一个例外。

我们想要做的是使用" GetValueOrDefault"属性,并对该属性调用GetType,因为可以保证它不会为null。例子:

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

回答

我们也可以在该类型上使用GetGenericParameters()方法。 myNullableObject.GetType()。GetGenericParameters()[0]应该为我们提供可为空的类型(例如,Guid,Int32等)。

回答

这是我们在VB中的答案。就目的而言,这可能是过大的杀伤力,但对其他一些人也可能有用。

首先,下面的代码可以确定我们是否正在处理Nullable类型:

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工具中,我试图将值转换为可能为Null或者不能为Nullable的通用类型:

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.GetUnderylingType(myType)

将返回基础类型;如果它不是可为null的类型,则返回null。