92

I examine the properties of an object via reflection and continue processing the data type of each property. Here is my (reduced) source:

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

My problem is, that I newly need to handle nullable properties, but I have no clue how to get the type of a nullable property.

Pranay Rana
  • 175,020
  • 35
  • 237
  • 263
user705274
  • 923
  • 1
  • 6
  • 6

6 Answers6

149

possible solution:

    propertyType = propertyInfo[propertyInfoIndex].PropertyType;
    if (propertyType.IsGenericType &&
        propertyType.GetGenericTypeDefinition() == typeof(Nullable<>))
    {
      propertyType = propertyType.GetGenericArguments()[0];
    }
Pranay Rana
  • 175,020
  • 35
  • 237
  • 263
Markus
  • 4,487
  • 3
  • 41
  • 51
  • 2
    The correct check for Nullables is also mentioned on MSDN: http://msdn.microsoft.com/en-us/library/ms366789.aspx. There, you can find some more resources on the topic, if needed. – Oliver Jan 23 '13 at 09:49
  • 94
    **Can be done in one line!** : `propertyType = Nullable.GetUnderlyingType(propertyType) ?? propertyType` – Yves M. Mar 28 '14 at 11:03
  • 7
    `propertyType.IsGenericType` is required indeed before `propertyType.GetGenericTypeDefinition()`, otherwise an exception is thrown. +1 – Mike de Klerk Dec 27 '15 at 13:36
38

Nullable.GetUnderlyingType(fi.FieldType) will do the work for you check below code for do the thing you want

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
  • 175,020
  • 35
  • 237
  • 263
  • 5
    I like the `Nullable.GetUnderlyingType(type)` solution because it is more explicit than `type.GetGenericArguments()[0]`, at least in this case. – Oliver Jan 23 '13 at 09:47
  • 6
    You **don't need to check IsGenericType and GetGenericTypeDefinition**, `Nullable.GetUnderlyingType` already do that natively. GetUnderlyingType is returning null when the type is not Nullable<> (source: http://msdn.microsoft.com/en-US/library/system.nullable.getunderlyingtype(v=vs.110).aspx) – Yves M. Mar 28 '14 at 10:53
21
foreach (var info in typeof(T).GetProperties())
{
  var type = info.PropertyType;
  var underlyingType = Nullable.GetUnderlyingType(type);
  var returnType = underlyingType ?? type;
}
Dave
  • 10,748
  • 3
  • 43
  • 54
Minh Giang
  • 631
  • 9
  • 28
5

As pointed out by Yves M. it is as simple as below.

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

  foreach (var prop in properties)
  {
     var propType = Nullable.GetUnderlyingType(prop.PropertyType) ?? prop.PropertyType;
     var dataType = propType.Name;
  }
Amir
  • 1,855
  • 3
  • 24
  • 40
0

I am using a loop to go through all class properties to get the property type. I use the following code:

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
  • 1,272
  • 9
  • 16
-1

This method is easy, fast and safe

public static class PropertyInfoExtension {
    public static bool IsNullableProperty(this PropertyInfo propertyInfo)
        => propertyInfo.PropertyType.Name.IndexOf("Nullable`", StringComparison.Ordinal) > -1;
}
muratoner
  • 2,316
  • 3
  • 20
  • 32