2009-12-06 89 views
2

有没有比以下更好的方法?DataTable to List <T> conversion

特别是,我想用别的东西替换Activator

public static List<T> ToList<T>(DataTable dt) 
     { 
      Type type = typeof(T); 

      List<T> list = new List<T>(); 

      foreach (DataRow dr in dt.Rows) 
      { 
       object[] args = new object[1]; 

       args[0] = dr; 

       list.Add((T)Activator.CreateInstance(type, args)); 
      } 

      return list; 
     } 
+0

对我来说看起来不错...你需要实例化你的T ... – 2009-12-06 00:24:43

回答

6

我想提的第一件事情是,你可能并不需要一个列表。可能性是,IEnumerable就足够了。即使您确实需要列表,将IEnumerable转换为列表也是微不足道的。

考虑到这一点,该代码来完成它一个很好的通用方式:

public static IEnumerable<T> ToEnumerable<T>(DataTable dt, Func<DataRow, T> translator) 
{ 
    foreach(DataRow dr in dt.Rows) 
    { 
     yield return translator(dr); 
    } 
} 

希望你可以看到如何重复使用,这是。你所需要做的就是提供一个知道如何将单个DataRow转换为你的T类型的函数。该功能可能使用Activator,但它不必。它可能只是使用正常的构造函数并设置一些属性。

+1

+1,使用yield你会打电话给你的翻译,就像你需要你的'IEnumerable '项目;如果您使用某种逻辑来中止列表处理,那么您将节省一些处理器周期。 – 2009-12-06 00:30:28

+0

但是,这种方法的问题是,它不向后兼容.net 2.0。 – anonymous 2009-12-06 03:45:30

+1

您可以使用.NET 2.0来完成,您只需使用匿名代理而不是Func 即可执行转换。或者你甚至可以直接在没有委托的情况下编写它,并直接映射到你的结果类类型,只需使用new() – 2009-12-06 04:10:53

2

我真的没有看到任何方式来改善这种代码 - 为什么你要避免Activator?你可以探索

一个办法是创造一些类型的接口是这样的:

interface IFoo 
{ 
    void Initialize(DataRow dr); 
} 

,然后实现对被传递给此方法的任何类型的这个接口。然后,你会限制你的泛型类型参数是这样的:

public static List<T> ToList<T>(DataTable dt) 
    where T : IFoo, new() 

然后改变你的方法是这样实施:

public static List<T> ToList<T>(DataTable dt) 
    where T : IFoo, new() 
{ 
    List<T> list = new List<T>(); 

    foreach (DataRow dr in dt.Rows) 
    { 
     T t = new T(); 
     t.Initialize(dr); 
     list.Add(t); 
    } 
    return list; 
} 
0

我要添加到安德鲁答案的一件事是,如果你走这条路线,你可以(排序)通过用new()约束约束泛型方法来避免Activator类。

public static List<T> ToList<T>(DataTable dt) 
    where T : IFoo, new() 
{ 
    ... 
    foreach (...) { 
     var foo = new T(); 
     foo.Initialize(dataRow); 
     list.Add(foo); 
    } 
    ... 
} 

我说的原因“八九不离十”,是因为C#实际上只是编译到这一点,在编译时的Activator.CreateInstance呼叫反正。但它看起来更干净。

+0

Doh,看起来像Andrew刚刚在他的答案中加上了那样。 – Josh 2009-12-06 00:33:15