C# 异常处理:集合已修改;可能无法执行枚举操作
最近在研究c# winform+hpsocket的tcp通讯程序
在代码中,我使用了list集合进行socket在线客户端的信息储存
list大家熟悉吧,熟悉list也自然会使用foreach遍历
这两个配合使用,简直完美
天啦噜,直到今天我才发现了foreach的这样一个严重问题(自己技艺不精)
foreach遍历list时:集合已修改;可能无法执行枚举操作
代码模拟还原List list = new List(); list.Add("阿本"); list.Add("是个"); list.Add("帅哥"); list.Add("吗"); foreach (var item in list) { Console.WriteLine(item); if (item == "吗") { list.Remove(item); } }
报错截图
QQ截图20200830051735.png
通过查阅微软开发文档发现原因:foreach语句是对枚举数的包装,它只允许从集合中read,不允许write。因为执行非read操作会造成list变化,比如索引变化,而foreach是不允许枚举对象变化的。 list.Remove(item); //就是这行代码的错,这锅它必须背。
解决方案
使用foreach命令时会将对象进行枚举,所以可以采用for循环精准定位操作。 List list = new List(); list.Add("阿本"); list.Add("是个"); list.Add("帅哥"); list.Add("吗"); for (int i = 0; i < list.Count; i++) { Console.WriteLine(list[i]); if (list[i] == "吗") { list.RemoveAt(i); } }
就这样轻松的解决这个问题啦。
写到这儿,小编又想到如果是Dictionary集合又该咋办,好的继续堆码。 Dictionary dict = new Dictionary(); dict.Add(1, "阿本"); dict.Add(2, "是个"); dict.Add(3, "帅哥"); dict.Add(4, "吗"); //用数组把Dictionary的key值存起来,然后通过遍历keys数组 int[] keys = dict.Keys.ToArray(); for (int i = 0; i < keys.Length; i++) { Console.WriteLine(dict[keys[i]]); dict.Remove(keys[i]); }
总结
foreach语句是对枚举数的包装,它只允许从集合中read,不允许write。
如果只是遍历读取用foreach简直完美,如果需要遍历的同时修改建议使用for循环遍历