Compile-time detection of accidentally assign a C# property to itself

前端 未结 2 1975
不思量自难忘°
不思量自难忘° 2021-02-06 07:59

Visual Studio C# compiler warns about accidentally assigning a variable to itself, but this warning does not apply to C# properties, only variables. As described in this other q

2条回答
  •  执念已碎
    2021-02-06 08:46

    This is the perfect situation for a Live Code Analyzer from VS2015. You could write up a basic analyzer that checks if a property is being assigned to itself and create a error.

    Here is a very good tutorial I followed a long time ago to help you get started on how to write one, they are not very hard to do: "C# and Visual Basic - Use Roslyn to Write a Live Code Analyzer for Your API"

    UPDATE: I had some free time so I wrote an analyzer up that does it.

    [DiagnosticAnalyzer(LanguageNames.CSharp)]
    public class SelfAssignmentAnalyzer : DiagnosticAnalyzer
    {
        public const string DiagnosticId = "SelfAssignment";
    
        private static readonly LocalizableString Title = "Do not do self assignment";
        private static readonly LocalizableString MessageFormat = "The variable '{0}' is assigned to itself";
        private static readonly LocalizableString Description = "A variable assignment to itself is likely an indication of a larger error.";
        private const string Category = "Correctness";
    
        private static DiagnosticDescriptor Rule = new DiagnosticDescriptor(DiagnosticId, Title, MessageFormat, Category, DiagnosticSeverity.Warning, isEnabledByDefault: true, description: Description);
    
        public override ImmutableArray SupportedDiagnostics { get { return ImmutableArray.Create(Rule); } }
    
        public override void Initialize(AnalysisContext context)
        {
            context.RegisterSyntaxNodeAction(AnalyzeNode, SyntaxKind.SimpleAssignmentExpression);
        }
    
        private void AnalyzeNode(SyntaxNodeAnalysisContext context)
        {
            var assignmentExpr = (AssignmentExpressionSyntax)context.Node;
    
            var right = context.SemanticModel.GetSymbolInfo(assignmentExpr.Right);
            var left = context.SemanticModel.GetSymbolInfo(assignmentExpr.Left);
            if (!right.Equals(left))
                return;
    
            var diagnostic = Diagnostic.Create(Rule, assignmentExpr.GetLocation(), assignmentExpr.Left.ToString());
            context.ReportDiagnostic(diagnostic);
    
        }
    }
    

    There may be optimizations you could do that could rule situations out without calling GetSymbolInfo (for example checking the text of the left and the right to see that they match) but I leave that as a exercise for you.

    EDIT:

    The analyzer in action inside Visual Studio 2015:

提交回复
热议问题