Найдите тип свойств, допускающих значение NULL, через отражение

84

Я исследую свойства объекта через отражение и продолжаю обрабатывать тип данных каждого свойства. Вот мой (сокращенный) источник:

private void ExamineObject(object o)
{
  Type type = default(Type);
  Type propertyType = default(Type);
  PropertyInfo[] propertyInfo = null;

  type = o.GetType();

  propertyInfo = type.GetProperties(BindingFlags.GetProperty |
                                    BindingFlags.Public |
                                    BindingFlags.NonPublic |
                                    BindingFlags.Instance);
  // Loop over all properties
  for (int propertyInfoIndex = 0; propertyInfoIndex <= propertyInfo.Length - 1; propertyInfoIndex++)
  {
    propertyType = propertyInfo[propertyInfoIndex].PropertyType;
  }
}

Моя проблема в том, что мне недавно нужно обрабатывать свойства, допускающие значение NULL, но я не знаю, как получить тип свойства, допускающего значение NULL.

user705274
источник
Я нахожу здесь хороший ответ, который стоит попробовать !!
Ицхак Вайнберг,

Ответы:

132

возможное решение:

    propertyType = propertyInfo[propertyInfoIndex].PropertyType;
    if (propertyType.IsGenericType &&
        propertyType.GetGenericTypeDefinition() == typeof(Nullable<>))
    {
      propertyType = propertyType.GetGenericArguments()[0];
    }
Маркус
источник
2
Правильная проверка значений Nullables также упоминается в MSDN: msdn.microsoft.com/en-us/library/ms366789.aspx . Там вы можете найти дополнительные ресурсы по теме, если это необходимо.
Оливер
78
Можно сделать одной строкой! :propertyType = Nullable.GetUnderlyingType(propertyType) ?? propertyType
Yves M.
6
propertyType.IsGenericTypeдействительно требуется раньше propertyType.GetGenericTypeDefinition(), иначе возникает исключение. +1
Майк де Клерк
37

Nullable.GetUnderlyingType(fi.FieldType) выполнит работу за вас, проверьте код ниже, чтобы сделать то, что вы хотите

System.Reflection.FieldInfo[] fieldsInfos = typeof(NullWeAre).GetFields();

        foreach (System.Reflection.FieldInfo fi in fieldsInfos)
        {
            if (fi.FieldType.IsGenericType
                && fi.FieldType.GetGenericTypeDefinition().Equals(typeof(Nullable<>)))
            {
                // We are dealing with a generic type that is nullable
                Console.WriteLine("Name: {0}, Type: {1}", fi.Name, Nullable.GetUnderlyingType(fi.FieldType));
            }

    }
Праная Рана
источник
5
Мне нравится Nullable.GetUnderlyingType(type)решение, потому что оно более явное, чем type.GetGenericArguments()[0], по крайней мере, в этом случае.
Оливер
6
Вам не нужно проверять IsGenericType и GetGenericTypeDefinition , это Nullable.GetUnderlyingTypeуже сделано изначально. GetUnderlyingType возвращает значение null, если тип не имеет значения Nullable <> (источник: msdn.microsoft.com/en-US/library/… )
Ив М.
15
foreach (var info in typeof(T).GetProperties())
{
  var type = info.PropertyType;
  var underlyingType = Nullable.GetUnderlyingType(type);
  var returnType = underlyingType ?? type;
}
Минь Джианг
источник
1

Как указал Ив М., это так просто, как показано ниже.

var properties = typeof(T).GetProperties();

  foreach (var prop in properties)
  {
     var propType = Nullable.GetUnderlyingType(prop.PropertyType) ?? prop.PropertyType;
     var dataType = propType.Name;
  }
Амир
источник
0

Я использую цикл, чтобы просмотреть все свойства класса, чтобы получить тип свойства. Я использую следующий код:

public Dictionary<string, string> GetClassFields(TEntity obj)
{
    Dictionary<string, string> dctClassFields = new Dictionary<string, string>();

    foreach (PropertyInfo property in obj.GetType().GetProperties())
    {
        if (property.PropertyType.IsGenericType && property.PropertyType.GetGenericTypeDefinition() == typeof(Nullable<>) && property.PropertyType.GetGenericArguments().Length > 0)
            dctClassFields.Add(property.Name, property.PropertyType.GetGenericArguments()[0].FullName);
        else
            dctClassFields.Add(property.Name, property.PropertyType.FullName);
    }

    return dctClassFields;
}
mbadeveloper
источник
0

Этот способ простой, быстрый и безопасный

public static class PropertyInfoExtension {
    public static bool IsNullableProperty(this PropertyInfo propertyInfo)
        => propertyInfo.PropertyType.Name.IndexOf("Nullable`", StringComparison.Ordinal) > -1;
}
Мурат ОНЕР
источник