c# - 罗斯林 If 语句

标签 c# roslyn

我正在使用 Roslyn 语法树来更新 if/else 语句。这是我的代码:

foreach (StatementSyntax statement in blockNode.Statements)
{
    if (statement.IsKind(SyntaxKind.IfStatement))
    {
        BlockSyntax ifBlock = statement.ChildNodes().OfType<BlockSyntax>().FirstOrDefault();
        if (ifBlock != null)
        {
            ReturnStatementSyntax newRSS = ifBlock.ChildNodes().OfType<ReturnStatementSyntax>().FirstOrDefault();
            blockNode = blockNode.InsertNodesBefore(newRSS, newExitCode);
        }
        ElseClauseSyntax elseBlock = statement.ChildNodes().OfType<ElseClauseSyntax>().FirstOrDefault();
        if (elseBlock != null)
        {
            BlockSyntax block = elseBlock.ChildNodes().OfType<BlockSyntax>().FirstOrDefault();
            if (block != null)
            {
                ReturnStatementSyntax newRSS = block.ChildNodes().OfType<ReturnStatementSyntax>().FirstOrDefault();
                blockNode = blockNode.InsertNodesBefore(newRSS, newExitCode);
            }
        }
        newBlock = newBlock.AddRange(blockNode.Statements);
    }
}

谁能解释为什么第一个 blockNode 插入节点有效,而第二个无效?我两次都看到了我想要插入的代码,但只有第一个更新了语法树。第二个什么都不做。

更新:我已经按照 JoshVarty 的建议进行了更改。我使用 DocumentEditor 加载更改。我现在在调用 GetChangedDocument 时遇到异常。这是我的代码:

DocumentEditor editor = DocumentEditor.CreateAsync(doc).Result;
editor.InsertBefore(blockNode, newEntryCode);
editor.InsertAfter(blockNode, newExitCode);
Document newDoc = editor.GetChangedDocument();

异常是:Microsoft.CodeAnalysis.CSharp.dll 中发生了 'System.InvalidOperationException' 类型的异常,但未在用户代码中处理

附加信息:指定的项目不是列表的元素。

我必须使用生成器吗?我错过了什么?

谢谢

最佳答案

我认为这里的问题是您从 statement 创建了一棵新树,然后尝试使用该新树的部分内容与 statement 进行比较。

基本上这条线第二次没有做任何事情:

blockNode = blockNode.InsertNodesBefore(newRSS, newExitCode);

blockNode 是您创建的全新树,不包含 newRSS。因此它无法找到 newRss 并插入您的 newExitCode

  • newRss 来自block
  • block 来自 elseBlock
  • elseBlock 来自原始语句

当尝试一次将多个更改应用到语法树时,您可以选择三个选项:

  1. 使用DocumentEditor - 请参阅:https://stackoverflow.com/a/30563669/300908
  2. 使用Annotations (第 235 和 239 行)
  3. 使用.TrackNodes()

我的理解是 DocumentEditor 是最简单的选项,它负责在幕后为您跟踪/注释节点。

关于c# - 罗斯林 If 语句,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31012602/

相关文章:

c# - Roslyn:如何获取与标识符关联的 ITypeSymbol?

c# - 寻找 C# => Linq 表达式编译器

c# - aspnetVnext 核心 CLR 中缺少 System.Drawing 命名空间

c# - 在语义模型中查找标识符

c# - linq改变结果集的值

c# - 将 XML 字符串转换为 List<T> 而无需在 C# 中指定元素根

visual-studio - 在哪里可以找到 Roslyn DEBUGGER 语法可视化工具?

C# 6 空条件运算符不适用于 LINQ 查询

c# - 逐字输出字符串属性以防止双重编码

C#:System.Windows.Controls.UserControl 作为列表框