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

Я использую отражение для заполнения свойств объекта.

Эти свойства имеют разные типы: String, Nullable (double) и Nullable (long) (не знаю, как избежать угловых скобок здесь ...). Значения этих свойств берутся из словаря пар (строка, объект).

Так, например, мой класс имеет следующие свойства:

string Description { get; set; } 
Nullable<long> Id { get; set; }
Nullable<double> MaxPower { get; set; }

(на самом деле их около дюжины), и в словаре будут такие записи, как ‹" Description "," A description ">,‹ "Id", 123456>, ‹" MaxPower ", 20000>.

Теперь я использую что-то вроде следующего для установки значений:

foreach (PropertyInfo info in this.GetType().GetProperties())
{
    if (info.CanRead)
    {
         object thisPropertyValue = dictionary[info.Name];

         if (thisPropertyValue != null && info.CanWrite)
         {
             Type propertyType = info.PropertyType;

             if (propertyType == typeof(String))
             {
                 info.SetValue(this, Convert.ToString(thisPropertyValue), null);
             }
             else if (propertyType == typeof(Nullable<double>))
             {
                 info.SetValue(this, Convert.ToDouble(thisPropertyValue), null);
             }
             else if (propertyType == typeof(Nullable<long>))
             {
                 info.SetValue(this, Convert.ToInt64(thisPropertyValue), null);
             }
             else
             {
                 throw new ApplicationException("Unexpected property type");
             }
         }
     }
}

Возникает вопрос: действительно ли мне нужно проверять тип каждого свойства перед присвоением значения? Есть ли что-нибудь похожее на приведение, которое я могу выполнить, чтобы значению свойства был присвоен тип соответствующего свойства?

В идеале я хотел бы иметь возможность сделать что-то вроде следующего (что, как я наивно думал, могло сработать):

         if (thisPropertyValue != null && info.CanWrite)
         {
             Type propertyType = info.PropertyType;

             if (propertyType == typeof(String))
             {
                 info.SetValue(this, (propertyType)thisPropertyValue, null);
             }
        }

Спасибо, Стефано


person Stefano Ricciardi    schedule 14.05.2009    source источник


Ответы (1)


Если значения уже имеют правильный тип, тогда нет: ничего делать не нужно. Если они могут быть неправильными (int vs float и т. Д.), Простой подход может быть таким:

(изменить с поправкой на нули)

Type propertyType = info.PropertyType;
if (thisPropertyValue != null)
{
    Type underlyingType = Nullable.GetUnderlyingType(propertyType);
    thisPropertyValue = Convert.ChangeType(
        thisPropertyValue, underlyingType ?? propertyType);
}
info.SetValue(this, thisPropertyValue, null);
person Marc Gravell    schedule 14.05.2009
comment
Я собирался предложить просто попробовать info.SetValue (this, thisPropertyValue, null); но это кажется лучшим решением. - person ChrisF; 14.05.2009
comment
+1 для метода Convert.ChangeType. Это отличное решение, позволяющее избежать ошибок в коде. - person Darin Dimitrov; 14.05.2009
comment
@Marc: Спасибо, это помогло;) @ ChrisF: info.SetValue (this, thisPropertyValue, null) вызвал исключение при попытке преобразовать int в double в одном из моих тестовых случаев. - person Stefano Ricciardi; 14.05.2009
comment
@Stefano - это было всего лишь предположение;) - person ChrisF; 15.05.2009