Установка свойства путем отражения со строковым значением

Я хотел бы установить свойство объекта через Reflection, со значением string типа. Например, предположим, что у меня есть class 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» не может быть преобразован в тип «System.Double».

Как преобразовать значение в правильный тип, основанный на propertyInfo ?

Вы можете использовать Convert.ChangeType() – он позволяет использовать информацию о времени выполнения для любого типа IConvertible для изменения форматов представления. Однако не все преобразования возможны, и вам может потребоваться написать специальную логику case, если вы хотите поддерживать конверсии из типов, которые не являются IConvertible .

Соответствующим кодом (без обработки исключений или специальной логикой случая) будет:

 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); 

На самом деле, я рекомендую вам посмотреть на весь class Convert .

Этот class и многие другие полезные classы являются частью System пространства имен . Мне посчастливилось сканировать это пространство имен каждый год или около того, чтобы увидеть, какие функции я пропустил. Попробуй!

Я замечаю, что многие рекомендуют Convert.ChangeType – это действительно работает для некоторых случаев, однако, как только вы начнете задействовать типы с InvalidCastExceptions nullable вы начнете получать 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

Вы можете использовать конвертер типов (без проверки ошибок):

 Ship ship = new Ship(); string value = "5.5"; var property = ship.GetType().GetProperty("Latitude"); var convertedValue = property.Converter.ConvertFrom(value); property.SetValue(self, convertedValue); 

Что касается организации кода, вы можете создать вид микширования, который приведет к созданию кода следующим образом:

 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 может быть повторно использован для разных classов.

Вы также можете создавать свои собственные преобразователи настраиваемого типа для присоединения к вашим свойствам или classам:

 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 .

 propertyInfo.SetValue( ship, Convert.ChangeType( value, propertyInfo.PropertyType ), null ); 

Я попробовал ответ от Л.Бушкина, и он отлично поработал, но он не будет работать для нулевых значений и полей с нулевым значением. Поэтому я изменил это на следующее:

 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); } 

Или вы можете попробовать:

 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"); 

Я отвечу на это общим ответом. Обычно эти ответы не работают с подсказками. Вот рабочая версия с подсказками.

 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); 

Вы хотите поиграть с Reflection или хотите создать производственную часть программного обеспечения? Я бы поставил под вопрос, почему вы используете reflection, чтобы установить свойство.

 Double new_latitude; Double.TryParse (value, out new_latitude); ship.Latitude = new_latitude; 
  • byte + byte = int ... почему?
  • В чем разница между Convert.ToInt32 и (int)?
  • Как преобразовать QString в std :: string?
  • Преобразования Java - char, int
  • Преобразование String для двойного использования в Java
  • Результат Struts2 INPUT: как он работает? Как обрабатываются ошибки преобразования / проверки?
  • Преобразование строки в дату в JavaScript
  • Как преобразовать String в InputStream в Java?
  • Как преобразовать байт UTF-8 в строку?
  • Преобразование строки в double в C #
  • Как преобразовать строку в целое число в C #
  • Давайте будем гением компьютера.