簡體   English   中英

如何用Roslyn中的var替換字符串變量?

[英]How do I replace a string variable with a var in Roslyn?

對於本地聲明,例如:string a = string.Empty;

如何編寫診斷程序以將其更改為:var a = string.Empty;

你不能。 var關鍵字告訴編譯器執行類型推斷,並且只使用var a; 編譯器沒有足夠的信息來推斷類型。

但是,您可以執行以下任何操作

var a = new String();
var b = String.Empty;
var c = "";

但這似乎比它的價值更多的努力。

編輯更新的請求:為什么要修改要使用var聲明的所有代碼? 無論如何,它編譯為相同的IL(簡單的例子):

// var a = String.Empty;
IL_0000:  ldsfld     string [mscorlib]System.String::Empty
IL_0005:  pop
// string b = String.Empty;
IL_0006:  ldsfld     string [mscorlib]System.String::Empty
IL_000b:  pop

我已經整理了一個帶診斷的代碼修復程序。 這是有趣的部分:

從ISyntaxNodeAnalyzer實現AnalyzeNode

public void AnalyzeNode(SyntaxNode node, SemanticModel semanticModel, Action<Diagnostic> public void AnalyzeNode(SyntaxNode node, SemanticModel semanticModel, Action<Diagnostic> addDiagnostic, CancellationToken cancellationToken)
    {
        var localDeclaration = (LocalDeclarationStatementSyntax)node;
        if (localDeclaration.Declaration.Type.IsVar) return;
        var variable = localDeclaration.Declaration.Variables.First();
        var initialiser = variable.Initializer;
        if (initialiser == null) return;
        var variableTypeName = localDeclaration.Declaration.Type;
        var variableType = semanticModel.GetTypeInfo(variableTypeName).ConvertedType;
        var initialiserInfo = semanticModel.GetTypeInfo(variable.Initializer.Value);
        var typeOfRightHandSideOfDeclaration = initialiserInfo.Type;
        if (Equals(variableType, typeOfRightHandSideOfDeclaration))
        {
            addDiagnostic(Diagnostic.Create(Rule, node.GetLocation(), localDeclaration.Declaration.Variables.First().Identifier.Value));
        }
    }

這主要是查看聲明兩側的類型,如果它們相同(並且RHS不是var),則添加診斷。

這是代碼修復的代碼:

public async Task<IEnumerable<CodeAction>> GetFixesAsync(Document document, TextSpan span, IEnumerable<Diagnostic> diagnostics, CancellationToken cancellationToken)
    {
        var root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false);
        var diagnosticSpan = diagnostics.First().Location.SourceSpan;
        var declaration = root.FindToken(diagnosticSpan.Start).Parent.AncestorsAndSelf().OfType<LocalDeclarationStatementSyntax>().First();
        return new[] { CodeAction.Create("Use var", c => ChangeDeclarationToVar(document, declaration, c)) };
    }

private async Task<Document> ChangeDeclarationToVar(Document document, LocalDeclarationStatementSyntax localDeclaration, CancellationToken cancellationToken)
    {
        var root = await document.GetSyntaxRootAsync(cancellationToken);
        var variableTypeName = localDeclaration.Declaration.Type;
        var varTypeName = SyntaxFactory.IdentifierName("var").WithAdditionalAnnotations(Formatter.Annotation);
        var newDeclaration = localDeclaration.ReplaceNode(variableTypeName, varTypeName);            
        var newRoot = root.ReplaceNode(localDeclaration, newDeclaration);
        return document.WithSyntaxRoot(newRoot);
    }

這一點很簡單,只需從Syntax工廠獲取var並將其切換出來。 請注意,var在SyntaxFactory中沒有自己的靜態方法,因此它是按名稱引用的。

編譯器無法從中推斷出類型。

你需要使用:

var a = ""; // compiler can see that is type `string`:

或者你可以這樣做:

string a;

暫無
暫無

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

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