Encuentre el tipo de propiedades que aceptan valores NULL mediante la reflexión

83

Examino las propiedades de un objeto a través de la reflexión y continúo procesando el tipo de datos de cada propiedad. Aquí está mi fuente (reducida):

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

Mi problema es que necesito manejar propiedades que aceptan valores NULL, pero no tengo ni idea de cómo obtener el tipo de propiedad que acepta valores NULL.

usuario705274
fuente
Encuentro una buena respuesta aquí que vale la pena intentar !!
Yitzhak Weinberg

Respuestas:

131

solución posible:

    propertyType = propertyInfo[propertyInfoIndex].PropertyType;
    if (propertyType.IsGenericType &&
        propertyType.GetGenericTypeDefinition() == typeof(Nullable<>))
    {
      propertyType = propertyType.GetGenericArguments()[0];
    }
Markus
fuente
2
La comprobación correcta de Nullables también se menciona en MSDN: msdn.microsoft.com/en-us/library/ms366789.aspx . Allí, puede encontrar más recursos sobre el tema, si es necesario.
Oliver
76
¡Se puede hacer en una línea! :propertyType = Nullable.GetUnderlyingType(propertyType) ?? propertyType
Yves M.
6
propertyType.IsGenericTypeDe hecho propertyType.GetGenericTypeDefinition(), se requiere antes , de lo contrario, se lanza una excepción. +1
Mike de Klerk
37

Nullable.GetUnderlyingType(fi.FieldType) hará el trabajo por usted, verifique el código a continuación para hacer lo que desea

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
fuente
5
Me gusta la Nullable.GetUnderlyingType(type)solución porque es más explícita que type.GetGenericArguments()[0], al menos en este caso.
Oliver
5
No es necesario que verifique IsGenericType y GetGenericTypeDefinition , Nullable.GetUnderlyingTypeya lo hace de forma nativa. GetUnderlyingType devuelve un valor nulo cuando el tipo no admite nulos <> (fuente: 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
fuente
0

Estoy usando un bucle para revisar todas las propiedades de la clase para obtener el tipo de propiedad. Yo uso el siguiente 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;
}
mbadesarrollador
fuente
0

Este método es fácil, rápido y seguro.

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

Como señala Yves M. , es tan simple como a continuación.

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

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