Я пытаюсь создать набор данных, основанный на свойствах объекта. Например, у меня есть экземпляр класса 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
Моя проблема заключается в том, что некоторые из этих свойств являются типами NULL, которые не поддерживаются наборами данных. Есть ли способ извлечь базовый тип системы из типа NULL?
Спасибо.
Ответ 1
Вот ваш ответ, в 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, я пытаюсь получить значения в общий тип, который может быть или не быть 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 задушит его... У вас может не быть этой проблемы, но моя ситуация чрезвычайно открыта.
Надеюсь, если бы я не ответил на ваш вопрос напрямую, вы можете cannibalize это и получить вас, куда вам нужно идти - но я только что реализовал это несколько минут назад, и мои тесты проходят.
Ответ 2
Nullable.GetUnderylingType(myType)
возвращает базовый тип или null, если он не является типом с нулевым значением.
Ответ 3
Вы также можете использовать метод GetGenericParameters()
для этого типа. myNullableObject.GetType().GetGenericParameters()[0]
должен указывать тип нулеустойчивости (так Guid
, Int32
и т.д.)
Ответ 4
Я предполагаю, что проблема заключается в признании того, является ли свойство нулевым или нет. В С# вы делаете это с помощью этого кода:
if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>))
... но я не уверен, что эквивалент последнего предложения в VB.NET.
Ответ 5
@Mendelt Siebenga: Вы можете вызвать GetType только для свойства value, если переменная не установлена в null; в противном случае вы получите исключение.
Что вы хотите сделать, это использовать свойство GetValueOrDefault и вызывать GetType, поскольку вам гарантировано, что он не будет равен нулю. Пример:
Dim i As Nullable(Of Integer) = Nothing
Dim t As Type = i.GetValueOrDefault().GetType()