如何用ArgumentSyntax代替ExpressionSyntax

本文关键字:ExpressionSyntax 代替 ArgumentSyntax 何用 | 更新日期: 2023-09-27 18:08:26

我想知道我有什么选择?我有这样一种情况:

public event EventHandler<EventArgs> Changed;
FooBase()
{
    Changed += new EventHandler<EventArgs>(HandleChanged);
}
void HandleChanged(object sender, EventArgs e)
{
}

必须被修复并更改为以下代码:

   public class FooBase
   {
    public event EventHandler<EventArgs> Changed;
    FooBase()
    {
        Changed += HandleChanged;
    }
    void HandleChanged(object sender, EventArgs e)
    {
    }
   }

在这种情况下,委托的创建是多余的。我正面临着一个ObjectCreationExpression,我需要用它的参数(ArgumentSyntax)替换它。

在下面的代码中,除了我将要说的内容之外,我几乎拥有了所有内容。赋值表达式由它的左右两部分组成。这两个都是表达式语法。目前困扰我的是,我需要创建一个表达式语法的参数语法不能发生在我的时刻,我正在寻找一种方法如何做到这一点!

代码修复:

        public async override Task RegisterCodeFixesAsync(CodeFixContext context)
    {
        var document = context.Document;
        var cancellationToken = context.CancellationToken;
        var span = context.Span;
        var diagnostics = context.Diagnostics;
        var root = await document.GetSyntaxRootAsync(cancellationToken);
        var diagnostic = diagnostics.First();
        var assignmentExpression = root.FindNode(context.Span) as AssignmentExpressionSyntax;
        var objectCreation = assignmentExpression?.Right as ObjectCreationExpressionSyntax;
        var argument = objectCreation?.ArgumentList.Arguments[0];
        if (argument == null)
            return;
        var argumentAsExpressionStatement = SyntaxFactory.AssignmentExpression(assignmentExpression.Kind(),
            assignmentExpression.Left, argument); //Does not compile
        var newRoot = root.ReplaceNode(objectCreation, 
            argument
            .WithoutLeadingTrivia()
            .WithAdditionalAnnotations(Formatter.Annotation));
        context.RegisterCodeFix(CodeActionFactory.Create(assignmentExpression.Span, diagnostic.Severity, "Remove redundant 'new'", document.WithSyntaxRoot(newRoot)), diagnostic);
    }

对于那些可能想知道我是如何找出一个委托的创建是多余的,这里是我使用的代码分析:

using System;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.Diagnostics;
using System.Collections.Immutable;
using System.Linq;
namespace RefactoringEssentials.CSharp.Diagnostics
{
    [DiagnosticAnalyzer(LanguageNames.CSharp)]
    public class RedundantDelegateCreationAnalyzer : DiagnosticAnalyzer
    {
        private static readonly DiagnosticDescriptor descriptor = new DiagnosticDescriptor(
            CSharpDiagnosticIDs.RedundantDelegateCreationAnalyzerID,
            GettextCatalog.GetString("Explicit delegate creation expression is redundant"),
            GettextCatalog.GetString("Redundant explicit delegate declaration"),
            DiagnosticAnalyzerCategories.RedundanciesInCode,
            DiagnosticSeverity.Warning,
            isEnabledByDefault: true,
            helpLinkUri: HelpLink.CreateFor(CSharpDiagnosticIDs.RedundantDelegateCreationAnalyzerID),
            customTags: DiagnosticCustomTags.Unnecessary
        );
        public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics => ImmutableArray.Create(descriptor);
        public override void Initialize(AnalysisContext context)
        {
            context.RegisterSyntaxNodeAction(
                (nodeContext) =>
                {
                    Diagnostic diagnostic;
                    if (TryGetDiagnostic(nodeContext, out diagnostic))
                    {
                        nodeContext.ReportDiagnostic(diagnostic);
                    }
                },
                 SyntaxKind.ExpressionStatement
            );
        }
        private static bool TryGetDiagnostic(SyntaxNodeAnalysisContext nodeContext, out Diagnostic diagnostic)
        {
            diagnostic = default(Diagnostic);
            if (nodeContext.IsFromGeneratedCode())
                return false;

            var semanticModel = nodeContext.SemanticModel;
            var expressionStatement = nodeContext.Node as ExpressionStatementSyntax;
            var addOrSubstractExpression = expressionStatement?.Expression as AssignmentExpressionSyntax;
            var rightMember = addOrSubstractExpression?.Right as ObjectCreationExpressionSyntax;
            if (rightMember == null || rightMember.ArgumentList.Arguments.Count != 1)
                return false; 
            var leftTypeInfo = ModelExtensions.GetTypeInfo(semanticModel, addOrSubstractExpression.Left).ConvertedType;
            if (leftTypeInfo == null || leftTypeInfo.Kind.Equals(SyntaxKind.EventDeclaration))
                return false;
            diagnostic = Diagnostic.Create(descriptor, addOrSubstractExpression.Right.GetLocation());
            return true;
        }
    }
}

如何用ArgumentSyntax代替ExpressionSyntax

如果我很好地理解你的问题,你只需要用IdentifierNameSyntax (HandleChanged)代替ObjectCreationExpressionSyntax而不是ArgumentSyntax。以下是编辑后的代码

public async override Task RegisterCodeFixesAsync(CodeFixContext context)
{
    var document = context.Document;
    var cancellationToken = context.CancellationToken;
    var span = context.Span;
    var diagnostics = context.Diagnostics;
    var root = await document.GetSyntaxRootAsync(cancellationToken);
    var diagnostic = diagnostics.First();
    var assignmentExpression = root.FindNode(context.Span) as AssignmentExpressionSyntax;
    var objectCreation = assignmentExpression?.Right as ObjectCreationExpressionSyntax;
    var argument = objectCreation?.ArgumentList.Arguments[0];
    if (argument == null)
        return;
   var identifier = argument.DescendantNodes()
                    .OfType<IdentifierNameSyntax>).First();
   var newRoot = root.ReplaceNode(objectCreation,
           SyntaxFactory.IdentifierName(identifier.Identifier.Text)); 

context.RegisterCodeFix(CodeActionFactory.Create(assignmentExpression.Span, diagnostic.Severity, "Remove redundant 'new'", document.WithSyntaxRoot(newRoot)), diagnostic);
}

我发现在ArgumentSyntax类中,有一个类型为ExpressionSyntax的属性,它指定了将被委托引用的方法的引用。

所以,代码变成了这样!:

        var assignmentExpression = root.FindNode(context.Span) as AssignmentExpressionSyntax;
        var objectCreation = assignmentExpression?.Right as ObjectCreationExpressionSyntax;
        var argument = objectCreation?.ArgumentList.Arguments[0];
        if (argument == null)
            return;
        var newRoot = root.ReplaceNode(objectCreation, 
            argument.Expression
            .WithoutLeadingTrivia()
            .WithAdditionalAnnotations(Formatter.Annotation));
        context.RegisterCodeFix(CodeActionFactory.Create(assignmentExpression.Span, diagnostic.Severity, "Remove redundant 'new'", document.WithSyntaxRoot(newRoot)), diagnostic);
相关文章:
  • 没有找到相关文章