How to convert value from object to Nullable <>

I have a class with some properties and I want to convert values ​​from string to the type of those properties. And I have a problem converting to nullable types. This is my conversion method:

public static object ChangeType(object value, Type type)
{
    if (type.IsGenericType && type.GetGenericTypeDefinition().Equals(typeof(Nullable<>)))
    {
        if (value == null)
        {
            return null;
        }

        var underlyingType = Nullable.GetUnderlyingType(type);
        var val = Convert.ChangeType(value, underlyingType);
        var nullableVal = Convert.ChangeType(val, type); // <-- Exception here
        return nullableVal;
    }

    return Convert.ChangeType(value, type);
}

      

I am getting an exception like this (for a property of type int?):

Invalid listing from 'System.Int32' to 'System.Nullable`1 [[System.Int32, mscorlib, Version = 4.0.0.0, Culture = neutral, PublicKeyToken = b77a5c561934e089]].

How can I convert from type to NULL type? Thank.

+3


source share


2 answers


It's impossible ... Boxing value types "erases" part Nullable<>

...

int? num = 5;
object obj = num;
Console.WriteLine(obj.GetType()); // System.Int32

      

and

int? num = null;
object obj = num;
Console.WriteLine(obj == null); // True

      



Note that this property makes it Nullable<>

"special". They need direct support from the CLR. Nullable<>

is not just a structure that you could write.

What can you do:

public static object ChangeType(object value, Type type)
{
    // returns null for non-nullable types
    Type type2 = Nullable.GetUnderlyingType(type);

    if (type2 != null)
    {
        if (value == null)
        {
            return null;
        }

        type = type2;
    }

    return Convert.ChangeType(value, type);
}

      

+3


source


var nullableVal = Activator.CreateInstance(type, val);

      

Using an activator will allow you to create a new instance of the class int?

with an argument passed to the value constructor int

. The code below is a literal demonstration of this:



var type = typeof(int?);

var underlyingType = typeof(int);

var val = 123;

var nullableVal = Activator.CreateInstance(type, val);

      

0


source







All Articles