如何将对象转换为通用类型

5
如果我在C#中从数据库获取一些值,它们的类型是object。现在我想将这些值转换为类型安全的,以加载到表示datarow的对象中。因此,我认为创建一个泛型扩展方法来扩展对象会很好。
所以我构建了以下内容:
public static T ConvertToType<T>(this object value)
{
   T returnValue = default(T);
   if (value != DBNull.Value)
   {
      returnValue = (T)value;
   }

   return returnValue;
}

我可以使用这个方法将给定的数据行datarow中的不同值进行转换,如果数据库存储了null值,那么我会得到默认类型。

例如:

foreach (DataRow row in myTable.Rows)
{
   MyClass myObject = new MyClass();
   myObject.Id = row["ID"].ConvertToType<int>();
}

对于编译时,这样做是可行的。但是似乎无法将对象转换为例如int之类的值类型。因此,我认为所有值类型都必须手动处理。

所以我扩展了第一个代码块:

public static T ConvertToType<T>(this object value)
{
   T returnValue = default(T);
   if (value != DBNull.Value)
   {
      if (wert is int)
      {
        rueckgabe = Convert.ToInt32(wert);
      }
      //else if All Value-Types are following...
      else
      {
        returnValue = (T)value;
      }
   }

   return returnValue;
}

但是编译器现在告诉我目标类型 T 无法转换为 int,这很明显。

是否有人有解决这个问题的好方案?或者这并不像我希望的那样简单。
2个回答

6

这已经被实现了。

你可以使用 row.Field<int>("ID")

该扩展方法位于 System.Data 命名空间下

对于可为空字段,你可以使用 row.Field<int?>("ID"),因为 .Field 会返回 null 而不是 default(T) 来表示 DBNull。


在 .Net 4.0 中找不到。 - Sebi
@Sebi,你有包含命名空间吗?根据MSDN文档,这个命名空间早在.Net 3.5就存在了。 - Steve
找到了;)我必须包含dll System.Data.DataSetExtension。原以为System.Data就足够了。谢谢,太棒了:) - Sebi
这个方法似乎没有按预期工作。如果我的数据行中有值“1”,它无法转换为整数。我认为这应该是可能的。 - Sebi
仅当数据库字段也表示整数时才返回。 - Jan Unld
@Jan UnId 哦,好的...我们的DataTable只是存储了object值。:( - Sebi

4
尝试这个: Convert.ChangeType
public static T ConvertTo<T>(this object value)
    {
        T returnValue = default(T);

        if (value is T)
        {
            returnValue = (T)value;
        }
        else
        {
            try
            {
                returnValue = (T)Convert.ChangeType(value, typeof(T));
            }
            catch (InvalidCastException)
            {
                returnValue = default(T);
            }
        }

        return returnValue;
    }

也许你应该考虑在此处不捕获 InvalidCastException 异常。如果你能想象默认类型值在程序中有一定用途,那么让调用方法处理异常可能会更好。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接