[C#]集合已修改;可能无法执行枚举操作

摘要

我相信很多人对这个再熟悉不过了。对已经修改的集合进行操作就会出现这个错。

解决办法

比如有下面的一段代码,我们创建一个集合,并向集合中添加10个数,然后,我们循环再将这些数移除了。

        static void Main(string[] args)
        {
            List<int> lst = new List<int>();
            for (int i = 0; i < 10; i++)
            {
                lst.Add(i);
            }
            foreach (var item in lst)
            {
                lst.Remove(item);
            }
            Console.Read();
        }

出现了.....

是不是被泛型集合提供的方法坑了?我记得很久之前我也被坑过。很疑惑吧,其实也很简单,因为你如果移除了一项,集合的元素个数是变化的。这个时候元素会重排,第二个元素的索引由1变为0,后面的依次往前移动。

        static void Main(string[] args)
        {
            List<int> lst = new List<int>();
            for (int i = 0; i < 10; i++)
            {
                lst.Add(i);
            }
            var result = lst;
            Console.WriteLine("lst的count" + lst.Count);
            lst.Remove(0);
            Console.WriteLine("lst的count" + lst.Count);
            for (int i = 0; i < lst.Count; i++)
            {
                Console.WriteLine("索引:{0},值:{1}", i, lst[i]);
            }
            Console.Read();
        }

上面的代码为集合添加10个元素。然后输出当前集合的count,接着将索引为0的元素移除。这个时候集合中应该没有元素0了。然后输出集合的元素个数。输出此时的集合中索引和对应的值。如图所示

可以看到,本来索引为1的1,往前移动了,此时他的索引变为了0.所以在使用foreach移除的时候,集合是变化的,是不允许的。难道就没办法操作了吗?当然有,它不是移除一个集合就少一个吗》

此时,我们可以通过for循环,从集合的队尾移除,这个时候移除队尾的元素,虽然集合的count变了,但他们的索引没有变化。

       static void Main(string[] args)
        {
            List<int> lst = new List<int>();
            for (int i = 0; i < 10; i++)
            {
                lst.Add(i);
            }
            var result = lst;
            Console.WriteLine("lst的count" + lst.Count);
            lst.Remove(0);
            Console.WriteLine("lst的count" + lst.Count);
            for (int i = lst.Count - 1; i >= 0; i--)
            {
                Console.WriteLine("索引:{0},值:{1}", i, lst[i]);
                Console.WriteLine("移除了元素:{0}", lst[i]);
                lst.RemoveAt(i);
            }
            Console.Read();
        }

那么我们只移除满足条件的是否也可以通过for循环呢?当然可以,foreach你不是不让吗?又不是只有你一个可以循环。

        static void Main(string[] args)
        {
            List<int> lst = new List<int>();
            for (int i = 0; i < 10; i++)
            {
                lst.Add(i);
            }
            var result = lst;
            Console.WriteLine("lst的count" + lst.Count);
            lst.Remove(0);
            Console.WriteLine("lst的count" + lst.Count);
            for (int i = 0; i < lst.Count; i++)
            {
                Console.WriteLine("索引:{0},值:{1}", i, lst[i]);
                if (lst[i] % 2 == 0)
                {
                    Console.WriteLine("移除了元素:{0}", lst[i]);
                    lst.RemoveAt(i);
                }

            }
            Console.Read();
        }

总结

前不久刚有人遇到,这里还是记录一下吧。

时间: 2024-10-07 20:17:08

[C#]集合已修改;可能无法执行枚举操作的相关文章

C# 集合已修改;可能无法执行枚举操作

/********************************************************************** * C# 集合已修改;可能无法执行枚举操作 * 说明: * 之前搞Java的时候就很清楚使用多线程操作集合的时候,很容易出现线程 * 安全的问题,还有就是操作线程的时候容易出现集合被修改的问题. * * 2016-12-12 深圳 南山平山村 曾剑锋 ****************************************************

集合已修改;可能无法执行枚举操作。

foreach是取只读的,在取的时候数据不能变(包括修改,删除,添加等).要避免这个问题,就应该使用for循环.        之前没有考虑过对collection类型对象操作时for 和foreach的区别,总感觉foreach更方便一些.今天写了个FOREARCH循环来操作删除某个 collection的元素,出现异常:查询集合已修改:可能无法执行枚举操作查了一下,这个是使用foreach的典型的问题.foreach是取只读的,在取的时候数据不能变(包括修改,删除,添加等).要避免这个问题,

c#“集合已修改;可能无法执行枚举操作”

list中用了remove操作,结果报这个错误. 使用foreach不能执行删除.修改,这是规定.你可以使用for循环遍历修改. 如果你是删除的话,for循环 i 要从大到小,比如: for(int i=50;i>=0;i--){ } 而不是 for(int i=0;i<=50;i++){ } 因为当用foreach遍历Collection时,如果对Collection有Add或者Remove操作或者给item某个属性赋值都会有这个错误. 因为Collection返回的IEnumerator把

{&quot;集合已修改;可能无法执行枚举操作。&quot;}

无论是向集合中添加元素还是从集合中删除元素,都会导致集合内部的变化,特别是集合遍历器的变化.例如 List<int> list = new List<int>{1,2,3,4,5}; foreach(int x in list) { list.Remove(x); //将引发异常:{"集合已修改:可能无法执行枚举操作."} } 使用foreach不能执行删除.修改,这是规定.你可以使用for循环遍历修改. 如果你是删除的话,for循环 i 要从大到小,比如: f

解决点击关闭按钮,应用程序退出时,系统爆出“集合已修改,可能无法执行枚举操作”异常的相关思路

这两天在优化升级公司的一个业务系统时,更改了一下窗体关闭事件中的一句代码,由system.Enviromen.Exit(0)改为了Application.Exit();但是这时候问题就出现了,当点击系统右上角关闭按钮的时候,会爆出“集合已修改,可能无法执行枚举操作”的异常.如下图所示: 这是什么原因造成的呢?问了一下度娘,出现“集合已修改,可能无法执行枚举操作”这种异常大部分都是因为误用foreach语句引起的,foreach是取只读的,在取的时候数据不能变(包括修改,删除,添加等).要避免这个

C#使用List出现“集合已修改;可能无法执行枚举操作”错误的解决办法

原因: 在循环的时候,当集合被删除了一个item后,那么总数 count和索引就会发生改变.所以会报错 解决方法: 不要在List上执行枚举集合的操作(例如foreach)中去执行修改集合的操作.如果需要修改集合,先使用 ToArray() 方法转化成Array,例如 foreach(string s in rs.ToArray()) { if(s.IndexOf(t)<0) { rs.Remove(t); } } 原文地址:http://blog.51cto.com/13567390/2061

多线程下的for循环和foreach循环 System.InvalidOperationException: 集合已修改;可能无法执行枚举

背景:当循环体在循环的时候有需求要修改自己.或者在多线程下,循环静态变量的时候,别人很容易修改了循环体内的数据.但是这就会报错的 准备:for:foeach:多线程. 解决方案:For循环是线程安全的,foreach是线程不安全的.说起开好像很高大上哈.意思是在循环内如,如果调用他们自己的循环体.前者是可以的,但是后者是不行的. 再者如果你循环的是字典.字典是键值对的形式,所以采用线程安全的字典ConcurrentDictionary的字典也可以一定程度的解决问题.但是做好的方案还是添加锁 1,

集合已修改,可能无法执行枚举操作

常规是foreach循环过程中对象发生变化,此处的变化不包括对象内属性的修改,仅限于对象. 案例: List<Person> Persons; foreach(Person p in Persons) { p = new Person(); //错误,对象发生了变化. p = existPerson;  //错误,对象发生了变化. p.Name = "Lanny"; //正确,属性是允许修改的. }

GMAP 集合已修改;可能无法执行枚举操作 错误【正解】(原创)

这个例子引自http://q.cnblogs.com/q/60028/,我做的时候遇到同样的问题,问了没有人回答我,后来我找到了解决办法,在此分享. 先看一下问题: 今天在主界面里写了一个Thread,函数用While(1)循环,循环中先查找数据库中的最新记录,然后把最新记录的坐标值添加到GMap控件中的一个overlay中显示出来,王红说那个有人说把foreach改成for就好了,可是我还是出这个异常,而且位置奇怪,是程序的Program.cs文件中出现的,代码如下: static class