Encontre o tipo de propriedades anuláveis ​​por meio de reflexão

83

Eu examino as propriedades de um objeto por meio de reflexão e continuo processando o tipo de dados de cada propriedade. Aqui está minha fonte (reduzida):

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;
  }
}

Meu problema é que recentemente preciso lidar com propriedades anuláveis, mas não tenho ideia de como obter o tipo de uma propriedade anulável.

user705274
fonte
Acho boa resposta aqui vale a pena tentar !!
Yitzhak Weinberg

Respostas:

130

solução possível:

    propertyType = propertyInfo[propertyInfoIndex].PropertyType;
    if (propertyType.IsGenericType &&
        propertyType.GetGenericTypeDefinition() == typeof(Nullable<>))
    {
      propertyType = propertyType.GetGenericArguments()[0];
    }
Markus
fonte
2
A verificação correta de Nullables também é mencionada no MSDN: msdn.microsoft.com/en-us/library/ms366789.aspx . Lá, você pode encontrar mais alguns recursos sobre o assunto, se necessário.
Oliver
76
Pode ser feito em uma linha! :propertyType = Nullable.GetUnderlyingType(propertyType) ?? propertyType
Yves M.
6
propertyType.IsGenericTypeé necessário antes propertyType.GetGenericTypeDefinition(), caso contrário, uma exceção é lançada. +1
Mike de Klerk
37

Nullable.GetUnderlyingType(fi.FieldType) fará o trabalho para você, verifique o código abaixo para fazer o que você deseja

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));
            }

    }
Pranay Rana
fonte
5
Gosto da Nullable.GetUnderlyingType(type)solução porque é mais explícita do que type.GetGenericArguments()[0], pelo menos neste caso.
Oliver
5
Você não precisa verificar IsGenericType e GetGenericTypeDefinition , Nullable.GetUnderlyingTypejá faz isso nativamente. GetUnderlyingType está retornando null quando o tipo não é Nullable <> (fonte: msdn.microsoft.com/en-US/library/… )
Yves M.
14
foreach (var info in typeof(T).GetProperties())
{
  var type = info.PropertyType;
  var underlyingType = Nullable.GetUnderlyingType(type);
  var returnType = underlyingType ?? type;
}
Minh Giang
fonte
0

Estou usando um loop para percorrer todas as propriedades de classe para obter o tipo de propriedade. Eu uso o seguinte código:

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
fonte
0

Este método é fácil, rápido e seguro

public static class PropertyInfoExtension {
    public static bool IsNullableProperty(this PropertyInfo propertyInfo)
        => propertyInfo.PropertyType.Name.IndexOf("Nullable`", StringComparison.Ordinal) > -1;
}
Murat ÖNER
fonte
0

Como apontado por Yves M. , é tão simples quanto abaixo.

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

  foreach (var prop in properties)
  {
     var propType = Nullable.GetUnderlyingType(prop.PropertyType) ?? prop.PropertyType;
     var dataType = propType.Name;
  }
Amir
fonte