【问题标题】:How do foreach loops work in C#? [closed]foreach 循环如何在 C# 中工作? [关闭]
【发布时间】:2008-12-29 22:52:46
【问题描述】:

哪些类型的类可以使用foreach 循环?

【问题讨论】:

  • 您可能需要选择一个不同的可接受答案,因为您选择的答案并不能真正代表正确答案。

标签: c# foreach


【解决方案1】:

实际上,严格来说,你需要使用foreach 是一个公共的GetEnumerator() 方法,它返回带有bool MoveNext() 方法和? Current {get;} 属性的东西。然而,最常见的含义是“实现IEnumerable/IEnumerable<T>,返回IEnumerator/IEnumerator<T>

暗示,这包括实现ICollection/ICollection<T>的任何东西,例如Collection<T>List<T>、数组(T[])等。所以任何标准的“数据收集”通常都会支持foreach

对于第一点的证明,以下工作正常:

using System;
class Foo {
    public int Current { get; private set; }
    private int step;
    public bool MoveNext() {
        if (step >= 5) return false;
        Current = step++;
        return true;
    }
}
class Bar {
    public Foo GetEnumerator() { return new Foo(); }
}
static class Program {
    static void Main() {
        Bar bar = new Bar();
        foreach (int item in bar) {
            Console.WriteLine(item);
        }
    }
}

它是如何工作的?

foreach(int i in obj) {...} 这样的foreach 循环有点等同于:

var tmp = obj.GetEnumerator();
int i; // up to C# 4.0
while(tmp.MoveNext()) {
    int i; // C# 5.0
    i = tmp.Current;
    {...} // your code
}

但是,有一些变化。例如,如果枚举器(tmp)支持IDisposable,则也使用它(类似于using)。

注意声明“int iinside (C# 5.0) 与 outside (up C# 4.0) 位置的区别 ) 循环。如果您在代码块内的匿名方法/lambda 中使用i,这一点很重要。但那是另一回事了;-p

【讨论】:

  • +1 表示深入。对于可能是“初学者”的问题,我通常不会那么深入,因为这对新程序员来说似乎是压倒性的。
  • 没错,Gortok - 所以我跟进了有关列表/数组/等的内容。
  • 最好提到对循环变量的隐式运行时强制转换 - 可能会产生类型不兼容异常。
  • 不要忘记:当使用带有 foreach 的数组时,编译器会创建一个简单的 for-loop(使用 IL 时可以看到)。
  • @Marc Gravell:好的,酷!我编辑了帖子以使其更清楚 - 至少对我而言。毕竟布局不仅在 C# 5.0 中很重要,而且总是很重要,只是它发生了变化。希望你不要介意。
【解决方案2】:

来自MSDN

foreach 语句重复了一组 每个嵌入式语句 数组或对象中的元素 收藏foreach 声明是 用于遍历集合 获得所需的信息,但是 不应该用来改变 要避免的集合内容 不可预知的副作用。 (强调我的)

所以,如果你有一个数组,你可以使用 foreach 语句来遍历数组,像这样:

 int[] fibarray = new int[] { 0, 1, 2, 3, 5, 8, 13 };
    foreach (int i in fibarray)
    {
        System.Console.WriteLine(i);
    }

您也可以使用它来遍历 List<T> 集合,如下所示:

List<string> list = new List<string>();

foreach (string item in list)
{
    Console.WriteLine(item);
}

【讨论】:

  • 奇怪的是,根据 MSDN (msdn.microsoft.com/en-us/library/9yb8xew9(VS.80).aspx),对象类型不需要实现 IEnumerable。任何以正确方式定义 GetEnumerator、MoveNext、Reset 和 Current 的类型都可以使用。很奇怪吧?
  • 整洁。我不知道。 :-)
【解决方案3】:

根据博文Duck Notation,使用了duck typing。

【讨论】:

    【解决方案4】:

    这是文档:Main articleWith ArraysWith Collection Objects

    请务必注意“集合元素的类型必须可转换为标识符类型”。这有时无法在编译时检查,如果实例类型不可分配给引用类型,则可能会生成运行时异常。

    如果水果篮里有一个非苹果,例如橙子,这将产生一个运行时异常。

    List<Fruit> fruitBasket = new List<Fruit>() { new Apple(), new Orange() };
    foreach(Apple a in fruitBasket)
    

    这会使用Enumerable.OfType 安全地将列表过滤到仅苹果

    foreach(Apple a in fruitBasket.OfType<Apple>() )
    

    【讨论】:

      【解决方案5】:
      IList<ListItem> illi = new List<ListItem>();
      ListItem li = null;
      
      foreach (HroCategory value in listddlsubcategory)
      {
          listddlsubcategoryext = server.getObjectListByColumn(typeof(HroCategory), "Parentid", value.Id);
          li = new ListItem();
          li.Text = value.Description;
          li.Value = value.Id.ToString();
          illi.Add(li);
          IList<ListItem> newilli = new List<ListItem>();
          newilli = SubCatagoryFunction(listddlsubcategoryext, "-->");
          foreach (ListItem c in newilli)
          {
              illi.Add(c);
          }
      }
      

      【讨论】:

        【解决方案6】:

        也可以在MSDN 上找到有关此主题的有用信息。从那篇文章中汲取精华:

        foreach 关键字枚举一个集合,对集合中的每个元素执行一次嵌入语句:

        foreach (var item in collection)
        {
            Console.WriteLine(item.ToString());
        }
        

        编译器将上面示例中显示的 foreach 循环转换为类似于此构造的内容:

        IEnumerator<int> enumerator = collection.GetEnumerator();
        while (enumerator.MoveNext())
        {
            var item = enumerator.Current;
            Console.WriteLine(item.ToString());
        }
        

        【讨论】:

          【解决方案7】:

          你可以试试这个……

          List<int> numbers = new List<int>();
                  numbers.Add(5);
                  numbers.Add(15);
                  numbers.Add(25);
                  numbers.Add(35);
          
                  Console.WriteLine("You are added total number: {0}",numbers.Count);
                  foreach (int number in numbers)
                  {
                      Console.WriteLine("Your adding Number are: {0}", number);
                  }
          

          【讨论】:

            猜你喜欢
            • 2016-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2019-01-21
            • 2021-10-22
            • 2016-12-27
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多