Determine if reflected property can be assigned null

13,858

Solution 1

You need to handle null references and Nullable<T>, so (in turn):

bool canBeNull = !type.IsValueType || (Nullable.GetUnderlyingType(type) != null);

Note that IsByRef is something different, that allows you to choose between int and ref int / out int.

Solution 2

From http://msdn.microsoft.com/en-us/library/ms366789.aspx

if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>))

Type would be your PropertyInfo.PropertyType

Solution 3

PropertyInfo propertyInfo = ...
bool canAssignNull = 
    !propertyInfo.PropertyType.IsValueType || 
    propertyInfo.PropertyType.IsGenericType &&
        propertyInfo.PropertyType.GetGenericTypeDefinition() == typeof(Nullable<>)

Solution 4

Marc and Jonas both have parts to determine if a generic type can be assigned null.

// A silly example. default(T) will return null if it is nullable. So no reason to check here. Except for the sake of having an example.
public U AssignValueOrDefault<U>(object item)
{
    if (item == null)
    {
        Type type = typeof(U); // Type from Generic Parameter

        // Basic Types like int, bool, struct, ... can't be null
        //   Except int?, bool?, Nullable<int>, ...
        bool notNullable = type.IsValueType ||
                           (type.IsGenericType && type.GetGenericTypeDefinition() != typeof(Nullable<>)));

        if (notNullable)
            return default(T);
    }

    return (U)item;
}

Note: Most of the time you can check if the variable is null. Then use default(T). It will return null by default of the object is a class.

Share:
13,858

Related videos on Youtube

David
Author by

David

Updated on April 03, 2022

Comments

  • David
    David about 2 years

    I wish to automagically discover some information on a provided class to do something akin to form entry. Specifically I am using reflection to return a PropertyInfo value for each property. I can read or write values to each property from my "form", but if the property is defined as "int", I would not be able to, and my program should not even try, to write a null value.

    How can I use reflection to determine if a given property can be assigned a null value, without writing a switch statement to check for every possible type? In particular I want to detect the difference between boxed types like "int" vs. "int?", since in the second case I do want to be able to write a null value. The IsValueType and IsByRef don't seem to see a difference.

    public class MyClass
    {
        // Should tell me I cannot assign a null
        public int Age {get; set;} 
        public DateTime BirthDate {get; set;}
        public MyStateEnum State {get; set;}
        public MyCCStruct CreditCard {get; set;}
    
        // Should tell me I can assign a null
        public DateTime? DateOfDeath {get; set;}
        public MyFamilyClass Famly {get; set;}
    }
    

    Note that I need to determine this information long before I actually attempt to write the value, so using exception handling wrapped around SetValue is not an option.

  • David Hedlund
    David Hedlund over 14 years
    That only returns the nullables, though. Works for DateTime?, but not for MyFamilyClass, as that's not a generic, but still a type that can be assigned a null value
  • David
    David over 14 years
    Something I didn't think about but I did test your answer against is arrays, such as int[] (which can be assigned null). Your answer worked correctly for this case as well.
  • Marc Gravell
    Marc Gravell over 14 years
    Arrays are reference-types, so they work the same as classes.
  • pqsk
    pqsk over 10 years
    I think that it should be noted that in the OP, there was examples using an int? and DateTime?, so the first check would return true (!type.IsValueType). I do like this way better than the one given in MSDN, but curious why you added what seems to be a redundant check. Maybe, because you want to deal with all cases beyond what was asked for?
  • Marc Gravell
    Marc Gravell over 10 years
    @pqsk because the questions is "...can be assigned null"; need to consider reference types
  • TamusJRoyce
    TamusJRoyce over 6 years
    Combining Marc's answer and this helped me
  • TamusJRoyce
    TamusJRoyce over 6 years
    Using PropertyInfo has more overhead than using the type directly. But may be helpful if you need the extra features for other things down the road.
  • Neville Nazerane
    Neville Nazerane over 6 years
    @MarcGravell this is just a coincidence, wasn't stalking you. I am unable to access the IsValueType but I do find it in the debugger. Do I have to use a cast?
  • Neville Nazerane
    Neville Nazerane over 6 years
    just found it. for .net core and .net standard this property is here type.GetTypeInfo().IsValueType
  • ArthNRick
    ArthNRick about 6 years
    string can be null, but not is Nullable<>