哪些类型的类可以使用foreach
循环?
7 回答
实际上,严格来说,您需要使用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
来自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,使用了鸭子类型。
需要注意的是“集合元素的类型必须可转换为标识符类型”。这有时无法在编译时检查,如果实例类型不可分配给引用类型,则可能会生成运行时异常。
如果水果篮里有非苹果,例如橙子,这将产生运行时异常。
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>() )
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);
}