Determine if reflected property can be assigned null
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.
Related videos on Youtube
David
Updated on April 03, 2022Comments
-
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 over 14 yearsThat 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 over 14 yearsSomething 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 over 14 yearsArrays are reference-types, so they work the same as classes.
-
pqsk over 10 yearsI 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 over 10 years@pqsk because the questions is "...can be assigned null"; need to consider reference types
-
TamusJRoyce over 6 yearsCombining Marc's answer and this helped me
-
TamusJRoyce over 6 yearsUsing 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 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 over 6 yearsjust found it. for .net core and .net standard this property is here
type.GetTypeInfo().IsValueType
-
ArthNRick about 6 yearsstring can be null, but not is Nullable<>