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

    10 Solutions collect form web for “通过使用string值进行reflection来设置属性”

    您可以使用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;