【问题标题】:Is there any way to test my conversions to avoid using exceptions?有什么方法可以测试我的转换以避免使用异常?
【发布时间】:2011-10-25 23:45:09
【问题描述】:

我正在使用反射从 DataRows 构造任意对象,当橡胶最终遇到道路时,我需要从 DataRow 中获取一个值并将其分配给对象上的属性。

因为 DataRows 可能充满了不支持转换的类型,其中许多会导致必须处理的异常。例如,DBnulls 可能会出现在 DataRow 中,或者某些不能很好地转换为另一种格式的数字格式,等等。有什么办法可以避免抛出异常吗? (我不会接受检查目标对象属性和源数据中每种类型组合的巨大 switch 语句。)

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 转换之前,有什么办法可以查看?


解决方案

感谢 Stecya,这就是我想出的:

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

逻辑上等价,优雅,没有更多的例外!

【问题讨论】:

    标签: c# .net-4.0 exception-handling


    【解决方案1】:

    使用TypeConverter检查是否可以在类型之间进行转换

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

    您还可以使用此 TypeConverter 将一种类型实际转换为另一种类型

    【讨论】:

    • 是否保证如果TypeDescriptor.GetConverter(Type T)为null或者.CanConvertFrom(Type R)为false,那么Convert.ChangeType(T obj, type R)会失败?我不想关闭任何本来可以成功的转化。
    • 应该可以,但是如果你想确定不要使用 TypeConverter 来改变类型
    【解决方案2】:

    您可以使用Visitor pattern。这是让函数为您进行类型检查的一种优雅方式。

    【讨论】:

    • 访客模式不适用。如您所见,我所有的转换都是伪原始类型 - 我无法进入并更改这些本机类型的代码以实现从 DataRow 类型转换的通用方法。
    • 可以添加扩展方法。
    猜你喜欢
    • 2012-02-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-25
    • 2014-05-24
    • 1970-01-01
    • 2020-09-07
    • 1970-01-01
    • 2018-02-11
    相关资源
    最近更新 更多