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

前端 未结 2 1971
不思量自难忘°
不思量自难忘° 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:33

    Change the way you type the parameters, so the error happens less often.

    Parameter first:

       public Foo(ILogger logger)
       { 
       }
    

    Assignment next: copy/paste the parameter twice

       public Foo(ILogger logger)
       { 
           // this.{paste} = {paste};
           this.logger = logger;
       } 
    

    Lastly, correct the misspelt property:

       public Foo(ILogger logger)
       { 
           this.Logger = logger;
       } 
    
    0 讨论(0)
  • 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<DiagnosticDescriptor> 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:

    0 讨论(0)
提交回复
热议问题