![](/img/trans.png)
[英]Why there is no SelectToArray method in System.Linq.Enumerable
[英]Updating a System.Linq.Enumerable after the query
我有一个查询,我从csv文件中加载数据
var transactions = from line in System.IO.File.ReadAllLines(path).Skip(1)
let columns = line.Split(',')
select new Transaction
{
AccountNo = long.Parse(columns[0]),
Date = DateTime.Parse(columns[1], new CultureInfo("en-AU")),
DebitAmount = columns[3].Length > 0? decimal.Parse(columns[3]): 0.00m,
CreditAmount = columns[4].Length > 0 ? decimal.Parse(columns[4]) : 0.00m,
Categories = columns[5],
Serial = columns[6]
};
现在,当我遍历此枚举时,我希望能够设置事务对象的其他字段。
使用列表,我可以使用for循环遍历每个列表并根据需要进行任何更改,但是如何使用System.Linq.Enumerable做到这一点呢?
您可以使用以下命令将其转换为List<Transaction>
:
var transactions = (from line in System.IO.File.ReadAllLines(path).Skip(1)
let columns = line.Split(',')
select new Transaction
{
AccountNo = long.Parse(columns[0]),
Date = DateTime.Parse(columns[1], new CultureInfo("en-AU")),
DebitAmount = columns[3].Length > 0? decimal.Parse(columns[3]): 0.00m,
CreditAmount = columns[4].Length > 0 ? decimal.Parse(columns[4]) : 0.00m,
Categories = columns[5],
Serial = columns[6]
}).ToList();
如果您不实现查询,则将在迭代结果时创建Transaction
新实例。 该ToList()
将迭代查询和结果物化到一个列表。 因此,您可以更改结果。
在此处查找更多信息: 如何:将查询结果存储在内存中 http://msdn.microsoft.com/zh-cn/library/bb513810.aspx
为此,您必须首先将查询“物化”到内存中的集合,例如数组:
transactions = transactions.ToArray();
foreach (var transaction in transactions)
{
// Fill other members here
}
因为如果不这样做,您的更改将丢失,仅因为迭代查询将始终创建新的Transaction
对象。
另一个选择是编写一个执行此操作的“转换”方法:
public Transaction FillOtherProperties(Transaction transaction)
{
// Fill other members here
return transaction;
}
您可以按以下方式使用它:
transactions.Select(FillOtherProperties);
当您需要迭代器是惰性的(例如,集合太大而无法容纳在内存中)时,这很有用。
缺点是您正在对现有对象进行变异,这可以看作是一种副作用,这可能会引起其他开发人员的困惑。 通常,您希望查询无副作用。
var transactions =
System.IO.File.ReadAllLines("").Skip(1).Select(line => new { line, columns = line.Split(',') }).Select(
strings => new Transaction
{
AccountNo = long.Parse(strings.columns[0]),
Date = DateTime.Parse(strings.columns[1], new CultureInfo("en-AU")),
DebitAmount = strings.columns[3].Length > 0 ? decimal.Parse(strings.columns[3]) : 0.00m,
CreditAmount = strings.columns[4].Length > 0 ? decimal.Parse(strings.columns[4]) : 0.00m,
Categories = strings.columns[5],
Serial = strings.columns[6]
}).ToList();
IEnumerable<Transaction> newTransactions = transactions.Select(tr => new Transaction(){/*assign new values*/});
无需创建新对象
transactions.ForEach(transaction => { transaction.AccountNo = 12; /*other manipulation*/});
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.