【问题标题】:C# yield Follow-up to the endC# yield 跟进到最后
【发布时间】:2013-12-24 00:29:22
【问题描述】:

如果我调用 methodA 然后 methodB 输出是:“121234”。但我需要输出:来自methodA的“1234”、“12”和来自methodB的“34”。我需要记住 getNumber 以返回结束的位置,并且下一个调用从这里继续。有可能的?

方法片段集

int x = 0;
foreach (var num in GetNumber())
{
    if (x == 2)
    {
        break;
    }
    x++;
    Console.Write(num);
}

方法B 片段集

int x = 0;
foreach (var num in GetNumber())
{
    if (x == 4)
    {
        break;
    }
    x++;
    Console.Write(num);
}

获取号码

static IEnumerable<int> GetNumber()
{
    int x = 0;
    while (true)
    {
        yield return x++;
    }
}

【问题讨论】:

    标签: c# yield yield-keyword


    【解决方案1】:

    可以在方法外初始化x

    static class InfiniteContinuingSequence
    {
        static int x = 0;
    
        public static IEnumerable<int> GetNumbers()
        {
            while (true)
            {
                yield return x++;
            }
        }
    }
    

    但您必须明确注意枚举此序列的时间和地点。如果不小心被枚举了多次,就会“丢失”序列中的数字;如果您尝试详尽枚举GetNumbers(),您将获得无限循环或溢出;如果你尝试从多个线程调用它而不加锁,你会得到潜在的奇怪行为。


    相反,我可能会建议使用显式枚举器,或者能够为您的方法指定一个“重启点”(在这种情况下,至少您不会因多次枚举而出现奇怪的行为):

    static IEnumerable<int> GetNumbers(int startingPoint = 0)
    {
        int x = startingPoint;
        while (true)
        {
            yield return x++;
        }
    }
    

    【讨论】:

      【解决方案2】:

      GetNumber 更改为

      static int x = 0;
      static IEnumberable<int> GetNumber()
      {
         while (true) { yield return x++; }
      }
      

      问题是您有两个 GetNumber 枚举。通过将x 设为静态,您将获得您想要的结果。但请注意这不是thread safe 代码。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-09-30
        • 2017-02-21
        • 2014-01-10
        • 2018-09-17
        • 2014-06-14
        • 2016-10-04
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多