简体   繁体   English

IEnumerable的 <T> 在C#中

[英]IEnumerable<T> in C#

I am trying to get the following code to compile but am getting errors in VS2008. 我试图让以下代码编译,但在VS2008中遇到错误。 Anyone can tell me where I am going wrong? 谁能告诉我哪里出错了?

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);
        }
    }
}

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 r at 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 + dot-key),它应该建议你添加“using 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 answer as well, it shows a better (in my opinion at least) way to write this whole code. 最后看到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);
    }
}

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. C#3.0 afaik。 Pay attention to the seemingly endless loop in the getter, and the call to Take(1000). 注意getter中看似无穷无尽的循环,以及对Take(1000)的调用。 With this method you now have an 'endless' sequence of natural numbers (endless up until the maxvalue of an int). 使用这种方法,您现在可以拥有一个“无穷无尽”的自然数序列(直到int的maxvalue为止)。 It won't get stuck, as long as you tell it to take a specific amount. 只要你告诉它采取特定的金额,它就不会卡住。

DISCLAIMER: Most of the code borrowed from Earwicker's answer. 免责声明:大多数代码都是从Earwicker的答案中借来的。

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有正确的答案,我知道这是学习代码,但为了进一步学习,我想提两件事:

  1. Enumerable.Range()
  2. Take some time to think about this implementation: 花点时间考虑一下这个实现:

.

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);
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM