Jon*_*eet 41
鉴于标签,我认为你的意思是在.NET中 - 我会选择谈论C#,因为这就是我所知道的.
该foreach声明(通常)使用IEnumerable和IEnumerator或他们的共通表兄弟.表格声明:
foreach (Foo element in source)
{
// Body
}
Run Code Online (Sandbox Code Playgroud)
其中source器具IEnumerable<Foo>是大致等效于:
using (IEnumerator<Foo> iterator = source.GetEnumerator())
{
Foo element;
while (iterator.MoveNext())
{
element = iterator.Current;
// Body
}
}
Run Code Online (Sandbox Code Playgroud)
请注意,IEnumerator<Foo>它位于末尾,但语句退出.这对于迭代器块很重要.
要实现IEnumerable<T>或IEnumerator<T>自己,最简单的方法是使用迭代器块.而不是在这里写下所有细节,最好只是引用你到深度C#的第6章,这是一个免费下载.整个第6章是关于迭代器的.我在深度网站上的C#上还有另外两篇文章:
作为一个简单的例子:
public IEnumerable<int> EvenNumbers0To10()
{
for (int i=0; i <= 10; i += 2)
{
yield return i;
}
}
// Later
foreach (int x in EvenNumbers0To10())
{
Console.WriteLine(x); // 0, 2, 4, 6, 8, 10
}
Run Code Online (Sandbox Code Playgroud)
要实现IEnumerable<T>类型,您可以执行以下操作:
public class Foo : IEnumerable<string>
{
public IEnumerator<string> GetEnumerator()
{
yield return "x";
yield return "y";
}
// Explicit interface implementation for nongeneric interface
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator(); // Just return the generic version
}
}
Run Code Online (Sandbox Code Playgroud)
(我在这里假设C#)
如果您有自定义对象列表,则可以像使用任何其他对象一样使用foreach:
List<MyObject> myObjects = // something
foreach(MyObject myObject in myObjects)
{
// Do something nifty here
}
Run Code Online (Sandbox Code Playgroud)
如果你想创建自己的容器,可以使用yield关键字(从.Net 2.0及以上我相信)和IEnumerable接口.
class MyContainer : IEnumerable<int>
{
private int max = 0;
public MyContainer(int max)
{
this.max = max;
}
public IEnumerator<int> GetEnumerator()
{
for(int i = 0; i < max; ++i)
yield return i;
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}
Run Code Online (Sandbox Code Playgroud)
然后将它与foreach一起使用:
MyContainer myContainer = new MyContainer(10);
foreach(int i in myContainer)
Console.WriteLine(i);
Run Code Online (Sandbox Code Playgroud)