最近在研究c# winform+hpsocket的tcp通讯程序

在代码中,我使用了list集合进行socket在线客户端的信息储存
list大家熟悉吧,熟悉list也自然会使用foreach遍历
这两个配合使用,简直完美

天啦噜,直到今天我才发现了foreach的这样一个严重问题(自己技艺不精)

foreach遍历list时:集合已修改;可能无法执行枚举操作

代码模拟还原

List<string> list = new List<string>();
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<string> list = new List<string>();
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<key,value>集合又该咋办,好的继续堆码。

Dictionary<int, string> dict = new Dictionary<int, string>();
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循环遍历

Last modification:August 30th, 2020 at 06:05 am
如果觉得我的文章对你有用,请随意赞赏