哪些类型的类可以使用foreach
循环?
Answers:
实际上,严格来说,您需要使用的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) {...}
kinda之类的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
”在循环内(C#5.0)与外部(C#4.0以上)的位置不同。如果您i
在代码块内使用匿名方法/ lambda,则非常重要。但这是另一个故事;-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的介绍,使用鸭子输入。
重要的是要注意“集合元素的类型必须可以转换为标识符类型”。如果实例类型不能分配给引用类型,则有时无法在编译时进行检查,并且会生成运行时异常。
如果水果篮中有非Apple(例如橙色),则会生成运行时异常。
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());
}