2010-10-23 91 views
13

爲什麼foreach循環只讀?我的意思是你可以獲取數據,但不能增加++或減少 - 。背後有什麼理由? 是的,我是一個初學者:)爲什麼foreach循環只讀在C#

〔實施例:

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

你是什麼意思while循環被只讀的意思嗎? while循環是一個構造;它既不是隻讀也不是讀寫。你可以發佈一些代碼和/或澄清你的問題嗎?謝謝。 – CesarGon 2010-10-23 15:46:24

+1

我想他是在討論迭代變量,如在foreach中(項目theItem inItemList)...該項目不能分配給。 – 2010-10-23 15:47:59

+0

他現在澄清了這個問題:他在談論foreach而不是while。 – CesarGon 2010-10-23 15:48:46

回答

9

這是因爲的foreach是爲了遍歷一個容器,確保每一個項目被訪問只有一次,在不改變容器,避免討厭的副作用。

參見:foreach in MSDN

如果你的意思是,爲什麼會改變一個元素像一個整數不會影響整體的容器,以及這是因爲迭代在這種情況下,變量將是值類型和複製,例如:

// 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 
} 

下面的例子有實際上通過調用突變方法修改原始集合中的對象的電勢:

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

爲了避免關於值Vs引用類型的混亂和上面提到的場景(以及與優化有關的一些原因),MS選擇使得迭代readonly的變量。

1

foreach被設計爲訪問集合中的每個項目一次,而不使用明確的「循環索引」;如果您想要更多地控制循環並獲得循環索引,請使用for

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

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

但是,您不能將項目添加到集合或從集合中刪除項目。

+0

實際上,您無法修改迭代變量引用的對象的字段/屬性。 – 2010-10-23 16:09:10

+0

@Michael:我發佈的代碼適合我。我正在使用.NET 3.5和Visual Studio 2008. – CesarGon 2010-10-23 16:23:03

7

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

也許您應該閱讀文檔IEnumerable<T>IEnumerator<T>。這應該更清楚。最重要的是IEnumerable<T>有一個Current類型T。而這個屬性只有一個getter,但沒有setter。

但是如果它有一個setter,會發生什麼?

  • 它將與陣列很好地工作和列表
  • 它不會與像散列表複雜容器很好地工作,有序列表由於變化引起的容器較大變化(例如重排序),因此,無效信號迭代器。 (如果迭代器被修改以避免迭代器中的狀態不一致,大多數集合將使迭代器無效。)
  • 在LINQ中它根本沒有任何意義。例如對於select(x=>f(x)),這些值是函數的結果並且沒有關聯的永久存儲。
  • 迭代器寫入與yield return語法它沒有意義或者
+0

「修改副本是沒用的。」如果我想要做一些工作,比如列表中所有數字的平方和?它可以通過只讀限制來完成,但修改副本通常很有用。 – raylu 2014-11-26 08:51:20