簡體   English   中英

為什么foreach循環在C#中只讀

[英]Why is foreach loop Read-Only in C#

為什么foreach循環只讀? 我的意思是你可以獲取數據,但不能增加++或減少 - 。 它背后的任何原因? 是的我是初學者:)

〔實施例:

int[] myArray={1,2,3};
foreach (int num in myArray)
{
  num+=1;
}

這是因為foreach意味着迭代一個容器,確保每個項目只訪問一次,而不更改容器,以避免令人討厭的副作用。

請參閱: MSDN中的foreach

如果你的意思是為什么像整數這樣的元素的更改不會影響整數的容器,那么這是因為在這種情況下迭代的變量將是一個值類型並被復制,例如:

// Warning: Does not compile
foreach (int i in ints)
{
  ++i; // Would not change the int in ints
}

即使迭代變量是一個引用類型,其操作返回一個新對象,你也不會改變原始集合,你只需要在大多數時間重新分配給這個變量:

// Warning: Does not compile
foreach (MyClass ob in objs)
{
  ob=ob+ob; // Reassigning to local ob, not changing the one from the original 
            // collection of objs
}

以下示例可能通過調用mutating方法實際修改原始集合中的對象:

// Warning: Does not compile
foreach (MyClass ob in objs)
{
  ob.ChangeMe(); // This could modify the object in the original collection
}

為了避免在值與引用類型和上述場景(以及與優化相關的一些原因)方面的混淆,MS選擇只readonly迭代變量。

因為當前元素是按值返回的(即復制)。 修改副本是沒用的。 如果它是引用類型,則可以修改該對象的內容,但不能替換引用。

也許您應該閱讀IEnumerable<T>IEnumerator<T>的文檔。 這應該讓它更清晰。 最重要的一點是IEnumerable<T>具有類型為T的屬性Current 而這個屬性只有一個吸氣劑,但沒有二傳手。

但如果它有一個二傳手會怎么樣?

  • 它適用於數組和列表
  • 它不適用於復雜的容器,如哈希表,有序列表,因為更改會導致容器中的更大更改(例如重新排序),從而使迭代器無效。 (如果迭代器被修改以避免迭代器中的狀態不一致,則大多數集合都會使迭代器失效。)
  • 在LINQ中它完全沒有任何意義。 例如,使用select(x=>f(x)) ,值是函數的結果,並且沒有關聯的永久存儲。
  • 使用yield return語法編寫的迭代器也沒有意義

foreach旨在僅訪問集合中的每個項目一次,並且不使用顯式的“循環索引”; 如果你想要更多地控制循環並有一個循環索引,請使用for

編輯:您可以更改在foreach循環內迭代的集合中的項目。 例如:

foreach(Chair ch in mychairs)
{
    ch.PaintColour = Colour.Green; //this alters the chair object *in* the collection.
}

但是,您無法在集合中添加或刪除項目。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM