Nullable
is a type, not a property of a type. System.String
is nullable, but it is not a Nullable
, unlike int?
, which is a shortcut for Nullable<System.Int32>
. All reference types in C# are nullable (you can pass a null reference), while the Nullable
type can only accept a non-nullable value type as an argument.
If you want to check if a given type can accept null
as a value, you can do something like this:
bool CanBeNull<T>()
{
return default(T) == null;
}
Of course, this already makes the assumption that the default value is the null value, which isn't necessarily the case; but it will work for both reference types and Nullable
value types. If you have to deal with a value type that accepts null but not as the default value, you'll have to add it specifically. There isn't really a sure and simple way to check if a given type can be assigned null other than actually trying to assign a null value.
Indeed, what "can be assigned null" means is something that depends very much on the compiler. For example, doing something like int? someValue = null;
actually calls the constructor of int?
- it's equivalent to int? someValue = new int?();
.
If you don't know the type at compile-time (so you can't use generics), you can add a check for whether the given type is a value type:
if (!type.IsValueType) // Can be assigned null
Make sure you treat classes, value types and interfaces correctly. And of course, just being able to assign a null
value to a local/field doesn't mean it's necessarily a valid value. In the end, the decision is yours.