C#:使一个类在foreach中可用

时间:2015-03-24 11:56:00

标签: c# ienumerable primes

我对这件事有点问题: 我必须在C#中创建一个PrimeCollection类,它实现IEnumerable接口并动态生成素数集合。

所以,如果我写一个像这样的测试:

static void Main(string[] args) {
    PrimeCollection pc = new PrimeCollection();
    foreach (int p in pc)
        Console.WriteLine(p);
}

它应该生成素数,直到达到int32 limit。

到目前为止,我有这个:

class PrimeCollection {
    public IEnumerable<int> Primes() {
        var ints = Enumerable.Range(2, Int32.MaxValue - 1);
        return ints.Where(x => !ints.TakeWhile(y => y < Math.Sqrt(x)).Any(y => x % y == 0));
    }
}

然而要做生成我需要像这样调出它:

static void Main(string[] args) {
    PrimeCollection pc = new PrimeCollection();
    foreach (int p in pc.Primes())
        Console.WriteLine(p);
}

我假设我需要创建IEnumerable类,而不是方法,但我不知道如何动态生成数字。

3 个答案:

答案 0 :(得分:2)

没有理由拥有一个可实例化的类。你没有举办州。

public static class Prime
{
    public static IEnumerable<int> Values() 
    {
        var ints = Enumerable.Range(2, Int32.MaxValue - 1);
        return ints.Where(x => !ints.TakeWhile(y => y < Math.Sqrt(x)).Any(y => x % y == 0));
    }
}

然后你可以像这样使用它:

static void Main(string[] args) 
{
    foreach (int p in Prime.Values())
        Console.WriteLine(p);
}

答案 1 :(得分:2)

如果要专门创建自定义primes-enumerable,可以将其定义为现有linq查询的包装器。像这样:

public class PrimesEnumerable : IEnumerable<int> {
    public PrimesEnumerable() {
        var ints = Enumerable.Range(2, Int32.MaxValue - 1);
        _internalEnumerable = ints.Where(x => !ints.TakeWhile(y => y*y<=x).Any(y => x % y == 0));
    }
    public readonly IEnumerable<int> _internalEnumerable;

    public IEnumerator<int> GetEnumerator() {
        return _internalEnumerable.GetEnumerator();
    }

    System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() {
        return _internalEnumerable.GetEnumerator();
    }
}

现在你可以预告它了:

var primes = new PrimesEnumerable();

int i = 0;
foreach (var prime in primes) {
    if (i == 10)
        break;

    Console.WriteLine(prime);
    i++;
}
Console.ReadLine();

注意:确定@CarstenKönig正在谈论的错误。

答案 2 :(得分:1)

你的意思是这样的吗?

class Program
{
    static void Main(string[] args)
    {
        foreach(var prime in new PrimeCollection())
        {
            Console.WriteLine(prime);
        }
        Console.Read();
    }
}

class PrimeCollection : IEnumerable
{
    public IEnumerator GetEnumerator()
    {
        var ints = Enumerable.Range(2, Int32.MaxValue - 1);
        return ints.Where(x => !ints.TakeWhile(y => y < Math.Sqrt(x)).Any(y => x % y == 0)).GetEnumerator();
    }
}