C# 罗斯林·伊夫曼的声明

C# 罗斯林·伊夫曼的声明,c#,roslyn,C#,Roslyn,我正在使用Roslyn语法树来更新if/else语句。这是我的密码: foreach (StatementSyntax statement in blockNode.Statements) { if (statement.IsKind(SyntaxKind.IfStatement)) { BlockSyntax ifBlock = statement.ChildNodes().OfType<BlockSyntax>().FirstOrDefault()

我正在使用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);
    }
}
DocumentEditor editor = DocumentEditor.CreateAsync(doc).Result;
editor.InsertBefore(blockNode, newEntryCode);
editor.InsertAfter(blockNode, newExitCode);
Document newDoc = editor.GetChangedDocument();
异常为:Microsoft.CodeAnalysis.CSharp.dll中发生“System.InvalidOperationException”类型的异常,但未在用户代码中处理

其他信息:指定的项不是列表的元素

我必须用发电机吗?我错过了什么


谢谢

我相信这里的问题在于,您可以从
语句
创建一个新树,然后尝试使用该新树的部分内容与
语句
进行比较

基本上,这条线在第二次运行时没有任何作用:

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

  • newRss
    来自
    block
  • block
    来自
    elseBlock
  • elseBlock
    来自原始的
    语句
尝试同时对语法树应用多个更改时,有三个选项:

  • 使用-请参阅:
  • 使用(第235行和第239行)
  • 使用

  • 我的理解是,
    DocumentEditor
    是最简单的选择,它负责在封面下为您跟踪/注释节点

    我认为这里的问题在于,您可以从
    语句
    创建一个新树,然后尝试使用该新树的部分内容与
    语句
    进行比较

    基本上,这条线在第二次运行时没有任何作用:

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

    • newRss
      来自
      block
    • block
      来自
      elseBlock
    • elseBlock
      来自原始的
      语句
    尝试同时对语法树应用多个更改时,有三个选项:

  • 使用-请参阅:
  • 使用(第235行和第239行)
  • 使用

  • 我的理解是,
    DocumentEditor
    是最简单的选择,它负责在封面下为您跟踪/注释节点

    下面是我如何解决这个问题的。我使用SyntaxGenerator重写if语句,然后在重写某些方法时使用DocumentEditor保存对语法树的所有更改。以下是相关代码:

    SyntaxGenerator synGen = editor.Generator;
    foreach (StatementSyntax statement in blockNode.Statements)
    {
        if (statement.IsKind(SyntaxKind.IfStatement))
        {
            IfStatementSyntax ifs = statement as IfStatementSyntax;
            SyntaxList<StatementSyntax> trueStatements = new SyntaxList<StatementSyntax>();
            SyntaxList<StatementSyntax> falseStatements = new SyntaxList<StatementSyntax>();
    
            BlockSyntax ifBlock = ifs.ChildNodes().OfType<BlockSyntax>().FirstOrDefault();
            if (ifBlock != null)
            {
                ReturnStatementSyntax newRSS = ifBlock.ChildNodes().OfType<ReturnStatementSyntax>().FirstOrDefault();
                SyntaxList<StatementSyntax> ifStatements = ifBlock.Statements;
                foreach (StatementSyntax ss in ifStatements)
                {
                    if (ss.Kind() != SyntaxKind.ReturnStatement)
                    {
                        trueStatements = trueStatements.Add(ss);
                    }
                 }
                 foreach (StatementSyntax ss in newExitCode)
                 {
                     trueStatements = trueStatements.Add(ss);
                 }
                 trueStatements = trueStatements.Add(newRSS);
                 ElseClauseSyntax elseBlock = ifs.ChildNodes().OfType<ElseClauseSyntax>().FirstOrDefault();
                 if (elseBlock != null)
                 {
                     BlockSyntax block = elseBlock.ChildNodes().OfType<BlockSyntax>().FirstOrDefault();
                     if (block != null)
                     {
                         ReturnStatementSyntax newRSS = block.ChildNodes().OfType<ReturnStatementSyntax>().FirstOrDefault();
                         SyntaxList<StatementSyntax> elseStatements = block.Statements;
                         foreach (StatementSyntax ss in elseStatements)
                         {
                             if (ss.Kind() != SyntaxKind.ReturnStatement)
                             {
                                 falseStatements = falseStatements.Add(ss);
                             }
                         }
                         foreach (StatementSyntax ss in newExitCode)
                         {
                             falseStatements = falseStatements.Add(ss);
                         }
                         falseStatements = falseStatements.Add(newRSS);
                     }
                 }
                 IfStatementSyntax newIfStatement = (IfStatementSyntax)synGen.IfStatement(ifs.Condition, trueStatements, falseStatements);
                 newBlock = newBlock.Add(newIfStatement);
            }
            else
            {
                if (!statement.IsKind(SyntaxKind.ReturnStatement))
                {
                    newBlock = newBlock.Add(statement);
                }
                else
                {
                    newBlock = newBlock.AddRange(newExitCode);
                    newBlock = newBlock.Add(statement);
                }
            }
        }
    }
    var newBody = SyntaxFactory.Block(SyntaxFactory.Token(SyntaxKind.OpenBraceToken), newBlock, SyntaxFactory.Token(SyntaxKind.CloseBraceToken));
    var newMethod = SyntaxFactory.MethodDeclaration(mds.AttributeLists, mds.Modifiers, mds.ReturnType, mds.ExplicitInterfaceSpecifier, mds.Identifier, mds.TypeParameterList, mds.ParameterList, mds.ConstraintClauses, newBody, mds.ExpressionBody);
    editor.ReplaceNode(mds, newMethod);
    SyntaxNode newRoot = editor.GetChangedRoot();
    var newFormattedRoot = Formatter.Format(newRoot, Workspace);
    Document newDoc = editor.GetChangedDocument();
    doc = doc.WithSyntaxRoot(newFormattedRoot);
    methodsChanged++;
    
    SyntaxGenerator-synGen=editor.Generator;
    foreach(blockNode.Statements中的语句语法语句)
    {
    if(statement.IsKind(SyntaxKind.IfStatement))
    {
    IfStatementSyntax ifs=作为IfStatementSyntax的语句;
    SyntaxList trueStatements=新的SyntaxList();
    SyntaxList falseStatements=新SyntaxList();
    BlockSyntax ifBlock=ifs.ChildNodes().OfType().FirstOrDefault();
    if(ifBlock!=null)
    {
    ReturnStatementSyntax newRSS=ifBlock.ChildNodes().OfType().FirstOrDefault();
    syntaxlistifstatements=ifBlock.Statements;
    foreach(ifStatements中的语句语法)
    {
    if(ss.Kind()!=SyntaxKind.ReturnStatement)
    {
    trueStatements=trueStatements.Add(ss);
    }
    }
    foreach(newExitCode中的语句语法ss)
    {
    trueStatements=trueStatements.Add(ss);
    }
    trueStatements=trueStatements.Add(newRSS);
    ElseClauseSyntax elseBlock=ifs.ChildNodes().OfType().FirstOrDefault();
    if(elseBlock!=null)
    {
    BlockSyntax block=elseBlock.ChildNodes().OfType().FirstOrDefault();
    if(块!=null)
    {
    ReturnStatementSyntax newRSS=block.ChildNodes().OfType().FirstOrDefault();
    SyntaxList elstatements=block.Statements;
    foreach(ElsStatements中的语句语法ss)
    {
    if(ss.Kind()!=SyntaxKind.ReturnStatement)
    {
    虚假陈述=虚假陈述。添加(ss);
    }
    }
    foreach(newExitCode中的语句语法ss)
    {
    虚假陈述=虚假陈述。添加(ss);
    }
    falseStatements=falseStatements.Add(newRSS);
    }
    }
    IfStatementSyntax newIfStatement=(IfStatementSyntax)synGen.IfStatement(ifs.Condition、TrueStatement、FalseStatement);
    newBlock=newBlock.Add(newIfStatement);
    }
    其他的
    {
    if(!statement.IsKind(SyntaxKind.ReturnStatement))
    {
    newBlock=newBlock.Add(语句);
    }
    其他的
    {
    newBlock=newBlock.AddRange(newExitCode);
    newBlock=newBlock.Add(语句);
    }
    }
    }
    }
    var newBody=SyntaxFactory.Block(SyntaxFactory.Token(SyntaxKind.OpenBraceToken)、newBlock、SyntaxFactory.Token(SyntaxKind.CloseBraceToken));
    var newMethod=SyntaxFactory.MethodDeclaration(mds.AttributeList、mds.Modifiers、mds.ReturnType、mds.ExplicitInterfaceSpecifier、mds.Identifier、mds.TypeParameterList、mds.ParameterList、mds.ConstraintCauses、newBody、mds.ExpressionBody);
    ReplaceNode(mds,newMethod);
    SyntaxNode newRoot=editor.GetChangedRoot();
    var newFormattedRoot=Formatter.Format(newRoot,Workspace);
    Document newDoc=editor.GetChangedDocument();
    doc=doc.WithSyntaxRoot(newFormattedRoot);
    方法改变++;
    

    感谢Josh Varty和Jeroen Vannevel帮助我解决了这个问题。

    以下是我如何解决这个问题的。我用的是S