88 votes

Trouver le type de propriétés nullables par réflexion

J'examine les propriétés d'un objet par réflexion et je continue à traiter le type de données de chaque propriété. Voici ma source (réduite) :

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

Mon problème est que j'ai récemment besoin de gérer des propriétés nullables, mais je n'ai aucune idée de la façon d'obtenir le type d'une propriété nullable.

0 votes

Je trouve bonne Réponse aquí vaut la peine d'être essayé !

141voto

Markus Points 2472

Solution possible :

    propertyType = propertyInfo[propertyInfoIndex].PropertyType;
    if (propertyType.IsGenericType &&
        propertyType.GetGenericTypeDefinition() == typeof(Nullable<>))
    {
      propertyType = propertyType.GetGenericArguments()[0];
    }

2 votes

La vérification correcte des Nullables est également mentionnée sur MSDN : msdn.microsoft.com/en-us/library/ms366789.aspx . Vous y trouverez d'autres ressources sur le sujet, si nécessaire.

88 votes

Peut se faire en une seule ligne ! : propertyType = Nullable.GetUnderlyingType(propertyType) ?? propertyType

7 votes

propertyType.IsGenericType est en effet nécessaire avant que propertyType.GetGenericTypeDefinition() sinon une exception est levée. +1

37voto

Pranay Rana Points 69934

Nullable.GetUnderlyingType(fi.FieldType) fera le travail pour vous vérifiez le code ci-dessous pour faire ce que vous voulez

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 votes

J'aime la Nullable.GetUnderlyingType(type) parce qu'elle est plus explicite que la solution type.GetGenericArguments()[0] du moins dans ce cas.

6 votes

Usted il n'est pas nécessaire de vérifier IsGenericType et GetGenericTypeDefinition , Nullable.GetUnderlyingType le font déjà de manière native. GetUnderlyingType retourne null lorsque le type n'est pas Nullable<> (source : msdn.microsoft.com/en-US/library/ )

18voto

Minh Giang Points 31
foreach (var info in typeof(T).GetProperties())
{
  var type = info.PropertyType;
  var underlyingType = Nullable.GetUnderlyingType(type);
  var returnType = underlyingType ?? type;
}

2voto

Amir Points 352

Comme l'a souligné Yves M. c'est aussi simple que ci-dessous.

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

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

0voto

mbadeveloper Points 824

J'utilise une boucle pour parcourir toutes les propriétés de la classe afin d'obtenir le type de propriété. J'utilise le code suivant :

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

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X