簡體   English   中英

編譯時檢測意外地將C#屬性分配給自身

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

Visual Studio C#編譯器警告無意中將變量分配給自身 ,但此警告不適用於C#屬性,僅適用於變量。 其他問題所述

但是,如果我為自己分配一個屬性,我真的會喜歡類似的東西,可以在編譯時警告我。

我目前正在使用Visual Studio 2013,但如果解決方案至少在Visual Studio 2015中有效,我也沒關系。此外,我不使用像ReSharper或CodeRush這樣的第三方商業插件,所以我更傾向於不使用的解決方案涉及購買東西,但我願意接受建議。

你知道我怎么能做到這一點?

背景:

我非常習慣使用只讀公共“檢查”屬性構建接收器依賴注入模式來存儲接收到的依賴項。

例如,假設一個依賴於ILogger實現的類Foo logger實例在構造函數中提供給類,構造函數檢查空值並將依賴項存儲在名為Logger的實例屬性中:

public class Foo
{
    public ILogger Logger { get; private set; }

    public Foo(ILogger logger)
    {
        if(logger == null) throw new ArgumentNullException("logger");
        this.Logger = logger;
    }
}

但是,我經常輸入錯誤,將屬性分配給自己而不是傳遞給構造函數的參數。

public class Foo
{
    public ILogger Logger { get; private set; }

    public Foo(ILogger logger)
    {
        if(logger == null) throw new ArgumentNullException("logger");
        this.Logger = Logger; // <-- This is wrong. Property assigned to itself.
    }
}

當然,我總是在測試和調試時最終發現這些錯誤,但它已經困擾了我幾次,我不想再浪費時間在這樣一個愚蠢的錯誤中。

有什么建議么?

這是VS2015實時代碼分析器的完美情況。 您可以編寫一個基本分析器,檢查屬性是否已分配給自身並創建錯誤。

這是一個非常好的教程,我很久以前就幫助你開始編寫一個,它們並不是很難做到:“ C#和Visual Basic - 使用Roslyn為你的API編寫一個實時代碼分析器

更新:我有一些空閑時間,所以我寫了一個分析器,它做到了。

[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);

    }
}

您可以進行優化,可以在不調用GetSymbolInfo情況下排除情況(例如檢查左側和右側的文本以查看它們是否匹配)但我將其作為練習留給您。

編輯:

Visual Studio 2015中的分析器:

分析器在行動

更改鍵入參數的方式,以便更少發生錯誤。

參數優先:

   public Foo(ILogger logger)
   { 
   }

下一步分配: 復制/粘貼參數兩次

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

最后,糾正拼錯屬性:

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM