如何用Roslyn中的var替换字符串变量?

对于本地声明,例如:string a = string.Empty;

如何编写诊断程序将其更改为:var a = string.Empty;

我已经整理了一个带诊断的代码修复程序。 这是有趣的部分:

从ISyntaxNodeAnalyzer实现AnalyzeNode

 public void AnalyzeNode(SyntaxNode node, SemanticModel semanticModel, Action public void AnalyzeNode(SyntaxNode node, SemanticModel semanticModel, Action 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> GetFixesAsync(Document document, TextSpan span, IEnumerable 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().First(); return new[] { CodeAction.Create("Use var", c => ChangeDeclarationToVar(document, declaration, c)) }; } private async Task 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关键字告诉编译器执行类型推断,并且只使用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 

编译器无法从中推断出类型。

您需要使用:

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

或者你可以这样做:

 string a;