通过使用string值进行reflection来设置属性
我想通过Reflection来设置一个对象的属性,其值为stringtypes。 所以,举个例子,假设我有一个Ship类, Latitude属性是double 。 
这是我想要做的:
 Ship ship = new Ship(); string value = "5.5"; PropertyInfo propertyInfo = ship.GetType().GetProperty("Latitude"); propertyInfo.SetValue(ship, value, null); 
 就这样,这将抛出一个ArgumentException : 
“System.String”types的对象不能转换为“System.Double”types。
 如何根据propertyInfo将值转换为正确的types? 
 您可以使用Convert.ChangeType() – 它允许您使用任何IConvertibletypes的运行时信息来更改表示forms。 但是,并非所有的转换都是可能的,如果您要支持非IConvertibletypes的转换,则可能需要编写特殊情况逻辑。 
相应的代码(没有exception处理或特殊情况逻辑)将是:
 Ship ship = new Ship(); string value = "5.5"; PropertyInfo propertyInfo = ship.GetType().GetProperty("Latitude"); propertyInfo.SetValue(ship, Convert.ChangeType(value, propertyInfo.PropertyType), null); 
 正如其他几个人所说,你想使用Convert.ChangeType : 
 propertyInfo.SetValue(ship, Convert.ChangeType(value, propertyInfo.PropertyType), null); 
 事实上,我build议你看看整个Convert类 。 
 这个类和许多其他有用的类是System Namespace的一部分。 我觉得每年都要扫描一下这个命名空间是很有用的,看看我错过了什么function。 试一试! 
 我注意到很多人推荐Convert.ChangeType – 这对一些情况有效,但是一旦你开始涉及nullabletypes,你将开始接收InvalidCastExceptions : 
几年前写了一个包装器来处理这个问题,但这并不完美。
你可以使用一个types转换器(无错误检查):
 Ship ship = new Ship(); string value = "5.5"; var property = ship.GetType().GetProperty("Latitude"); var convertedValue = property.Converter.ConvertFrom(value); property.SetValue(self, convertedValue); 
就组织代码而言,你可以创build一种类似的混合 ,这将导致代码如下所示:
 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可以重用于许多不同的类。 
您也可以创build自己的自定义types转换器来附加到您的属性或类:
 public class Ship : MPropertyAsStringSettable { public Latitude Latitude { get; set; } // ... } [TypeConverter(typeof(LatitudeConverter))] public class Latitude { ... } 
 您可能正在寻找Convert.ChangeType方法。 例如: 
 Ship ship = new Ship(); string value = "5.5"; PropertyInfo propertyInfo = ship.GetType().GetProperty("Latitude"); propertyInfo.SetValue(ship, Convert.ChangeType(value, propertyInfo.PropertyType), null); 
 使用Convert.ChangeType获取要从PropertyInfo.PropertyType转换的types。 
 propertyInfo.SetValue( ship, Convert.ChangeType( value, propertyInfo.PropertyType ), null ); 
或者你可以尝试:
 propertyInfo.SetValue(ship, Convert.ChangeType(value, propertyInfo.PropertyType), null); //But this will cause problems if your string value IsNullOrEmplty... 
如果您正在编写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"); 
我试着从LBushkin的答案,它的工作很好,但它不会工作的空值和可为空字段。 所以我改变了这个:
 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); } 
你是否在寻找反思,或者你正在寻找一个生产软件? 我会质疑你为什么使用reflection设置属性。
 Double new_latitude; Double.TryParse (value, out new_latitude); ship.Latitude = new_latitude;