-3

编辑:显然题外话...移动到Programmers.StackExchange.com

这不是一个实际问题,更像是一个谜。

问题

我很想知道是否有办法实现与以下内容等效的东西,但不使用yield

IEnumerable<T> Infinite<T>()
{
    while (true) { yield return default(T); }
}

规则

  1. 您不能使用yield关键字
  2. 仅直接使用 C# 本身 - 没有 IL 代码,没有构建动态程序集等。
  3. 您只能使用基本的 .NET 库(仅mscorlib.dll, System.Core.dll? 不知道还包括什么)。但是,如果您找到一些其他 .NET 程序集(WPF?!)的解决方案,我也很感兴趣。
  4. 不要实现 IEnumerable 或 IEnumerator。

笔记

我最近的一次:

IEnumerable<int> infinite = null;
infinite = new int[1].SelectMany(x => new int[1].Concat(infinite));

这是“正确的”,但在 14399 次迭代通过可枚举(不是完全无限)后会遇到 StackOverflowException。

我认为由于 CLR缺乏尾递归优化,可能无法做到这一点。证明会很好:)

4

3 回答 3

5
  1. 从您的问题中获取yield示例并将其转储到 Visual Studio 中。
  2. 编译。
  3. 在 Reflector/ILSpy/dotPeek/etc 中打开。并以 C# 1.0 语言级别显示反编译的源代码(或打开编译器生成的源代码的显示)。
  4. 宣布胜利,吃蛋糕。
于 2013-11-07T03:34:15.477 回答
2

这是一个几乎无限的迭代器:

using System;
using System.Linq;

public class Test
{
    public static void Main()
    {
        var infiniteIterator =
            Enumerable.Range(Int32.MinValue, Int32.MaxValue)
                      .SelectMany(i => Enumerable.Range(Int32.MinValue, Int32.MaxValue))
                      .SelectMany(i => Enumerable.Range(Int32.MinValue, Int32.MaxValue))
                      .SelectMany(i => Enumerable.Range(Int32.MinValue, Int32.MaxValue))
                      .Select(i => default(int));

        foreach (var infinite in infiniteIterator)
            Console.WriteLine(infinite);
    }
}
于 2013-11-07T04:06:20.180 回答
1

使用IEnumerable<T>yield调用一些 C# 编译器魔法,它将逻辑包装到 的实现中IEnumerable,如下所示:

IEnumerable<T> Infinite<T>() {
    return new Buzzlightyear<T>();
}
private class BuzzLightyear<T> : IEnumerable<T> where T : new() {
    public Boolean MoveNext() { return true; }
    public T Current { return new T(); }
}
于 2013-11-07T03:34:49.187 回答