通过使用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

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

你可以使用一个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;