foreach 循环如何在 C# 中工作?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/398982/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-04 01:56:42  来源:igfitidea点击:

How do foreach loops work in C#?

c#foreach

提问by user48616

Which types of classes can use foreachloops?

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

回答by George Stocker

From MSDN:

MSDN

The foreachstatement repeats a group of embedded statements for each element in an array or an object collection. The foreachstatement is used to iterate through the collection to get the desired information, but should not be used to change the contents of the collection to avoid unpredictable side effects. (emphasis mine)

foreach语句为数组或对象集合每个元素重复一组嵌入语句。该foreach语句用于遍历集合以获取所需信息,但不应用于更改集合的内容以避免不可预测的副作用。(强调我的)

So, if you have an array, you could use the foreach statement to iterate through the array, like so:

因此,如果您有一个数组,则可以使用 foreach 语句遍历该数组,如下所示:

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

You could also use it to iterate through a List<T>collection, like so:

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

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

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

回答by Marc Gravell

Actually, strictlyspeaking, all you need to use foreachis a public GetEnumerator()method that returns something with a bool MoveNext()method and a ? Current {get;}property. However, the most commonmeaning of this is "something that implements IEnumerable/IEnumerable<T>, returning an IEnumerator/IEnumerator<T>.

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

By implication, this includes anything that implements ICollection/ICollection<T>, such as anything like Collection<T>, List<T>, arrays (T[]), etc. So any standard "collection of data" will generally support foreach.

这意味着,这包括实现ICollection/ 的ICollection<T>任何内容,例如Collection<T>List<T>、数组 ( T[]) 等。因此,任何标准的“数据集合”通常都会支持foreach.

For proof of the first point, the following works just fine:

为了证明第一点,以下工作正常:

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);
        }
    }
}

How does it work?

它是如何工作的?

A foreach loop like foreach(int i in obj) {...}kinda equates to:

类似的 foreach 循环foreach(int i in obj) {...}相当于:

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

However, there are variations. For example, it the enumerator (tmp) supports IDisposable, it is used too (similar to using).

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

Note the differencein the placement of the declaration "int i" inside(C# 5.0) vs. outside(up C# 4.0) the loop. It's important if you use iin an anonymous method/lambda inside your code-block. But that is another story ;-p

请注意声明“ int i循环内部(C# 5.0)与外部(C# 4.0 以上)的位置上的差异。如果您i在代码块内使用匿名方法/lambda,这一点很重要。但那是另一个故事;-p

回答by tuinstoel

According to the blog post Duck Notation, duck typing is used.

根据博客文章Duck Notation,使用了鸭子类型。

回答by Amy B

Here's the docs: Main articleWith ArraysWith Collection Objects

这是文档: 主要文章带有集合对象的数组

It's important to note that "The type of the collection element must be convertible to the identifier type". This sometimes cannot be checked at compile time and can generate a runtime exception if the instance type is not assignable to the reference type.

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

This will generate a runtime exception if there is an non-Apple in the fruit basket, such as an orange.

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

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

This safely filters the list to only the Apples using Enumerable.OfType

这可以安全地使用Enumerable.OfType将列表过滤为仅 Apples

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

回答by shahzad

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);
    }
}

回答by Dedarul

you can try this...

你可以试试这个...

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);
        }

回答by r23

Useful info regarding this subject can be found on MSDNtoo. Taking the essence from that article:

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

The foreach keyword enumerates a collection, executing the embedded statement once for each element in the collection:

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

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

The compiler translates the foreach loop shown in the above example into something similar to this construct:

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

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