Setting a property by reflection with a string value
我想通过反射设置一个对象的属性,值类型为
我想做的是:
1 2 3 4 | Ship ship = new Ship(); string value ="5.5"; PropertyInfo propertyInfo = ship.GetType().GetProperty("Latitude"); propertyInfo.SetValue(ship, value, null); |
同样,这会抛出一个
Object of type 'System.String' cannot be converted to type 'System.Double'.
如何根据
您可以使用
相应的代码(无异常处理或特殊情况逻辑)为:
1 2 3 4 | Ship ship = new Ship(); string value ="5.5"; PropertyInfo propertyInfo = ship.GetType().GetProperty("Latitude"); propertyInfo.SetValue(ship, Convert.ChangeType(value, propertyInfo.PropertyType), null); |
正如其他一些人所说,您希望使用
1 2 3 | propertyInfo.SetValue(ship, Convert.ChangeType(value, propertyInfo.PropertyType), null); |
事实上,我建议你看看整个
这个类和许多其他有用的类都是
我注意到很多人都在推荐
http://weblogs.asp.net/pjohnson/archive/2006/02/07/Convert.ChangeType-doesn_2700_t-handle-nullables.aspx
几年前写了一个包装器来处理这个问题,但这也不完美。
http://weblogs.asp.net/pjohnson/archive/2006/02/07/Convert.ChangeType-doesn_2700_t-handle-nullables.aspx
您可以使用类型转换器(无错误检查):
1 2 3 4 5 | 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,它将导致如下代码:
1 2 |
这可以通过以下代码实现:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | 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; } // ... } |
还可以创建自己的自定义类型转换器以附加到属性或类:
1 2 3 4 5 6 7 | public class Ship : MPropertyAsStringSettable { public Latitude Latitude { get; set; } // ... } [TypeConverter(typeof(LatitudeConverter))] public class Latitude { ... } |
我尝试了lbushkin的答案,它工作得很好,但对于空值和可空字段不起作用。所以我把它改成了:
1 2 3 4 5 6 7 8 | propertyName="Latitude"; PropertyInfo propertyInfo = ship.GetType().GetProperty(propertyName); if (propertyInfo != null) { Type t = Nullable.GetUnderlyingType(propertyInfo.PropertyType) ?? propertyInfo.PropertyType; object safeValue = (value == null) ? null : Convert.ChangeType(value, t); propertyInfo.SetValue(ship, safeValue, null); } |
您可能正在寻找
1 2 3 4 | Ship ship = new Ship(); string value ="5.5"; PropertyInfo propertyInfo = ship.GetType().GetProperty("Latitude"); propertyInfo.SetValue(ship, Convert.ChangeType(value, propertyInfo.PropertyType), null); |
使用
1 2 3 | propertyInfo.SetValue( ship, Convert.ChangeType( value, propertyInfo.PropertyType ), null ); |
我将用一般性的回答来回答这个问题。通常这些答案不适用于guid。这里还有一个使用guid的工作版本。
1 2 3 4 5 6 | var stringVal="6e3ba183-89d9-e611-80c2-00155dcfb231"; // guid value as string to set var prop = obj.GetType().GetProperty("FooGuidProperty"); // property to be setted var propType = prop.PropertyType; // var will be type of guid here var valWithRealType = TypeDescriptor.GetConverter(propType).ConvertFrom(stringVal); |
或者你可以尝试:
1 2 3 | propertyInfo.SetValue(ship, Convert.ChangeType(value, propertyInfo.PropertyType), null); //But this will cause problems if your string value IsNullOrEmplty... |
如果您正在编写Metro应用程序,则应使用其他代码:
1 2 3 4 | Ship ship = new Ship(); string value ="5.5"; PropertyInfo propertyInfo = ship.GetType().GetTypeInfo().GetDeclaredProperty("Latitude"); propertyInfo.SetValue(ship, Convert.ChangeType(value, propertyInfo.PropertyType)); |
注:
1 | ship.GetType().GetTypeInfo().GetDeclaredProperty("Latitude"); |
而不是
1 | ship.GetType().GetProperty("Latitude"); |
你是想玩弄反射,还是想构建一个生产软件?我会问你为什么用反射来设置属性。
1 2 3 4 | Double new_latitude; Double.TryParse (value, out new_latitude); ship.Latitude = new_latitude; |