Есть ли способ проверить мои конверсии, чтобы избежать использования исключений? - PullRequest
6 голосов
/ 25 октября 2011

Я строю произвольные объекты из DataRows с помощью Reflection, и когда резина наконец встречает дорогу, мне нужно взять значение из DataRow и присвоить его свойству объекта.

Поскольку в DataRows могут быть типы, которые не поддерживают преобразование, многие из них приводят к исключениям, которые необходимо обработать. Например, DBnulls может заползти в DataRow или какой-либо числовой формат, который не преобразуется в другой, и т. Д. Есть ли способ избежать исключений? (Я не приму проверку гигантских операторов переключения для каждой комбинации типов в свойстве целевого объекта и исходных данных.)

public void Merge(DataRow data)
{
  PropertyInfo[] props = this.GetType().GetProperties(BindingFlags...);
  foreach (PropertyInfo pi in props.Where(p => T_IsPrimitive(p.PropertyType)))
  {
    object src = null;
    if( dataAsDataRow.Table.Columns.Contains(pi.Name) )
       src = ((DataRow)data)[pi.Name];
    if (src != null)
    {
       if( src.GetType() != pi.PropertyType ) {
        try {
            src = Convert.ChangeType(src, pi.PropertyType);
        } catch(InvalidCastException e) {
            try { src = Convert.ChangeType(src.ToString(), pi.PropertyType); }
            catch { throw e; }
        }
       }
       pi.SetValue(this, src, null);
    }
  }
}

public bool T_IsPrimitive(Type t)
{
   return t.IsPrimitive || t == typeof(Decimal) || t == typeof(String) ||
          t == typeof(DateTime) || t == typeof(TimeSpan)
}

Так есть ли способ посмотреть, прежде чем я прыгну с этими ChangeType преобразованиями?


РЕШЕНИЕ

Благодаря Стеце, вот что я придумала:

     if( src.GetType() != pi.PropertyType ) {
        object converted = null;
        TypeConverter converter = TypeDescriptor.GetConverter(pi.PropertyType);
        if( converter != null ) {
           if( converter.CanConvertFrom(vType) )
              converted = converter.ConvertFrom(src);
           else if( converter.CanConvertFrom(typeof(String)) )
              converted = converter.ConvertFrom(src.ToString());
        }
        src = converted;
     }
     if( src != null )
        pi.SetValue(this, src, null);

Логически эквивалентный, элегантный, и больше никаких исключений!

Ответы [ 2 ]

6 голосов
/ 25 октября 2011

Используйте TypeConverter , чтобы проверить, можете ли вы конвертировать между типами

bool CanConvert(Type from , Type to)
{
    TypeConverter converter = TypeDescriptor.GetConverter(to);
    return converter != null && converter.CanConvertFrom(from);
}

Также вы можете использовать этот TypeConverter для фактического преобразования из одного типа в другой

0 голосов
/ 25 октября 2011

Вы можете использовать Шаблон посетителя . Это элегантный способ заставить функции выполнять проверку типов для вас.

...