【问题标题】:DataTable to List<T> conversionDataTable 到 List<T> 的转换
【发布时间】:2009-12-06 00:22:29
【问题描述】:

有没有比以下更好的方法?

特别是,我想用其他东西替换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;
        }

【问题讨论】:

  • 对我来说似乎很好..你需要以某种方式实例化你的 T ......

标签: c# datatable generic-list


【解决方案1】:

我想首先提到的是,您可能不需要列表。奇怪的是,一个 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,使用yield,您将在需要IEnumerable&lt;T&gt; items 时致电您的翻译;如果您使用一些逻辑来中止列表处理,那么您将节省一些处理器周期。
  • 但是这种方法的问题是,它不能向后兼容 .net 2.0。
  • 您可以使用 .NET 2.0,您只需使用匿名委托而不是 Func 来执行转换。或者您甚至可以在没有委托的情况下编写它并直接映射到您的结果类类型,然后使用 new()
【解决方案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;
}

【讨论】:

    【解决方案3】:

    我要添加到 Andrew 的答案中的一件事是,如果你走那条路,你可以(排序)通过使用 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);
        }
        ...
    }
    

    我说“sorta”的原因是因为 C# 实际上只是在编译时将其编译为 Activator.CreateInstance 调用。但是看起来干净多了。

    【讨论】:

    • Doh,看起来安德鲁也刚刚在他的答案中添加了这个。
    猜你喜欢
    • 2011-01-17
    • 1970-01-01
    • 1970-01-01
    • 2013-10-14
    • 2011-09-30
    • 2014-01-17
    • 1970-01-01
    相关资源
    最近更新 更多