【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

转载于:https://www.cnblogs.com/samsonhuang/articles/2619831.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值