C# Yield 后续到底

问题描述 投票:0回答:2

如果我调用方法A,然后调用方法B,输出是:“121234”。但我需要输出:来自方法A的“1234”、“12”和来自方法B的“34”。我需要记住 getNumber 在哪里结束并返回,下一个调用从这里继续。有可能的?

方法A片段集

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
2个回答
4
投票

您可以在方法之外初始化

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

0
投票

GetNumber
更改为

static int x = 0;

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

问题是您有两个

GetNumber
枚举。通过使
x
静态,您将获得您想要的结果。但请注意,这不是线程安全的代码。

© www.soinside.com 2019 - 2024. All rights reserved.