How to check if an object is nullable?
How do I check if a given object is nullable in other words how to implement the following method...
bool IsNullableValueType(object o)
{
...
}
I am looking for nullable value types. I didn't have reference types in mind.
//Note: This is just a sample. The code has been simplified
//to fit in a post.
public class BoolContainer
{
bool? myBool = true;
}
var bc = new BoolContainer();
const BindingFlags bindingFlags = BindingFlags.Public
| BindingFlags.NonPublic
| BindingFlags.Instance
;
object obj;
object o = (object)bc;
foreach (var fieldInfo in o.GetType().GetFields(bindingFlags))
{
obj = (object)fieldInfo.GetValue(o);
}
obj
now refers to an object of type bool
(System.Boolean
) with value equal to true
. What I really wanted was an object of type Nullable<bool>
So now as a work around I decided to check if o is nullable and create a nullable wrapper around obj.
Solution 1:
There are two types of nullable - Nullable<T>
and reference-type.
Jon has corrected me that it is hard to get type if boxed, but you can with generics:
- so how about below. This is actually testing type T
, but using the obj
parameter purely for generic type inference (to make it easy to call) - it would work almost identically without the obj
param, though.
static bool IsNullable<T>(T obj)
{
if (obj == null) return true; // obvious
Type type = typeof(T);
if (!type.IsValueType) return true; // ref-type
if (Nullable.GetUnderlyingType(type) != null) return true; // Nullable<T>
return false; // value-type
}
But this won't work so well if you have already boxed the value to an object variable.
Microsoft documentation: https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/nullable-types/how-to-identify-a-nullable-type
Solution 2:
There is a very simple solution using method overloads
http://deanchalk.com/is-it-nullable/
excerpt:
public static class ValueTypeHelper
{
public static bool IsNullable<T>(T t) { return false; }
public static bool IsNullable<T>(T? t) where T : struct { return true; }
}
then
static void Main(string[] args)
{
int a = 123;
int? b = null;
object c = new object();
object d = null;
int? e = 456;
var f = (int?)789;
bool result1 = ValueTypeHelper.IsNullable(a); // false
bool result2 = ValueTypeHelper.IsNullable(b); // true
bool result3 = ValueTypeHelper.IsNullable(c); // false
bool result4 = ValueTypeHelper.IsNullable(d); // false
bool result5 = ValueTypeHelper.IsNullable(e); // true
bool result6 = ValueTypeHelper.IsNullable(f); // true
Solution 3:
This works for me and seems simple:
static bool IsNullable<T>(T obj)
{
return default(T) == null;
}
For value types:
static bool IsNullableValueType<T>(T obj)
{
return default(T) == null && typeof(T).BaseType != null && "ValueType".Equals(typeof(T).BaseType.Name);
}