如何在 C# 中的自定义对象上使用 foreach 关键字
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/348964/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to use foreach keyword on custom Objects in C#
提问by user42070
Can someone share a simple example of using the foreach
keyword with custom objects?
有人可以分享一个将foreach
关键字用于自定义对象的简单示例吗?
采纳答案by Jon Skeet
Given the tags, I assume you mean in .NET - and I'll choose to talk about C#, as that's what I know about.
鉴于标签,我假设您的意思是在 .NET 中 - 我将选择谈论 C#,因为这就是我所知道的。
The foreach
statement (usually) uses IEnumerable
and IEnumerator
or their generic cousins. A statement of the form:
该foreach
语句(通常)使用IEnumerable
和/IEnumerator
或它们的通用表亲。声明形式:
foreach (Foo element in source)
{
// Body
}
where source
implements IEnumerable<Foo>
is roughlyequivalent to:
其中source
器具IEnumerable<Foo>
是大致等效于:
using (IEnumerator<Foo> iterator = source.GetEnumerator())
{
Foo element;
while (iterator.MoveNext())
{
element = iterator.Current;
// Body
}
}
Note that the IEnumerator<Foo>
is disposed at the end, however the statement exits. This is important for iterator blocks.
请注意,IEnumerator<Foo>
被处理在最后,但是语句退出。这对于迭代器块很重要。
To implement IEnumerable<T>
or IEnumerator<T>
yourself, the easiest way is to use an iterator block. Rather than write all the details here, it's probably best to just refer you to chapter 6 of C# in Depth, which is a free download. The whole of chapter 6 is on iterators. I have another couple of articles on my C# in Depth site, too:
要实现IEnumerable<T>
或IEnumerator<T>
自己实现,最简单的方法是使用迭代器块。与其在此处写下所有详细信息,不如仅将您介绍给C# in Depth 的第 6 章,该章可免费下载。整个第 6 章都是关于迭代器的。我的 C# in Depth 网站上还有另外几篇文章:
As a quick example though:
举个简单的例子:
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
}
To implement IEnumerable<T>
for a type, you can do something like:
要实现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
}
}
回答by Mats Fredriksson
(I assume C# here)
(我假设 C# 在这里)
If you have a list of custom objects you can just use the foreach in the same way as you do with any other object:
如果您有一个自定义对象列表,您可以像使用任何其他对象一样使用 foreach:
List<MyObject> myObjects = // something
foreach(MyObject myObject in myObjects)
{
// Do something nifty here
}
If you want to create your own container you can use the yield keyword (from .Net 2.0 and upwards I believe) together with the IEnumerable interface.
如果您想创建自己的容器,您可以将 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();
}
}
And then use it with foreach:
然后将它与 foreach 一起使用:
MyContainer myContainer = new MyContainer(10);
foreach(int i in myContainer)
Console.WriteLine(i);
回答by Brackets
From MSDN Reference:
从MSDN 参考:
The foreach statement is not limited to IEnumerable
types and can be applied to an instance of any type that satisfies the following conditions:
foreach 语句不限于IEnumerable
类型,可以应用于满足以下条件的任何类型的实例:
has the public parameterless GetEnumerator
method whose return type is either class, struct, or interface type,
the return type of the GetEnumerator
method has the public Current property and the public parameterless MoveNext
method whose return type is Boolean.
具有GetEnumerator
返回类型为类、结构或接口类型GetEnumerator
的公共无参数MoveNext
方法,该方法的返回类型具有公共 Current 属性和公共无参数方法,其返回类型为布尔值。
If you declare those methods, you can use foreach
keyword without IEnumerable
overhead. To verify this, take this code snipped and see that it produces no compile-time error:
如果声明这些方法,则可以使用foreach
关键字而无需IEnumerable
开销。要验证这一点,请截断此代码并查看它是否不会产生编译时错误:
class Item
{
public Item Current { get; set; }
public bool MoveNext()
{
return false;
}
}
class Foreachable
{
Item[] items;
int index;
public Item GetEnumerator()
{
return items[index];
}
}
Foreachable foreachable = new Foreachable();
foreach (Item item in foreachable)
{
}