【发布时间】:2008-12-29 22:52:46
【问题描述】:
哪些类型的类可以使用foreach 循环?
【问题讨论】:
-
您可能需要选择一个不同的可接受答案,因为您选择的答案并不能真正代表正确答案。
哪些类型的类可以使用foreach 循环?
【问题讨论】:
实际上,严格来说,你需要使用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 i”inside (C# 5.0) 与 outside (up C# 4.0) 位置的区别 ) 循环。如果您在代码块内的匿名方法/lambda 中使用i,这一点很重要。但那是另一回事了;-p
【讨论】:
for-loop(使用 IL 时可以看到)。
来自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);
}
【讨论】:
根据博文Duck Notation,使用了duck typing。
【讨论】:
这是文档: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>() )
【讨论】:
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);
}
}
【讨论】:
也可以在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());
}
【讨论】:
你可以试试这个……
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);
}
【讨论】: