Hashtable htt = new Hashtable();
            for (int i = 0; i < 100; i++)
            {
                htt.Add(i, i);
            }
            MessageBox.Show(htt.Count.ToString());                foreach (DictionaryEntry de in htt)
                {
                    if ((int)de.Key % 2 == 0)
                    {
                        htt.Remove(de.Key);
                    }
                }
            MessageBox.Show(htt.Count.ToString());提示错误:集合已经修改,枚举操作可能不会执行.
请大家帮我分析一下,谢谢了!

解决方案 »

  1.   

    使用foreach虽然使用起来比for方便, 不用考虑索引出边界等问题, 但也有缺陷, 如你的例子中的错误, 不
    能够在循环体内部添加和删除遍历的集合体, 只能够修改.把下面的foreach改为for循环就可以了, 但根据你的思路, 每 htt.Remove(de.Key); 操作后要进行 i--操作, 如下:
     for   (int   i   =   0;   i   <   htt.Count;   i++)  
     { 
          if   ((int)htt[i].Key   %   2   ==   0) 
          { 
                   htt.Remove(de.Key); 
                   i--;
          } 
      

  2.   

    不好意思,根本没有htt[i].Key       这种写法的!
      

  3.   

    for (int i= htt.count-1;i>=0;i--) 
                                    { 
                                            htt.Remove(...);
                                    } 
      

  4.   

    楼上几的几种都可以用 我给你换种写法~ 也是用foreach 我个人不喜欢用for    Hashtable temp=new Hashtable(htt);
        foreach   (DictionaryEntry   de   in   temp) 
              { 
                  if   ((int)de.Key   %   2   ==   0) 
                  { 
                       htt.Remove(de.Key); 
                  } 
              }
      

  5.   

    不好意思,上面的语法不对~    Hashtable temp=new Hashtable();
        temp=htt;
        foreach   (DictionaryEntry   de   in   temp) 
              { 
                  if   ((int)de.Key   %   2   ==   0) 
                  { 
                       htt.Remove(de.Key); 
                  } 
              }
      

  6.   

    foreach使用IEnumerable接口提供的迭代器遍历集合。所以为了保证迭代器正常工作,不允许修改原始集合。而且我深入研究过哈希表的源码,其实哈希表在内部数组定位的时候,采用桶式算法,key先取低31位,值然后再与内部数组容量(100%是素数)取余,余数就是在内部数组定位的位置,但这样会产生冲突,例如内部数组容量是11,key 值为 0 的会存入位置0,key 值为11 的也会存入位置 0,为了解决这种冲突,后来的冲突元素就要移位寻找空位,具体算法可以看我的源码http://download.csdn.net/source/305015当然,我说了那么多,无非就是想说remove是效率很低的方法,因为remove中间一个元素,其后加入的所有元素都要重新计算自己的位置,计算量相当大。例如上例,把key为0的remove了,key为11的就要重新计算自己的位置,删除自己再重新加入。否则程序查找key为11的元素就会找不到该元素。所以你不如另外建立一个哈希表,在foreach里找到合适的元素就加入新表,不需要的就抛弃,不用管它,这样效率最高,也能解决foreach遍历的问题
      

  7.   

    using System;
    using System.Collections;namespace HashtableTest
    {
        class Program
        {
            static void Main(string[] args)
            {
                // 哈希表默认容量是 7,内部数组初始大小为 11
                // 每次扩容性能损失相当大,所以最好直接给定 capacity 值
                Hashtable htt = new Hashtable(100);            for (int i = 0; i < 100; i++)
                    htt.Add(i, i);
                Console.WriteLine(htt.Count);            // 使用一个副本,退出 foreach 就回收了,不会造成大的性能影响
                foreach (int key in ((Hashtable)htt.Clone()).Keys)
                    if (key % 2 == 0)
                        htt.Remove(key);
                Console.WriteLine(htt.Count);
            }
        }
    }