我尝试从List<T>
填充.NET 4.5 DataTable,其中T
是一个类型为string
的类。
我有一个函数makeNewDataTable()
,它创建一个DataTable
实例并为其添加一组列;这部分工作正常。
当我手动遍历列表时,正确的行数(包含正确的数据)将添加到DataTable中:
DataTable dataTable = makeNewDataTable();
if (inputList != null)
{
//inputList.Select(item => dataTable.Rows.Add(item.Property, DBNull.Value));
foreach (var item in inputList)
{
dataTable.Rows.Add(item.Property, DBNull.Value);
}
}
但是,如果我尝试将lambda表达式用于同一端:
DataTable dataTable = makeNewDataTable();
if (inputList != null)
{
inputList.Select(item => dataTable.Rows.Add(item.Property, DBNull.Value));
//foreach (var item in inputList)
//{
// dataTable.Rows.Add(item.Property, DBNull.Value);
//}
}
然后在if
语句结束}
后,我看到dataTable.Rows.Count == 0
。
当我使用lambda表达式时,为什么我没有看到行被添加,当手动编码的foreach循环工作正常时?
奖金问题:有没有办法按照lambda表达式的更简洁语法而不是手动编写foreach循环来做我想要的事情?
答案 0 :(得分:0)
Select是一个迭代器。 Lambda定义了在enumaration开始后如何填充IEnumerable。但是在使用foreach对使用ToList()或ToArray()或GetEnumerator()的select枚举或强制枚举的结果之后,它就会启动.MoveNext()...它是延迟执行。
建议不要执行Add in Select等操作。因为它可以在.NET的未来版本中默认并行执行,并且Add可能不是线程安全的
在“oldschool”foreach中没有什么不好的,当你有理由时,你应该使用lambdas:使用表达式树,捕获上下文,在强制传递委托/表达式的场景中快速创建匿名方法。
答案 1 :(得分:0)
我无法回答这个问题,但我可以回答红利问题:为此,你应该使用List.ForEach方法:
inputList.ForEach(item => dataTable.Rows.Add(item.Property, DBNull.Value));
但请注意,它仅适用于List
类型的值,而不是IList
或IEnumerable
,因此您可能需要致电ToList()
。