何时使用每种类型的循环?

时间:2010-12-20 15:01:18

标签: c# loops

我正在学习编程的基础知识(C#),但我认为这个问题本质上是通用的。

哪些简单的实际情况更适合特定类型的循环?

whilefor循环似乎非常相似,并且有几个SO问题解决了两者之间的差异。 foreach怎么样?根据我的基本理解,似乎我应该能够在foreach循环中执行for循环所做的所有操作。

7 个答案:

答案 0 :(得分:9)

哪种方法最适合代码可读性。换句话说,使用最符合情况的那个。

while:当你有一个需要在每个循环开始时检查的条件时。例如while(!file.EndOfFile) { }

for:当你有一个索引或计数器时,你在每个循环上递增。 for (int i = 0; i<array.Length; i++) { }。从本质上讲,你正在循环的东西是一个可索引的集合,数组,列表等。

foreach:循环遍历一组对象或其他Enumerable时。在这种情况下,您可能不知道(或关心)集合的大小,或者集合不是基于索引的(例如,一组对象)。一般来说,当我对某事物的索引或任何其他退出条件不感兴趣时​​,我发现foreach循环是最可读的。

无论如何,这些都是我的一般经验法则。

答案 1 :(得分:5)

<强> 1。 foreach和

foreach循环与IEnumerator一起使用,当for循环与索引一起使用时(在object myObject = myListOfObjects[i]中,i是索引)。

两者之间存在很大差异:

  • 索引可以根据列表中的位置直接访问任何对象。

  • 枚举器只能访问列表的第一个元素,然后移动到下一个元素(如msdn中的上一个链接所述)。它不能直接访问元素,只知道列表中元素的索引。

因此,调查员可能看起来不那么强大,但是:

  • 您并不总是知道组中元素的位置,因为所有组都没有排序/索引。
  • 您并不总是知道列表中的元素数量(想想链接列表)。
  • 即使按顺序排序,列表的索引访问也可以基于枚举器进行内部访问,这意味着每次按位置访问元素时,实际上可能实际列出了列表中的所有元素,直到元素为止。你想要的。
  • 索引并不总是数字。想想Dictionary

实际上foreach循环的强大优势和IEnumerator的基础使用是它适用于任何实现IEnumerable的类型(实现IEnumerable只意味着你提供了一个方法)返回一个枚举器)。列表,数组,字典和所有其他组类型都实现IEnumerable。而且你可以确定他们拥有的枚举器是最好的:你找不到最快的方式来浏览列表。

因此,for循环通常可被视为专门的foreach循环:

public void GoThrough(List<object> myList)
{
    for (int i=0; i<myList.Count; i++)
    {
        MessageBox.Show(myList[i].ToString());
    }
}

完全等同于:

public void GoThrough(List<object> myList)
{
    foreach (object item in myList)
    {
        MessageBox.Show(item.ToString());
    }
}

我说一般因为有一个明显的情况需要for循环:当你需要对象的索引(即列表中的位置)时,由于某种原因(比如显示它)。但是,当您进行良好的.NET编程时,您将最终意识到仅在特定情况下发生,而foreach应该是您对一组元素进行循环的默认候选者。

现在要继续比较foreach循环,它确实只是一个特定的眼睛糖果循环:

public void GoThrough(IEnumerable myEnumerable)
{
    foreach (object obj in myEnumerable)
    {
        MessageBox.Show(obj.ToString());
    }
}

完全等同于:

public void GoThrough(IEnumerable myEnumerable)
{
    IEnumerator myEnumerator = myEnumerable.GetEnumerator();
    while (myEnumerator.MoveNext())
    {
        MessageBox.Show(myEnumerator.Current.ToString());
    }
}

第一次写作虽然简单得多。

<强> 2。 while and do..while

while (condition) {action}循环和do {action} while (condition)循环之间的区别在于第一个循环在应用动作之前测试条件,第二个循环应用动作,然后测试条件。与其他循环相比,do {..} while (..)循环使用得非常少,因为即使最初未满足条件,它也至少运行一次动作(这可能导致麻烦,因为动作通常取决于条件)。

while循环比forforeach循环更通用,它们特别适用于对象列表。 while循环只是有条件继续,可以基于任何东西。例如:

string name = string.empty;
while (name == string.empty)
{
    Console.WriteLine("Enter your name");
    name = Console.ReadLine();
}

要求用户输入他的名字然后按Enter,直到他实际输入了一些内容。正如您所看到的,与列表无关。

第3。结论

当您浏览列表时,除非需要数字索引,否则应使用foreach,在这种情况下,您应使用for。 当它与list没有任何关系时,它只是一个程序结构,你应该使用while(..) {..}

现在结束一些不那么严格的事情:你的第一个目标应该是使你的代码可读/可维护让它快速运行,按顺序优先。任何实现这一点的东西都对你有好处。就个人而言,我认为foreach循环具有潜在的优势,它是最易读的

编辑:还有一种情况,for循环很有用:当您需要建立索引以特殊方式浏览列表或者需要修改列表时在循环。例如,在这种情况下,因为我们要从myList中删除每个null元素:

for (int i=myList.Count-1; i>=0; i--)
{
    if (myList[i] == null) myList.RemoveAt(i);
}

这里需要for循环,因为myList不能在foreach循环中修改,我们需要向后遍历它,因为如果你删除位置i的元素,那么索引&gt; i的所有元素都将更改。

但是自从LINQ以来,这些特殊结构的使用已经减少了。最后一个例子可以在LINQ中编写,例如:

myList.RemoveAll(obj => obj == null);

LINQ是第二步,首先学习循环。

答案 2 :(得分:2)

当您知道有多少次迭代时,将使用for

当您不知道使用while时,如果不知道并且至少需要执行一次代码,请使用do

当您遍历集合并且不需要使用索引时foreach (您也不能在collection[i]上使用的所有内容上使用foreach

答案 3 :(得分:1)

正如其他人所说,'这取决于'。

我发现现在很少使用简单的'for'循环。如果你开始使用Linq,你会发现你根本不需要循环,当你这样做时,就是所谓的'foreach'循环。

最终我同意Colin Mackay - 可读性代码!

答案 4 :(得分:1)

do while循环已被遗忘,我认为:)

取自here

C#while语句执行语句或语句块,直到指定的表达式求值为false。在某些情况下,您可能希望至少执行一次循环,然后检查条件。在这种情况下,您可以使用do..while循环。

do..while和while之间的区别在于do..while在循环的底部而不是顶部计算它的表达式。因此,do块中的语句总是至少执行一次。从以下示例中,您可以了解do..while循环函数。

using System;
using System.Windows.Forms;

namespace WindowsApplication1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            int count = 5;
            do{
                MessageBox.Show(" Loop Executed ");
                count++;
            }while (count <=4);
        }


        private void button2_Click(object sender, EventArgs e)
        {
            int count = 5;
            while (count <=4){
                MessageBox.Show(" Loop Executed ");
                count++;
            }
        }
    }
}

答案 5 :(得分:0)

如果你有一个集合并且你已经开始提前知道,那么你将系统地传递所有值,使用 foreach ,因为通常更容易使用“当前”实例。

如果某些条件可以让您停止迭代,则可以用于用于。它们非常相似,最大的区别在于 控制当前索引或值的更新时间(在for声明中),因为你决定何时何地在阻止更新某些值,然后在while谓词中检查这些值。

答案 6 :(得分:0)

如果您正在编写解析器类,假设一个XMLParser将从给定的源读取XML节点,您可以使用while循环,因为您不知道有多少个标记。 如果变量为真,你也可以在迭代时使用。

如果想要对迭代进行更多控制,可以使用for循环