1. 程式人生 > >集合已修改;可能無法執行枚舉操作

集合已修改;可能無法執行枚舉操作

bsp fine 輸出 bar 枚舉操作 field 執行 ima brush

我相信很多人對這個再熟悉不過了。對已經修改的集合進行操作就會出現這個錯。

解決辦法

比如有下面的一段代碼,我們創建一個集合,並向集合中添加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();
        }
技術分享圖片

技術分享圖片

List<IDefineField> sortedFields = new List<IDefineField>(fields.Count);
List<IDefineField> sortedFieldsCopy = new List<IDefineField>();
foreach (var item in sortedFields)
{
if (item != null)
{
sortedFieldsCopy.Add(item);
}
}

 移除為空元素 

集合已修改;可能無法執行枚舉操作