何时使用 SemanticModel.GetSymbolInfo 以及何时使用 SemanticModel.GetDeclaredSymbol

When to use SemanticModel.GetSymbolInfo and when SemanticModel.GetDeclaredSymbol

在某些情况下,当我尝试获取语法节点的 ISymbol 时,使用 SemanticModel.GetSymbolInfo 时失败(获取空)但使用 SemanticModel.GetDeclaredSymbol 时成功。

我在下面附上了一个例子。

所以我的问题是什么时候使用每种方法来获取语义模型?

public class Class1
{
    public System.String MyString { get; set; }

    public static void Main()
    {
        var str =
            @"
            namespace ClassLibrary31
            {
                public class Class1
                {
                    public System.String MyString { get; set; }
                }
            }";

        var syntaxTree = SyntaxFactory.ParseSyntaxTree(str);

        MetadataReference[] metadataReferenceReferences = new MetadataReference[]
        {
            MetadataReference.CreateFromFile(typeof(object).Assembly.Location),
        };

        var compilation =
            CSharpCompilation
                .Create("TraceFluent",
                    new[] {syntaxTree},
                    options: new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary, warningLevel:1),
                    references: metadataReferenceReferences
                );

        var temp = compilation.Emit("temp");
        var semanticModel = compilation.GetSemanticModel(syntaxTree, true);

        PropertyDeclarationSyntax propertySyntaxNode = 
            syntaxTree.GetRoot()
                .DescendantNodes()
                .OfType<PropertyDeclarationSyntax>()
                .First();

        //var symbolInfo = semanticModel.GetDeclaredSymbol(propertySyntaxNode);
        var symbol = semanticModel.GetDeclaredSymbol(propertySyntaxNode) as IPropertySymbol;
        var typeInfo = semanticModel.GetTypeInfo(propertySyntaxNode).Type;
    }
}

我相信您的意思是获取给定语法节点的符号,而不是获取树的语义模型。

一般来说,当你想获得一个声明的底层符号(class,属性,方法,...),那么你应该使用GetDeclaredSymbol。在内部,GetSymbolInfo 调用 this method. You can see the different cases handled there. Declarations are not handled, so for those you'd need to use GetDeclaredSymbol, whose internals you can find here.