以下代码可以通过LINQ或lambda来改进:
foreach (var item in listItem)
{
var dataRow = dataTable.NewRow();
foreach (var col in dataTableColumnNames)
{
var p = listType.GetProperty(col);
if (p != null)
{
dataRow[col] = p.GetValue(item, null);
}
}
dataTable.Rows.Add(dataRow);
}
虽然在程序中没有任何问题,但我想要感受一下LINQ / lambda。
答案 0 :(得分:4)
由于你的代码片段在其循环中调用语句(在内部循环中进行赋值并在外部调用Rows.Add()),因此使用LINQ不是一个非常好的方案。
如果您仍然希望以更“实用”的方式编写它,那么您可能做的最好的方法是使用ForEach()扩展方法而不是循环,但代码仍然会完全相同并且会实际上并没有真正使用LINQ。
在这里尝试使用LINQ非常困难,你最终会得到类似的东西:
listItem
.Select(item =>
{
var dataRow = dataTable.NewRow();
dataTableColumnNames
.Select(col => listType.GetProperty(col))
.Where(p => p != null)
.ForEach(p => dataRow[p.Name] = p.GetValue(item, null));
return row;
})
.ForEach(row => dataTable.Rows.Add(row));
我在这里使用属性的p.Name
代替col
来使这更简单,但一般功能应该是相同的。正如其他答案所述,这也不会提高可读性。
请注意,普通的LINQ中不包含ForEach()扩展方法,如果您还没有,则必须自己编写。
答案 1 :(得分:1)
我认为您还应该考虑可读性,特别是如果您的代码将来可能会发生变化。使用lamba表达式,你的代码不会有太大的改进,并且更难理解。
答案 2 :(得分:1)
正如你写的那样,没有。使用正确的方法,你可以在这里使用一些 LINQ,你只需要编写代码以方便其使用。这里,LINQ可用于收集要添加到表中的数据。然后使用循环将它们全部添加。
// let's create the table and its columns
var dataTable = new DataTable("My Table");
dataTable.Columns
.AddRange(new[] { "Name", "Address" }
.Select(n => new DataColumn(n))
.ToArray());
// the items to be added
var items = new[]
{
new { Name = "Bob", Address = "Foo Street" },
new { Name = "Joe", Address = "Bar Road" },
new { Name = "Jon", Address = "Baz Avenue" },
};
var itemType = items.GetType().GetElementType();
var rowDatas =
items.Select(item =>
from col in dataTable.Columns.Cast<DataColumn>()
let prop = itemType.GetProperty(col.ColumnName)
select new
{
col.ColumnName,
Value = prop != null
? prop.GetValue(item, null)
: null,
});
foreach (var rowData in rowDatas)
{
var row = dataTable.NewRow();
foreach (var cell in rowData)
row[cell.ColumnName] = cell.Value;
}
但是,您可以滥用它并利用在表的行集合上使用Add()
方法向数据表添加行的副作用。你通常不应该这样做,但它确实使事情变得更紧凑。
var itemType = items.GetType().GetElementType();
items.Select(item =>
dataTable.Rows.Add( // create and add a new row with the following values
dataTable.Columns
.Cast<DataColumn>()
.Select(col => itemType.GetProperty(col.ColumnName))
.Select(prop => prop != null ? prop.GetValue(item, null) : null)
.ToArray()
)
).ToList(); // "execute" this thing
答案 3 :(得分:0)
我会在进入循环之前得到属性信息。我假设listItem
的类型为List<T>
。
var properties = dataTableColumnNames
.Select(listItemType.GetProperty)
.OfType<PropertyInfo>() // drop null values
.ToList();
listItems.ForEach(item => {
var dataRow = dataTable.NewRow();
properties.ForEach(property =>
dataRow[property.Name] = property.GetValue(item, null));
dataTable.Rows.Add(dataRow);
});