简体   繁体   English

C#yield后续到底

[英]C# yield Follow-up to the end

If I call methodA and then methodB output is: "121234". 如果我调用methodA然后methodB输出是:“121234”。 But I need output: "1234", "12" from methodA and "34" from methodB. 但我需要输出:方法A中的“1234”,“12”和方法B中的“34”。 I need to remember where getNumber ended with the return, and the next call continue from here. 我需要记住getNumber在返回时的结束位置,下一次调用将从此处继续。 It is possible? 有可能的?

MethodA snipset MethodA snipset

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

MethodB snipset MethodB snipset

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

GetNumber GetNumber

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

You can initialize x outside the method: 您可以在方法外初始化x

static class InfiniteContinuingSequence
{
    static int x = 0;

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

But you will have to explicitly be careful when and where this sequence gets enumerated. 但是,您必须明确注意枚举此序列的时间和位置。 If it is inadvertently enumerated multiple times, you will "lose" numbers in the sequence; 如果无意中多次枚举,您将在序列中“丢失”数字; if you try to exhaustively enumerate GetNumbers() you'll get either an infinite loop or an overflow; 如果你试图详尽地枚举GetNumbers()你将获得无限循环或溢出; and if you try to call this from multiple threads without locking, you'll get potentially odd behavior. 如果你试图从没有锁定的多个线程调用它,你将得到可能奇怪的行为。


Instead, I might suggest to either use an explicit enumerator, or be able to specify a "restart point" to your method (in this case at least you will not get odd behavior by multiple enumerations): 相反,我可能会建议使用显式枚举器,或者能够为您的方法指定一个“重启点”(在这种情况下,至少您不会通过多个枚举获得奇怪的行为):

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

Change GetNumber to GetNumber更改为

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

The issue is that you have two enumerations of GetNumber. 问题是您有两个GetNumber枚举。 By making x static you will get the results you want. 通过使x静态,您将获得所需的结果。 But beware this is not thread safe code. 但要注意这不是thread safe代码。

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

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