C# Roslyn-如何在另一个语句之前和之后添加语句

C# Roslyn-如何在另一个语句之前和之后添加语句,c#,.net,roslyn,C#,.net,Roslyn,我有以下代码来检测方法调用。我想在调用语句之前和之后分别添加一个简单语句(例如Console.WriteLine(“Test”);)到源代码中,并将其保存回源文件。有任何代码片段或示例说明如何做到这一点吗 var methodDeclarations = classitem.DescendantNodes().OfType<MethodDeclarationSyntax>(); foreach (var memmeth in methodDeclarations) { va

我有以下代码来检测方法调用。我想在调用语句之前和之后分别添加一个简单语句(例如Console.WriteLine(“Test”);)到源代码中,并将其保存回源文件。有任何代码片段或示例说明如何做到这一点吗

var methodDeclarations = classitem.DescendantNodes().OfType<MethodDeclarationSyntax>();
foreach (var memmeth in methodDeclarations)
{

    var varInvocations = memmeth.DescendantNodes().OfType<InvocationExpressionSyntax>();
    foreach (InvocationExpressionSyntax invoc in varInvocations)
    {
             // insert new statement before and after the invocation
var methodDeclarations=classitem.DegenantNodes().OfType();
foreach(methodDeclarations中的var memmeth)
{
var varInvocations=memmeth.genderantnodes().OfType();
foreach(InvocationExpressionSyntax invoc在各种位置)
{
//在调用前后插入新语句

您试图将语句与表达式混合使用

如果我写

this.Test();
在我的代码中,它是ExpressionStatement中InvocationExpression中的SimpleExpressionStatement

语句基本上是表示一行代码的元素,在我们的示例中是this.Test();,可能类似于return;throw;等

因此,如果希望在表达式之前或之后插入语句,则必须在包含语句之前或之后插入语句

但是,这可能会产生问题,因为同一语句中可能有多个表达式,例如

if(Test() && Test2()){

}
因此,为了在方法调用之前或之后插入新语句,您只需找到最近的语句并在所述语句之前或之后插入,例如:

var statements = new List<StatementSyntax>();
var methodDeclarations = root.DescendantNodes().OfType<MethodDeclarationSyntax>();
foreach (var memmeth in methodDeclarations)
{
    var varInvocations = memmeth.DescendantNodes().OfType<InvocationExpressionSyntax>();
    foreach (InvocationExpressionSyntax invoc in varInvocations)
    {
        // Find the relevant node
        var statement = invoc.Ancestors().OfType<StatementSyntax>().FirstOrDefault();
        statements.Add(statement);
    }
}
// Track the nodes so you can change it in the tree even after modifying it
root = root.TrackNodes(statements.Distinct());
foreach(var statement in statements)
{
    var currentStatement = root.GetCurrentNode(statement);
    root = root.InsertNodesAfter(currentStatement,            
        new[] { SyntaxFactory.ExpressionStatement(
                    SyntaxFactory.InvocationExpression(
                        SyntaxFactory.MemberAccessExpression(
                            SyntaxKind.SimpleMemberAccessExpression, 
                            SyntaxFactory.IdentifierName("Console"), 
                            SyntaxFactory.IdentifierName("WriteLine"))
                        ))});
    currentStatement = root.GetCurrentNode(statement);
    root = root.InsertNodesBefore(currentStatement,
        new[] { SyntaxFactory.ExpressionStatement(
            SyntaxFactory.InvocationExpression(
                SyntaxFactory.MemberAccessExpression(
                    SyntaxKind.SimpleMemberAccessExpression,
                    SyntaxFactory.IdentifierName("Console"),
                    SyntaxFactory.IdentifierName("WriteLine"))
                ))});
}
var语句=新列表();
var methodDeclarations=root.degenantNodes().OfType();
foreach(methodDeclarations中的var memmeth)
{
var varInvocations=memmeth.genderantnodes().OfType();
foreach(InvocationExpressionSyntax invoc在各种位置)
{
//查找相关节点
var语句=invoc.祖先().OfType().FirstOrDefault();
报表。添加(报表);
}
}
//跟踪节点,以便即使在修改节点后也可以在树中对其进行更改
root=root.TrackNodes(statements.Distinct());
foreach(语句中的var语句)
{
var currentStatement=root.GetCurrentNode(语句);
root=root.InsertNodesAfter(currentStatement,
新[]{SyntaxFactory.ExpressionStatement(
SyntaxFactory.InvocationExpression(
SyntaxFactory.MemberAccessExpression(
SyntaxKind.SimpleMemberAccessExpression,
SyntaxFactory.IdentifierName(“控制台”),
SyntaxFactory.IdentifierName(“WriteLine”))
))});
currentStatement=root.GetCurrentNode(语句);
root=root.InsertNodesBefore(currentStatement,
新[]{SyntaxFactory.ExpressionStatement(
SyntaxFactory.InvocationExpression(
SyntaxFactory.MemberAccessExpression(
SyntaxKind.SimpleMemberAccessExpression,
SyntaxFactory.IdentifierName(“控制台”),
SyntaxFactory.IdentifierName(“WriteLine”))
))});
}

有帮助吗?谢谢@mjwills,我在那篇文章中的代码的问题是,我无法确定指定什么作为InsertNodesBefore的第一个参数,以便它正确地引用我在foreach循环中的invoc节点。因此,当我写root.InsertNodesBefore(invoc,new SyntaxNode[]{global})时;它抛出了很多例外情况@SJP感谢您的帮助!