我想通过反射设置一个对象的属性,值类型为字符串。
例如,假设我有一个Ship类,它的纬度属性是double。
这是我想做的:
Ship ship = new Ship();
string value = "5.5";
PropertyInfo propertyInfo = ship.GetType().GetProperty("Latitude");
propertyInfo.SetValue(ship, value, null);
这将抛出一个ArgumentException:
类型为System的对象。字符串'不能转换为'System.Double'类型。
如何将值转换为适当的类型,基于propertyInfo?
你可以使用类型转换器(没有错误检查):
Ship ship = new Ship();
string value = "5.5";
var property = ship.GetType().GetProperty("Latitude");
var convertedValue = property.Converter.ConvertFrom(value);
property.SetValue(self, convertedValue);
在组织代码方面,你可以创建一种mixin,结果是这样的代码:
Ship ship = new Ship();
ship.SetPropertyAsString("Latitude", "5.5");
这将通过以下代码实现:
public interface MPropertyAsStringSettable { }
public static class PropertyAsStringSettable {
public static void SetPropertyAsString(
this MPropertyAsStringSettable self, string propertyName, string value) {
var property = TypeDescriptor.GetProperties(self)[propertyName];
var convertedValue = property.Converter.ConvertFrom(value);
property.SetValue(self, convertedValue);
}
}
public class Ship : MPropertyAsStringSettable {
public double Latitude { get; set; }
// ...
}
MPropertyAsStringSettable可以被许多不同的类重用。
你也可以创建你自己的自定义类型转换器来附加到你的属性或类:
public class Ship : MPropertyAsStringSettable {
public Latitude Latitude { get; set; }
// ...
}
[TypeConverter(typeof(LatitudeConverter))]
public class Latitude { ... }
如果你正在编写Metro应用程序,你应该使用其他代码:
Ship ship = new Ship();
string value = "5.5";
PropertyInfo propertyInfo = ship.GetType().GetTypeInfo().GetDeclaredProperty("Latitude");
propertyInfo.SetValue(ship, Convert.ChangeType(value, propertyInfo.PropertyType));
注意:
ship.GetType().GetTypeInfo().GetDeclaredProperty("Latitude");
而不是
ship.GetType().GetProperty("Latitude");