【C#】foreach迭代变量只读

c#中使用foreach是非常方便的操作,foreach的执行效率比for高,foreach可以在不用知道长度的情况下进行遍历,但是for一般要知道长度才能遍历,否则要在循环的内部进行控制。 foreach在c#中一般用于操作集合对象。但我在用foreach循环删除元素时遇到了麻烦,比如这样的代码:

foreach (Class.Rectangle rec in rectangles)

{

     if (this.searchedlayer.Equals(rec.Outlayer) && rec.Number == 3)

     {

          this.selectedrectangle = rec;

          this.rectangles.Remove(this.selectedrectangle);

     }

}

这样写的话运行会出错:集合已修改,可能无法执行枚举操作 foreach。

    因为foreach是取只读的,在取的时候数据不能变(包括修改,删除,添加等),当修改了集合的元素时,地址可能发生某种改变,所以不跳出循环继续遍历时,就可能出现引用找不到的情况。所以要把代码改成这样:

foreach (Class.Rectangle rec in rectangles)

{

     if (this.searchedlayer.Equals(rec.Outlayer) && rec.Number == 3)

     {

          this.selectedrectangle = rec;

          break;

     }

}

this.rectangles.Remove(this.selectedrectangle);

如果要循环删除可以增加一个for循环:

for (int i = 0; i < rectangles.Count; i++)

{  

    foreach (Class.Rectangle rec in rectangles)

    {

         if (this.searchedlayer.Equals(rec.Outlayer) && rec.Number == 3)

         {

               this.selectedrectangle = rec;

               break;

         }

    }  

    this.rectangles.Remove(this.selectedrectangle);

}

只读的原因:

namespace System.Collections
{
    // 摘要:
    //     支持对非泛型集合的简单迭代。
    [ComVisible(true)]
    [Guid("496B0ABF-CDEE-11d3-88E8-00902754C43A")]
    public interface IEnumerator
    {
        // 摘要:
        //     获取集合中的当前元素。
        //
        // 返回结果:
        //     集合中的当前元素。
        //
        // 异常:
        //   System.InvalidOperationException:
        //     枚举数定位在该集合的第一个元素之前或最后一个元素之后。
        object Current { get; }
        bool MoveNext();
        void Reset();
    }
}

namespace System.Collections
{
    // 摘要:
    //     公开枚举数,该枚举数支持在非泛型集合上进行简单迭代。
    [ComVisible(true)]
    [Guid("496B0ABE-CDEE-11d3-88E8-00902754C43A")]
    public interface IEnumerable
    {
        // 摘要:
        //     返回一个循环访问集合的枚举数。
        //
        // 返回结果:
        //     可用于循环访问集合的 System.Collections.IEnumerator 对象。
        [DispId(-4)]
        IEnumerator GetEnumerator();
    }
}

每个实现的迭代器,返回类型必须为 IEnumerable、IEnumerator、IEnumerable<T> 或 IEnumerator<T>。foreach中的迭代变量是即为IEnumerable、IEnumerator、IEnumerable<T> 或 IEnumerator<T>类型。从上面的接口可以看出,object Current是只读的,因此,foreach迭代变量只能是只读的。

另:

foreach中的迭代变量本来就是只读,不可修改的。
对值类型中的属性赋值,会改变值类型对象在栈上的内存分步,所以实际上就是对值类型对象本身重新赋值了

 

原文地址:http://blog.sina.com.cn/s/blog_7685afd70100phz7.html

http://blog.csdn.net/smartmz/article/details/7077423

posted @ 2012-08-02 13:50  我思故我在...  阅读(6043)  评论(0编辑  收藏  举报