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.


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

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

    }

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

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

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

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;
  }
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.