foreach(BruteforceEntry be in Entries.Values)
{
if (be.AddedTimeRemove <= now)
Entries.Remove(be.IPAddress);
else if (be.Unbantime <= now && be.Unbantime.Day == DateTime.Now.Day)
Entries.Remove(be.IPAddress);
}
抛出异常:
收藏被修改;枚举操作可能无法执行。
由于某种原因,它不再存在。
我知道你不能删除某些东西,而是以这种方式迭代它。我的问题是:我该如何解决?
答案 0 :(得分:37)
您无法修改正在迭代的集合。在这种情况下,一个更好的解决方案是通过迭代字典来创建要删除的条目列表,然后遍历该列表,从字典中删除条目:
List<string> removals = new List<string>();
DateTime now = DateTime.Now;
foreach(BruteforceEntry be in Entries.Values)
{
if (be.AddedTimeRemove <= now ||
(be.Unbantime <= now && be.Unbantime.Day == DateTime.Now.Day))
{
removals.Add(be.IPAddress);
}
}
foreach (string address in removals)
{
Entries.Remove(address);
}
请注意,如果您使用的是.NET 3.5,则可以使用LINQ查询来表达第一部分:
List<string> removals = (from be in Entries.Values
where be.AddedTimeRemove <= now ||
(be.Unbantime <= now &&
be.Unbantime.Day == DateTime.Now.Day)
select be.IPAddress).ToList();
答案 1 :(得分:8)
简单地说:在迭代它时,你无法从集合中删除一个条目。
一种可能的解决方法是创建集合的浅表副本(例如使用ToList
)并迭代它:
foreach(BruteforceEntry be in Entries.Values.ToList())
{
// modify the original collection
}
答案 2 :(得分:2)
您可以将foreach(BruteforceEntry be in Entries.Values)
更改为foreach(BruteforceEntry be in new List<BruteforceEntry>(Entries.Values))
这样你就不会修改你的收藏,而是修改它的副本。
答案 3 :(得分:2)
看起来您的问题是关于为什么异常不被抛出以前的位置。正如其他答案陈述的那样,你通常不能改变你正在迭代的集合,但是你正在遍历Values集合,我认为它是字典中值的副本,而不是引用主字典集合本身。所以它不再有迭代和修改同样的问题。
答案 4 :(得分:1)
使用foreach
进行迭代时,无法修改集合。相反,使用for
循环迭代它。
答案 5 :(得分:1)
这(在我看来)是最简单的方法:
Dictionary<String, String> A = new Dictionary<string, string>(); //Example Dictionary
A.Add("A", "A"); //Example Values
A.Add("B", "B");
A.Add("C", "C");
for (int i = A.Count - 1; i >= 0; i--) //Loop backwards so you can remove elements.
{
KeyValuePair<String, String> KeyValue = A.ElementAt(i); //Get current Element.
if (KeyValue.Value == "B") A.Remove(KeyValue.Key);
}
在你的情况下:
for (int i = Entries.Count - 1; i >= 0; i--)
{
KeyValuePair<String, BruteforceEntry> KeyValue = Entries.ElementAt(i);
if (KeyValue.Value.AddedTimeRemove <= now)
Entries.Remove(KeyValue.Key);
else if (KeyValue.Value.Unbantime <= now && KeyValue.Value.Unbantime.Day == DateTime.Now.Day)
Entries.Remove(KeyValue.Key);
}
答案 6 :(得分:0)
归结你的问题......
foreach(... ... in Entries.Values)
{
Entries.Remove(...);
}
正如其他人所说,你在迭代时修改迭代器。
你可以像@David所说的那样使用for
循环,但要确保从最后开始(反向迭代)。