I have a string and a Type, and I want to return the string value converted to that Type.
public static object StringToType(string value, Type propertyType)
{
return Convert.ChangeType(value, propertyType, CultureInfo.InvariantCulture);
}
This returns an object that I can use in a property set value call:
public static void SetBasicPropertyValueFromString(object target,
string propName,
string value)
{
PropertyInfo prop = target.GetType().GetProperty(propName);
object converted = StringToType(value, prop.PropertyType);
prop.SetValue(target, converted, null);
}
This works for most basic types, except nullables.
[TestMethod]
public void IntTest()
{ //working
Assert.AreEqual(1, ValueHelper.StringToType("1", typeof (int)));
Assert.AreEqual(123, ValueHelper.StringToType("123", typeof (int)));
}
[TestMethod]
public void NullableIntTest()
{ //not working
Assert.AreEqual(1, ValueHelper.StringToType("1", typeof (int?)));
Assert.AreEqual(123, ValueHelper.StringToType("123", typeof (int?)));
Assert.AreEqual(null, ValueHelper.StringToType(null, typeof (int?)));
}
NullableIntTest fails on first line with:
System.InvalidCastException: Invalid cast from ‘System.String’ to ‘System.Nullable`1[[System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]’.
I’m having difficulty detemining if the type is nullable and changing the behaiour of the StringToType method.
Behaviour I am after:
If string is null or empty, return null, else convert as per the non-nullable type.
Result
Like Kirill’s answer, only with one ChangeType call.
public static object StringToType(string value, Type propertyType)
{
var underlyingType = Nullable.GetUnderlyingType(propertyType);
if (underlyingType != null)
{
//an underlying nullable type, so the type is nullable
//apply logic for null or empty test
if (String.IsNullOrEmpty(value)) return null;
}
return Convert.ChangeType(value,
underlyingType ?? propertyType,
CultureInfo.InvariantCulture);
}
You cannot use Convert.ChangeType on nullable types cause it is not inherited from IConvertible. You should rewrite your method.