我有一个奇怪的错误,我不明白,并改变LINQ的IEnumerable列表中途修复它,我不明白为什么
不是真正的代码,但非常相似 以下代码不起作用:
// an IEnumerable of some object (Clasess) internally an array
var ansestors = GetAnsestors();
var current = GetCurrentServerNode();
var result = from serverNode in ansestors
select new PolicyResult
{
//Some irrelevant stuff
OnNotAvailableNode = NodeProcessingActionEnum.ContinueExecution,
};
var thisNode = new PolicyResult
{
//Some irrelevant stuff
OnNotAvailableNode = NodeProcessingActionEnum.ThrowException,
};
result = result.Reverse();
result = result.Concat(new List<PolicyResult> { thisNode });
result.First().OnNotAvailableNode = NodeProcessingActionEnum.ThrowException;
// When looking in the debugger, and in logs, the first element of the
// result sequence has OnNotAvailableNode set to ContinueExecution
// Which doesnt make any sense...
但是当我将结尾更改为以下内容时,它会起作用:
result = result.Reverse();
result = result.Concat(new List<PolicyResult> { thisNode });
var policyResults = result.ToList();
var firstPolicyResult = policyResults.First();
firstPolicyResult.OnNotAvailableNode = NodeProcessingActionEnum.ThrowException;
return policyResults;
这里的所有类型都是类(引用类型),但NodeProcessingActionEnum是一个枚举。
这是一个错误吗?
我错过了一些关于LINQ的重要内容?
帮助?
答案 0 :(得分:5)
result.First()
执行(延迟/延迟)查询。
该行将设置值OK,但是当您稍后使用result
时,将再次执行 查询。
稍后您正在查看新获取的副本。事实上它是不同的让我假设GetAnsestors()
也被懒惰地评估并且不在内存中List<>
这意味着ToList()
值得进行优化以及修复。请注意,在ToList之后,您还可以使用
var firstPolicyResult = policyResults[0];
答案 1 :(得分:0)
问题是在IEnumerable上运行其实我已经改变了主意 - 这可能不是它。不过,这个解决方案可能值得一试。First
会将其从枚举器中删除,因此您必须检查下一个元素。
您可以使用能够为您进行更改的内容包装IEnumerable,例如使用the Select
override which accepts an index too:
var modifiedResults = results.Select((r, index) => {
if (index == 0) {
// This is the first element
r.OnNotAvailableNode = NodeProcessingActionEnum.ThrowException;
}
return r;
});
(未经测试)应该做到这一点。