I was recently asked how one could remove extra parentheses from a ObjectCreationExpressionSyntax when they are deemed redundant. For example, in the following case, the parentheses after the ProcessStartInfo are redundant:

var y = new System.Diagnostics.ProcessStartInfo() { FileName = @"C:\blah.txt" };

So the expected result after the code fix would be:

var y = new System.Diagnostics.ProcessStartInfo { FileName = @"C:\blah.txt" };

To start, we need to create an analyzer that identifies this scenario. Luckily, this is fairly easy. We can start by registering a SyntaxNodeAction for all SyntaxKind.ObjectCreationExpressoin kinds in the code. Inside this code, we will just check for an empty argument list and a non missing initializer:

public override void Initialize(AnalysisContext context)

    context.RegisterSyntaxNodeAction((syntaxContext) =>
        var node = syntaxContext.Node as ObjectCreationExpressionSyntax;

        if (node.ArgumentList.Arguments.Any())

        if (node.Initializer.IsMissing)

        syntaxContext.ReportDiagnostic(Diagnostic.Create(Rule, syntaxContext.Node.GetLocation()));
    }, SyntaxKind.ObjectCreationExpression);

Now that we have a working analyzer, we can look at the codefix. Luckily the codefix for this analyzer is also very simple. We just need to look for the ArgumentList syntax node and remove that from the document.

public override async Task RegisterCodeFixesAsync(CodeFixContext context)

    var diagnostic = context.Diagnostics.First();
    context.RegisterCodeFix(CodeAction.Create("Remove parens", async token =>

        var document = context.Document;
        var root = await document.GetSyntaxRootAsync(token);

        var objectCreationNode = root.FindNode(diagnostic.Location.SourceSpan, false) as ObjectCreationExpressionSyntax;
        // Find the arguments list to remove
        var nodeToRemove =objectCreationNode.ChildNodes().Where(x => x.IsKind(SyntaxKind.ArgumentList)).First();
        var newDoc = document.WithSyntaxRoot(root.RemoveNode(nodeToRemove, SyntaxRemoveOptions.KeepTrailingTrivia));
        return newDoc;
    }, RedundantParensAnalyzer.DiagnosticId), diagnostic);

Note that we keep the trailing trivia in this case as that is that pattern that feels right for this code fix.

That's all there is to it. Now this code fix will properly remove the redundant parentheses whenever a diagnostic is raised.