【发布时间】:2010-10-11 13:08:09
【问题描述】:
我发现(以一种艰难的方式)正在枚举的集合不能在“Foreach”语句中修改
“集合已修改;枚举操作可能无法执行。”
现在,我想出的解决方案是创建一个大小相同的虚拟集合,其中包含一个字典键并对其进行枚举以修改相关集合。
private void InvalidateAuthenticatedNodes()
{
var dummy = new Dictionary<int, bool>(_AuthenticatedNodes.Count);
foreach (var nodeId in _AuthenticatedNodes.Keys)
dummy[nodeId] = false;
foreach (var nodeId in dummy.Keys)
_AuthenticatedNodes[nodeId] = false;
ClearAuthenticatedDateTime();
}
以上代码运行良好;我正在重构上面的代码以使用 Func 委托返回键的副本,如下所示
private void InvalidateAuthenticatedNodes()
{
var getNodeIds =
new Func<Dictionary<int, bool>, IEnumerable<int>>(
nodes => nodes.Select(node => node.Key));
foreach (var nodeId in getNodeIds(_AuthenticatedNodes))
{
_AuthenticatedNodes[nodeId] = false;
}
ClearAuthenticatedDateTime();
}
与我的预期不同,getNodeIds 不会返回副本。 有没有办法退回副本?
*EDIT:JaredPar's answer之前的临时结果
与 JaredPar 的回答类似,但他的回答更简洁,我同意了他的回答。 但这是我想出的类似结果。
private void InvalidateAuthenticatedNodes()
{
var getNodeIds =
new Func<Dictionary<int, bool>, IEnumerable<int>>(nodes =>
nodes.Select(node => node.Key));
foreach (var nodeId in getNodeIds(_AuthenticatedNodes).ToList())
{
_AuthenticatedNodes[nodeId] = false;
}
ClearAuthenticatedDateTime();
}
*EDIT:最终结果(优化)
_AuthenticatedNodes.Keys.ToList().ForEach(
nodeId => _AuthenticatedNodes[nodeId] = false);
【问题讨论】:
-
由于您并没有真正使用列表(例如,不添加或删除条目),请使用 ToArray() 代替。无论如何,ToList() 大致转换为 ToArray(),但要贵得多。
-
感谢您的意见,chuckj。我认为在重构时我需要在某个地方停下来。但是当我遇到类似情况时,我会听取您的建议。
标签: c# linq delegates .net-3.5 c#-3.0