【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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM