C# 中的 IEnumerable<T>
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1174713/
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
IEnumerable<T> in C#
提问by fcuk112
I am trying to get the following code to compile but am getting errors in VS2008. Anyone can tell me where I am going wrong?
我正在尝试编译以下代码,但在 VS2008 中出现错误。谁能告诉我我哪里出错了?
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace dummy
{
public class NaturalNumbersSequence : IEnumerable<int>
{
public IEnumerator<int> GetEnumerator()
{
for (int i = 1; i <= 1000; i++)
yield return i;
}
IEnumerator IEnumerable.GetEnumerator()
{
for (int i = 1; i <= 1000; i++)
yield return i;
}
}
class Program
{
static void Main(string[] args)
{
foreach (int i in new NaturalNumbersSequence())
Console.WriteLine(i);
}
}
}
采纳答案by Lasse V. Karlsen
Well, the first compiler error I get is that it complains that:
好吧,我得到的第一个编译器错误是它抱怨:
Using the generic type 'System.Collections.Generic.IEnumerator' requires '1' type arguments
使用泛型类型“System.Collections.Generic.IEnumerator”需要“1”类型参数
This is on line 16, this one:
这是第 16 行,这个:
IEnumerator IEnumerable.GetEnumerator()
Fixing that by adding a using directive for the System.Collections
namespace (tip: place the cursor just after IEnumerator, on the rat the end of the word, and hit Ctrl+. (ctrl + the dot-key), it should suggest you add a "using System.Collections;" directive, do that).
通过为System.Collections
命名空间添加 using 指令来解决这个问题(提示:将光标放在 IEnumerator 之后,在单词末尾的r上,然后按 Ctrl+。(ctrl + 点键),它应该建议您添加一个“使用 System.Collections;" 指令,这样做)。
Then it compiles, and runs. Does that match what you expect?
然后它编译并运行。这符合你的预期吗?
Also, note that you should always post the actual error messages you're getting, this way we're not barking up the wrong tree if there's something else wrong with your code that we're not seeing at first glance.
另外,请注意,您应该始终发布您收到的实际错误消息,这样我们就不会在您的代码中出现我们乍一看没有看到的其他错误时发出错误的树。
Additionally, you can simplify this very common implementation of IEnumerable<T>
by calling one of the methods from the other, hence I would simplify the implementation of the second methods like this:
此外,您可以IEnumerable<T>
通过从另一个方法调用一个方法来简化这个非常常见的实现,因此我会像这样简化第二个方法的实现:
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator(); // this will return the one
// available through the object reference
// ie. "IEnumerator<int> GetEnumerator"
}
this way you only implement the actual enumerator code once.
这样您只需实现一次实际的枚举器代码。
And finally see Earwicker's answeras well, it shows a better (in my opinion at least) way to write this whole code.
回答by Daniel Earwicker
Not sure why you're getting errors, but wouldn't this be simpler?
不确定为什么会出现错误,但这不是更简单吗?
public static class NumbersSequence
{
public static IEnumerable<int> Naturals
{
get
{
for (int i = 1; i <= 1000; i++)
yield return i;
}
}
}
class Program
{
public static void Main(string[] args)
{
foreach (int i in NumbersSequence.Naturals)
Console.WriteLine(i);
}
}
回答by Erik van Brakel
Slightly off-topic, but perhaps interesting to see is this approach:
有点偏离主题,但也许有趣的是这种方法:
public static class NumbersSequence
{
public static IEnumerable<int> Naturals
{
get
{
int i = 0;
while(true)
yield return i++;
}
}
}
class Program
{
static void Main(string[] args)
{
foreach (int i in NumbersSequence.Naturals.Take(1000))
Console.WriteLine(i);
}
}
C# 3.0 afaik. Pay attention to the seemingly endless loop in the getter, and the call to Take(1000). With this method you now have an 'endless' sequence of natural numbers (endless up until the maxvalue of an int). It won't get stuck, as long as you tell it to take a specific amount.
C# 3.0 afaik。注意 getter 中看似无限的循环,以及对 Take(1000) 的调用。使用这种方法,您现在拥有一个“无限”的自然数序列(直到 int 的最大值为止)。只要您告诉它取特定数量,它就不会卡住。
DISCLAIMER: Most of the code borrowed from Earwicker's answer.
免责声明:大部分代码都是从 Earwicker 的回答中借来的。
回答by Joel Coehoorn
Lasse has the right answer, and I know this is learning code, but in the interest of furthering your learning I want to mention two things:
Lasse 有正确的答案,我知道这是学习代码,但为了进一步学习,我想提两件事:
Enumerable.Range()
- Take some time to think about this implementation:
Enumerable.Range()
- 花点时间考虑一下这个实现:
.
.
public class NaturalNumbersSequence : IEnumerable<int>
{
public IEnumerator<int> GetEnumerator()
{
for (int i=0 i <= int.MaxValue;i++)
yield return i;
}
IEnumerator IEnumerable.GetEnumerator()
{
for (int i=0 i <= int.MaxValue;i++)
yield return i;
}
}
class Program
{
static void Main(string[] args)
{
foreach (int i in new NaturalNumbersSequence().TakeWhile(i => i<=1000) )
Console.WriteLine(i);
}
}