86

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

4

7 回答 7

166

实际上,严格来说,您需要使用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 循环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
}

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

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

于 2008-12-29T23:01:43.240 回答
7

来自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);
}
于 2008-12-29T22:55:11.770 回答
4

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

于 2008-12-29T23:12:54.857 回答
2

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

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

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

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

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

foreach(Apple a in fruitBasket.OfType<Apple>() )
于 2008-12-29T23:24:50.307 回答
-1
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);
    }
}
于 2017-03-17T10:40:18.810 回答
-1

也可以在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());
}
于 2018-04-24T14:20:58.230 回答
-2

你可以试试这个...

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);
        }
于 2018-03-31T07:18:28.670 回答