簡體   English   中英

for 和 foreach 和有什么不一樣?

[英]What is the difference between for and foreach?

forforeach循環之間的主要區別是什么?

在哪些場景中我們可以使用for而不是foreach ,反之亦然。

可以用簡單的程序顯示嗎?

兩者在我看來都一樣。 我無法區分它們。

for循環是一個結構,表示“執行此操作n. 次”。

foreach循環是一種結構,表示“對此 IEnumerable 中的每個值/對象執行此操作”

如果要迭代的對象實現了IEnumerable接口,則可以使用foreach 如果只能通過索引訪問對象for則需要使用for

我將嘗試以更一般的方法回答這個問題:

foreach用於以預定義的方式迭代給定集合或列表(任何實現IEnumerable )的每個元素。 您不能影響確切的順序(除了跳過條目或取消整個循環),因為這是由容器決定的。

foreach (String line in document) { // iterate through all elements of "document" as String objects
    Console.Write(line); // print the line
}

for只是另一種編寫循環的方法,該循環在進入循環之前和每次迭代之后都執行了一次代碼。 它通常用於循環代碼指定次數。 與這里的foreach相反,您可以影響當前位置。

for (int i = 0, j = 0; i < 100 && j < 10; ++i) { // set i and j to 0, then loop as long as i is less than 100 or j is less than 10 and increase i after each iteration
    if (i % 8 == 0) { // skip all numbers that can be divided by 8 and count them in j
        ++j
        continue;
    }
    Console.Write(i);
}
Console.Write(j);

如果可能且適用,請始終使用foreach而不是for (假設有一些數組索引)。 根據內部數據組織, foreach可以比使用for和索引(尤其是使用鏈表時)快得多。

每個人都給了你關於 foreach 的正確答案,即它是一種遍歷實現 IEnumerable 的元素的方法。

另一方面, for 比其他答案中顯示的要靈活得多。 事實上,for 用於在指定條件為真時執行語句塊。

來自微軟文檔:

for (initialization; test; increment)
     statement

初始化 必需。 一種表達。 在執行循環之前,此表達式僅執行一次。

測試要求。 布爾表達式。 如果 test 為真,則執行語句。 如果測試為假,則循環終止。

增量 必需。 一種表達。 增量表達式在每次循環結束時執行。

聲明 可選。 如果 test 為真則執行的語句。 可以是復合語句。

這意味着您可以以多種不同的方式使用它。 經典學校的例子是從 1 到 10 的數字之和:

int sum = 0;
for (int i = 0; i <= 10; i++)
    sum = sum + i;

但是你也可以用它來對數組中的數字求和:

int[] anArr = new int[] { 1, 1, 2, 3, 5, 8, 13, 21 };
int sum = 0;
for (int i = 0; i < anArr.Length; i++)
    sum = sum + anArr[i];

(這也可以用 foreach 來完成):

int[] anArr = new int[] { 1, 1, 2, 3, 5, 8, 13, 21 };
int sum = 0;
foreach (int anInt in anArr)
    sum = sum + anInt;

但是你可以用它來求從 1 到 10 的偶數之和:

int sum = 0;
for (int i = 0; i <= 10; i = i + 2)
    sum = sum + i;

你甚至可以發明一些像這樣的瘋狂東西:

int i = 65;
for (string s = string.Empty; s != "ABC"; s = s + Convert.ToChar(i++).ToString()) ;
    Console.WriteLine(s);

for循環:

 1) need to specify the loop bounds( minimum or maximum).

  2) executes a statement or a block of statements repeatedly 
    until a specified expression evaluates to false.

例1:-

int K = 0;

for (int x = 1; x <= 9; x++){
        k = k + x ;
}

foreach 語句:

1)do not need to specify the loop bounds minimum or maximum.

2)repeats a group of embedded statements for 
     a)each element in an array 
  or b) an object collection.       

例2:-

int k = 0;

int[] tempArr = new int[] { 0, 2, 3, 8, 17 };

foreach (int i in tempArr){
    k = k + i ;
}

foreach幾乎相當於:

var enumerator = list.GetEnumerator();
var element;
while(enumerator.MoveNext()){
  element = enumerator.Current;
}

並且為了實現“foreach”兼容模式,這需要提供一個具有方法GetEnumerator()的類,該方法返回具有MoveNext()方法、 Reset()方法和Current屬性的對象。

實際上,您不需要實現 IEnumerable 和 IEnumerator。

一些派生點:

  • foreach不需要知道集合長度,因此允許遍歷“流”或某種“元素生產者”。
  • foreach調用迭代器上的虛擬方法(大部分時間),因此性能不如for

C# 中 For 和 For Each 循環的區別

  1. For 循環執行代碼塊,直到表達式返回 false,而 ForEach 循環通過對象集合中的項目執行代碼塊。

  2. For 循環可以使用對象集合執行,也可以不使用任何對象集合,而 ForEach 循環只能使用對象集合執行。

  3. for 循環是一個普通的循環結構,可用於多種用途,因為 foreach 被設計為僅適用於 Collections 或 IEnumerables 對象。

如果您有數組或其他 IEnumerable 數據集合,則 foreach 很有用。 但 for 可用於訪問可通過其索引訪問的數組元素。

當您預先知道或確定希望循環運行多少次時,for 循環很有用。 例如,如果您需要為一周中的每一天執行一個流程,您就知道需要 7 個循環。

foreach 循環是當您想要對集合或數組的所有部分重復一個過程時,但具體循環運行多少次並不重要。 例如,您正在格式化用戶最喜歡的書籍列表。 每個用戶可能擁有不同數量的書籍,或者沒有,我們並不真正關心它有多少,我們只希望循環對所有書籍進行操作。

這取決於你在做什么,以及你需要什么。

如果您正在遍歷一組項目,並且不關心索引值,那么 foreach 會更方便、更容易編寫且更安全:您不會弄錯項目數。

例如,如果您需要處理集合中的每第二個項目,或者以相反的順序處理它們,那么 for 循環是唯一實用的方法。

最大的區別是 foreach 循環依次處理集合中每個元素的實例,而 for 循環可以處理任何數據,而不僅限於集合元素。 這意味着 for 循環可以修改集合 - 這是非法的並且會在 foreach 循環中導致錯誤

有關更多詳細信息,請參閱 MSDN: foreachfor

for循環重復執行一個語句或一個語句塊,直到指定表達式的計算結果為 false。

需要指定循環邊界(最小或最大)。 下面是一個簡單的 for 循環的代碼示例,它從 0 開始直到 <= 5。

我們詳細看一下foreach 外表看似簡單的循環,其實是一個叫做枚舉器的復雜數據結構:

枚舉數是具有Current屬性、 MoveNext方法和Reset方法的數據結構。 Current屬性保存當前元素的值,每次調用MoveNext 都會使枚舉數前進到序列中的下一項。

枚舉器很棒,因為它們可以處理任何迭代數據結構。 事實上,它們非常強大,以至於所有 LINQ 都建立在枚舉器之上。

但是枚舉器的缺點是它們需要為序列中的每個元素調用CurrentMoveNext 所有這些方法調用加起來,尤其是在關鍵任務代碼中。

相反,for 循環只需為列表中的每個元素調用get_Item 這是一種比 foreach 循環少的方法調用,差異確實顯示出來。

那么什么時候應該使用 foreach 循環,什么時候應該使用 for 循環呢?

您需要執行以下操作:

使用 LINQ 時,請使用 foreach
當您處理非常大的計算值序列時,請使用 foreach
當性能不是問題時,使用 foreach
但是如果你想要最佳性能,請改用 for 循環

我們通過其工作方式了解 c# 中 for 和 foreach 循環之間的主要區別:

for循環:

  1. for 循環的變量總是只有整數。
  2. For 循環重復執行語句或語句塊,直到指定表達式的計算結果為 false。
  3. 在 for 循環中我們必須指定循環的邊界(最大值或最小值)。-------->我們可以說這是 for 循環的限制。

foreach循環:

  1. 在 foreach 循環的情況下,循環的變量與數組下的值的類型相同。

  2. Foreach 語句為數組或對象集合中的每個元素重復一組嵌入語句。

  3. 在 foreach 循環中,您不需要指定循環邊界最小值或最大值。---> 在這里我們可以說這是 for each 循環的優點。

許多答案已經存在,我只需要確定一個不存在的差異。

for 循環是故障安全的,而 foreach 循環是快速失敗的。

如果迭代和修改同時在對象中完成,快速失敗迭代將拋出ConcurrentModificationException

但是,即使迭代進入無限循環,故障安全迭代也可以確保操作不會失敗。

public class ConcurrentModification {
    public static void main(String[] args) {
        List<String> str = new ArrayList<>();

        for(int i=0; i<1000; i++){
            str.add(String.valueOf(i));
        }

        /**
         * this for loop is fail-safe. It goes into infinite loop but does not fail. 
         */
        for(int i=0; i<str.size(); i++){
            System.out.println(str.get(i));
            str.add(i+ "  " + "10");
        }

        /**
         * throws ConcurrentModificationexception 
        for(String st: str){
            System.out.println(st);
            str.add("10");
        }
        */

        /* throws ConcurrentModificationException 
         Iterator<String> itr = str.iterator();
        while(itr.hasNext()) {
            System.out.println(itr.next());
            str.add("10");
        }*/
    }
} 

希望這有助於從不同角度理解 for 和 foreach 循環之間的區別。

如果有人感興趣,我找到了一個很好的博客來了解故障安全和快速故障之間的區別:

for 和 foreach 之間的簡單區別

  for loop is working with values.it must have condition then increment and intialization also.you have to knowledge about 'how many times loop repeated'.

 foreach is working with objects and enumaretors. no need to knowledge how many times loop repeated.

您可以將 foreach 用於簡單的數組,例如

int[] test = { 0, 1, 2, 3, ...};

當你有一個二維數組時,你可以使用 for

int[][] test = {{1,2,3,4},
                {5,2,6,5,8}};

foreach語法既快速又簡單。 for語法稍微復雜一些,但也更靈活。

foreach在迭代集合中的所有項目時很有用。 for在迭代整體或項目子集時很有用。

提供每個集合項的foreach迭代變量是只讀的,因此我們無法在迭代時修改這些項。 使用for語法,我們可以根據需要修改項目。

底線 - 使用foreach快速迭代集合中的所有項目。 用於迭代集合中項目的子集或在迭代時修改項目。

就性能而言,我更喜歡 FOR 循環。 當您使用更多項目時,FOREACH 會有點慢。

如果您對實例執行更多業務邏輯,則 FOREACH 執行得更快。

演示:我創建了一個包含 10000000 個實例的列表,並使用 FOR 和 FOREACH 進行循環。

循環所需的時間:

  • FOREACH -> 53.852 毫秒
  • FOR -> 28.9232ms

下面是示例代碼。

class Program
{

    static void Main(string[] args)
    {
        List<TestClass> lst = new List<TestClass>();
        for (int i = 1; i <= 10000000; i++)
        {
            TestClass obj = new TestClass() {
                ID = i,
                Name = "Name" + i.ToString()
            };
            lst.Add(obj);
        }

        DateTime start = DateTime.Now;
        foreach (var obj in lst)
        {
            //obj.ID = obj.ID + 1;
            //obj.Name = obj.Name + "1";
        }
        DateTime end = DateTime.Now;
        var first = end.Subtract(start).TotalMilliseconds;

        start = DateTime.Now;
        for (int j = 0; j<lst.Count;j++)
        {
            //lst[j].ID = lst[j].ID + 1;
            //lst[j].Name = lst[j].Name + "1";
        }
        end = DateTime.Now;
        var second = end.Subtract(start).TotalMilliseconds;
    }
}

public class TestClass
{
    public long ID { get; set; }
    public string Name { get; set; }
}

如果我取消注釋循環內的代碼:然后,循環所需的時間:

  • FOREACH -> 2564.1405ms
  • FOR -> 2753.0017ms

結論
如果你用實例做更多的業務邏輯,那么推薦使用 FOREACH。 如果您沒有對實例進行太多邏輯處理,則建議使用 FOR。

foreach 語句為實現 System.Collections.IEnumerable 或 System.Collections.Generic.IEnumerable 接口的數組或對象集合中的每個元素重復一組嵌入語句。 foreach 語句用於遍歷集合以獲取您想要的信息,但不能用於從源集合中添加或刪除項目以避免不可預測的副作用。 如果您需要從源集合中添加或刪除項目,請使用 for 循環。

foreach相關的一件重要事情是,foreach 迭代變量不能在循環體中更新(或分配新值)。

例如 :

List<string> myStrlist = new List<string>() { "Sachin", "Ganguly", "Dravid" };
              foreach(string item in myStrlist)

              {

                  item += " cricket"; // ***Not Possible*** 

              }

暫無
暫無

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

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