Znajdź typ właściwości dopuszczających wartość null za pomocą odbicia

84

Badam właściwości obiektu poprzez odbicie i kontynuuję przetwarzanie typu danych każdej właściwości. Oto moje (zredukowane) źródło:

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

Mój problem polega na tym, że na nowo muszę obsłużyć właściwości dopuszczające wartość null, ale nie mam pojęcia, jak uzyskać typ właściwości dopuszczającej wartość null.

user705274
źródło
Znajduję tutaj dobrą odpowiedź , którą warto wypróbować!
Yitzhak Weinberg

Odpowiedzi:

132

możliwe rozwiązanie:

    propertyType = propertyInfo[propertyInfoIndex].PropertyType;
    if (propertyType.IsGenericType &&
        propertyType.GetGenericTypeDefinition() == typeof(Nullable<>))
    {
      propertyType = propertyType.GetGenericArguments()[0];
    }
Markus
źródło
2
Prawidłowe sprawdzenie wartości Nullables jest również wymienione w witrynie MSDN: msdn.microsoft.com/en-us/library/ms366789.aspx . W razie potrzeby możesz tam znaleźć więcej zasobów na ten temat.
Oliver
78
Można to zrobić w jednej linii! :propertyType = Nullable.GetUnderlyingType(propertyType) ?? propertyType
Yves M.
6
propertyType.IsGenericTypejest rzeczywiście wymagana wcześniej propertyType.GetGenericTypeDefinition(), w przeciwnym razie zostanie zgłoszony wyjątek. +1
Mike de Klerk
37

Nullable.GetUnderlyingType(fi.FieldType) wykona pracę za Ciebie, sprawdź poniższy kod, aby zrobić to, co chcesz

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
źródło
5
Podoba mi się to Nullable.GetUnderlyingType(type)rozwiązanie, ponieważ jest bardziej jednoznaczne niż type.GetGenericArguments()[0], przynajmniej w tym przypadku.
Oliver
6
Nie musisz sprawdzać IsGenericType i GetGenericTypeDefinition , Nullable.GetUnderlyingTypejuż zrób to natywnie. GetUnderlyingType zwraca wartość null, gdy typ nie ma wartości Nullable <> (źródło: msdn.microsoft.com/en-US/library/… )
Yves M.
15
foreach (var info in typeof(T).GetProperties())
{
  var type = info.PropertyType;
  var underlyingType = Nullable.GetUnderlyingType(type);
  var returnType = underlyingType ?? type;
}
Minh Giang
źródło
1

Jak zauważył Yves M., jest to tak proste, jak poniżej.

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

  foreach (var prop in properties)
  {
     var propType = Nullable.GetUnderlyingType(prop.PropertyType) ?? prop.PropertyType;
     var dataType = propType.Name;
  }
Amir
źródło
0

Używam pętli, aby przejść przez wszystkie właściwości klasy, aby uzyskać typ właściwości. Używam następującego kodu:

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
źródło
0

Ta metoda jest łatwa, szybka i bezpieczna

public static class PropertyInfoExtension {
    public static bool IsNullableProperty(this PropertyInfo propertyInfo)
        => propertyInfo.PropertyType.Name.IndexOf("Nullable`", StringComparison.Ordinal) > -1;
}
Murat ÖNER
źródło