有没有比以下更好的方法?
特别是,我想用其他东西替换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 :(得分: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 :(得分: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;
}
答案 2 :(得分:0)
我要添加到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调用。但它看起来更清洁。