Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/198.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/325.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 如何从上一个返回点恢复方法?_Android_C#_Iterator_Yield Return - Fatal编程技术网

Android 如何从上一个返回点恢复方法?

Android 如何从上一个返回点恢复方法?,android,c#,iterator,yield-return,Android,C#,Iterator,Yield Return,我想知道C#中是否存在某种机制,允许从上次调用过程中到达的最后一个返回“恢复”方法 我需要什么:我有一个抽象语法树(AST),它是由源语言设计的解析器创建的。这个抽象语法树是一个“根类”的对象,这个“根类”具有字段和其他类的实例等。我需要做的是创建一个sequencer,它接受这个抽象语法树,并通过生成器创建其他语言的指令。指令序列以null结尾。这可以通过生成器方法next()实现,该方法调用sequencer方法,动态计算下一条指令。换句话说,我不能浏览整个抽象语法树,生成所有指令并在每次调

我想知道C#中是否存在某种机制,允许从上次调用过程中到达的最后一个返回“恢复”方法

我需要什么:我有一个抽象语法树(AST),它是由源语言设计的解析器创建的。这个抽象语法树是一个“根类”的对象,这个“根类”具有字段和其他类的实例等。我需要做的是创建一个sequencer,它接受这个抽象语法树,并通过生成器创建其他语言的指令。指令序列以null结尾。这可以通过生成器方法
next()
实现,该方法调用sequencer方法,动态计算下一条指令。换句话说,我不能浏览整个抽象语法树,生成所有指令并在每次调用
next()
时逐个返回它们,但我必须在每次生成器调用next()时创建它们中的每一个

示例:我将发布一个伪代码,以便您更好地理解问题

static void Main(string[] args)
{Parser parser = new Parser (//constructor stuff);
 Sequencer sequencer = new Sequencer(parser.Parse()); //the mehtod Parse() generates the AST
 Generator generator = new Generator(sequencer);
 Instruction instruction = generator.next();
 while(instruction)
      {print instruction
       instruction = generator.next();
      } 
}
重要提示:我希望您理解的最重要的一点是,
next()
并不总是在某种迭代中调用,因此我认为
foreach
和迭代器不是一个好的解决方案。

这是因为为了使用iterotors,我终于要写一些

foreach(instruction in next())
       {//do stuff with instruction}
我不想那样做

但是,我将让您了解应该如何构造
next()

Instruction next()
{ return sequencer.generate();}
因此,
generate()

最复杂的部分是,我需要一些具有
收益率返回
行为的东西(因此从我在下一个
generate()中离开的地方开始)
调用,但由于我前面解释的原因,没有使用迭代器。因此,在AST内部移动非常困难,因为我无法明确引用实际节点的父节点(如作为实际节点副本的字段)

由于这是不够的,您可以递归调用
generate
(例如,如果有某种迭代构造函数需要翻译)


如何实现这一点?

使用
yield return
实现主逻辑。这将创建一个枚举器。将其存储在类成员变量或其他永久性的地方


然后在返回普通对象的包装器方法中使用该枚举器,每次调用时从枚举器中提取一个新项。

使用
产生返回
来实现主逻辑。这将创建一个枚举器。将其存储在类成员变量或其他永久性位置

然后在返回普通对象的包装器方法中使用该枚举器,在每次调用时从枚举器中提取一个新项。

事实上,除了满足您的要求之外,还需要注意的是,它公开了该方法,这正是您在这里需要的

发电机:

public class Generator
{
    //...

    public IEnumerable<Instruction> Generate()
    {
        // ...
        yield return new Instruction(...);
        // ...
    }
    //...
}
我注意到可以在
IEnumerable
上调用
GetEnumerator
,这就回答了一个类似的问题

此外,正如中所指出的,您可以使用更准确地满足您需要的舒适方法包装
MoveNext
Current
。您甚至可以为
IEnumerator
类型编写扩展方法:

public static class IEnumeratorExtensions
{
    public static Instruction NextInstruction(this IEnumerator<Instruction> @this)
    {
        if (@this.MoveNext())
        {
            return @this.Current;
        }

        return null; // or throw, or whatever you like
    }
}
公共静态类IEnumeratorExtensions
{
公共静态指令下一条指令(此IEnumerator@this)
{
如果(@this.MoveNext())
{
return@this.Current;
}
返回null;//或throw,或任何您喜欢的
}
}
事实上,除了满足您的需求之外,您还需要注意的是,它公开了方法,这正是您在这里需要的

发电机:

public class Generator
{
    //...

    public IEnumerable<Instruction> Generate()
    {
        // ...
        yield return new Instruction(...);
        // ...
    }
    //...
}
我注意到可以在
IEnumerable
上调用
GetEnumerator
,这就回答了一个类似的问题

此外,正如中所指出的,您可以使用更准确地满足您需要的舒适方法包装
MoveNext
Current
。您甚至可以为
IEnumerator
类型编写扩展方法:

public static class IEnumeratorExtensions
{
    public static Instruction NextInstruction(this IEnumerator<Instruction> @this)
    {
        if (@this.MoveNext())
        {
            return @this.Current;
        }

        return null; // or throw, or whatever you like
    }
}
公共静态类IEnumeratorExtensions
{
公共静态指令下一条指令(此IEnumerator@this)
{
如果(@this.MoveNext())
{
return@this.Current;
}
返回null;//或throw,或任何您喜欢的
}
}

如果你告诉你想解决什么问题,答案很容易。这看起来像是一个。顺便说一句,你问的是状态机。你唯一想
返回的问题是什么(没有);
而不是
返回一些对象;
?我同意你的观点,但我不能发布整个“代码生成器”我应该发布抽象语法树类,可能还有语法分析器代码。显然,这是不可能的:DI编辑了整个问题,以便更好地理解问题及其约束。我希望它能帮助你(和我:P)@LovaJ.-我猜误解是因为您坚持认为
IEnumerator.Current
/
IEnumerator.MoveNext()
对绝对不如单个“next()”方法…如果您真的需要
next())为什么不用一个方法来包装带有辅助类的C创建的迭代器?不知道为什么你认为“代码>前缀和<代码> iQueDebug <代码>作为一个单独的不可分离的概念……如果你告诉你要解决什么问题,这将是很容易回答的。这看起来像一个BTW。你所问的被称为状态机。是唯一的PR。你想
放弃返回(无);
而不是
放弃返回某个对象;
?我同意你的观点,但我不能发布