Convert.ChangeType() fails on Nullable Types

Viewed 87668

I want to convert a string to an object property value, whose name I have as a string. I am trying to do this like so:

string modelProperty = "Some Property Name";
string value = "SomeValue";
var property = entity.GetType().GetProperty(modelProperty);
if (property != null) {
    property.SetValue(entity, 
        Convert.ChangeType(value, property.PropertyType), null);
}

The problem is this is failing and throwing an Invalid Cast Exception when the property type is a nullable type. This is not the case of the values being unable to be Converted - they will work if I do this manually (e.g. DateTime? d = Convert.ToDateTime(value);) I've seen some similiar questions but still can't get it to work.

7 Answers

This works perfectly even for Nullable types:

TypeConverter conv = TypeDescriptor.GetConverter(type);
return conv.ConvertFrom(value);

For type safety you should also call conv.CanConvertFrom(type) method before calling ConvertFrom(). In case it returns false you can fallback to ChangeType or something else.

I did it in this way

public static List<T> Convert<T>(this ExcelWorksheet worksheet) where T : new()
    {
        var result = new List<T>();
        int colCount = worksheet.Dimension.End.Column;  //get Column Count
        int rowCount = worksheet.Dimension.End.Row;

        for (int row = 2; row <= rowCount; row++)
        {
            var obj = new T();
            for (int col = 1; col <= colCount; col++)
            {

                var value = worksheet.Cells[row, col].Value?.ToString();
                PropertyInfo propertyInfo = obj.GetType().GetProperty(worksheet.Cells[1, col].Text);
                propertyInfo.SetValue(obj, Convert.ChangeType(value, Nullable.GetUnderlyingType(propertyInfo.PropertyType) ?? propertyInfo.PropertyType), null);

            }
            result.Add(obj);
        }

        return result;
    }
Related