Consider the following sample code:
class SampleClass
{
public long SomeProperty { get; set; }
}
public void SetValue(SampleClass instance, decimal valu
When the Type is a Nullable Guid then none of the above proposed solutions work.
Invalid cast from 'System.DBNull
' to 'System.Guid
' exception is thrown at Convert.ChangeType
To fix that change to:
var convertedValue = value == System.DBNull.Value ? null : Convert.ChangeType(value, targetType);
Contributing to jeroenh's answer, I would add that Convert.ChangeType crashes with a null value, so the line for getting the converted value should be:
var convertedValue = value == null ? null : Convert.ChangeType(value, targetType);
The answer by Thomas is right, but I thought I would add my finding that Convert.ChangeType does not handle conversion to nullable types. To handle nullable types, I used the following code:
void SetValue(PropertyInfo info, object instance, object value)
{
var targetType = info.PropertyType.IsNullableType()
? Nullable.GetUnderlyingType(info.PropertyType)
: info.PropertyType;
var convertedValue = Convert.ChangeType(value, targetType);
info.SetValue(instance, convertedValue, null);
}
This code makes use of the following extension method:
public static class TypeExtensions
{
public static bool IsNullableType(this Type type)
{
return type.IsGenericType
&& type.GetGenericTypeDefinition().Equals(typeof(Nullable<>));
}
This is a very old question but I thought I'd chime in for ASP.NET Core Googlers.
In ASP.NET Core, .IsNullableType()
is protected (amongst other changes) so the code is a tad different. Here's @jeroenh's answer modified to work in ASP.NET Core:
void SetValue(PropertyInfo info, object instance, object value)
{
Type proptype = info.PropertyType;
if (proptype.IsGenericType && proptype.GetGenericTypeDefinition().Equals(typeof(Nullable<>)))
{
proptype = new NullableConverter(info.PropertyType).UnderlyingType;
}
var convertedValue = Convert.ChangeType(value, proptype);
info.SetValue(instance, convertedValue);
}
void SetValue(PropertyInfo info, object instance, object value)
{
info.SetValue(instance, Convert.ChangeType(value, info.PropertyType));
}
Thomas answer only works for types that implement IConvertible interface:
For the conversion to succeed, value must implement the IConvertible interface, because the method simply wraps a call to an appropriate IConvertible method. The method requires that conversion of value to conversionType be supported.
This code compile a linq expression that does the unboxing (if needed) and the conversion:
public static object Cast(this Type Type, object data)
{
var DataParam = Expression.Parameter(typeof(object), "data");
var Body = Expression.Block(Expression.Convert(Expression.Convert(DataParam, data.GetType()), Type));
var Run = Expression.Lambda(Body, DataParam).Compile();
var ret = Run.DynamicInvoke(data);
return ret;
}
The resulting lambda expression equals to (TOut)(TIn)Data where TIn is the type of the original data and TOut is the given type