我们应该如何向现有变量添加实例化?

时间:2014-04-23 16:24:36

标签: c# roslyn

我编写了一个能够正确检测未实例化集合的Analyzer。现在我正在编写适当的CodeFixProvider,它将提供实例化它的选项。

当我执行我的代码并查看提供的修补程序时,它只会删除标识符并仅保留类型。我的方法在哪里出错了?

enter image description here

public async Task<IEnumerable<CodeAction>> GetFixesAsync(Document document, TextSpan span, IEnumerable<Diagnostic> diagnostics, CancellationToken cancellationToken)
{
    var root = await document.GetSyntaxRootAsync(cancellationToken);
    var token = root.FindToken(span.Start);
    document.TryGetSemanticModel(out var semanticModel);
    var statement = token.Parent.Parent as VariableDeclarationSyntax;

    // Construct variable declaration
    var declarator = new SeparatedSyntaxList<VariableDeclaratorSyntax>();
    var identifier = statement.Variables[0].Identifier;
    var newType = semanticModel.GetTypeInfo(statement.Type).Type;
    var newObject = SyntaxFactory.ObjectCreationExpression(type: SyntaxFactory.ParseTypeName(newType.Name));
    var equalsClause = SyntaxFactory.EqualsValueClause(newObject);
    declarator.Add(SyntaxFactory.VariableDeclarator(identifier, null, equalsClause));

    var newStatement = SyntaxFactory.VariableDeclaration(statement.Type, declarator);
    var newRoot = root.ReplaceNode(statement, newStatement);

    return new[]
    {
        CodeAction.Create("Instantiate collection variable", document.WithSyntaxRoot(newRoot))
    };
}

1 个答案:

答案 0 :(得分:2)

你必须记住,Roslyn中的所有类型都是不可变的。这意味着,即使像Add()这样的操作实际上并未修改他们所要求的对象,也会返回修改后的对象。

这意味着在Add()之后,您必须使用返回的值,而不是原始对象。

如果您将代码修改为以下代码,它将起作用:

declarator = declarator.Add(SyntaxFactory.VariableDeclarator(identifier, null, equalsClause));