如何确定 FieldDeclarationSyntax 的类型是否是 Roslyn 中的接口?

How to determine if the type of a FieldDeclarationSyntax is an interface in Roslyn?

假设有一个 class 包含接口类型的私有字段。 用Roslyn分析上面的代码,怎么判断FieldDeclarationSyntax后面的类型是不是接口?使用下面的代码检索字段声明的 ISymbol,我找不到像 IsInterface 或类似的任何 属性。

using System.Linq;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;

public class SampleClass
{
    public static void Main()
    {
        var str =
            @"
            namespace Sample
            {
                public interface IBar
                {
                    void Do();
                }

                public class Foo
                {
                    private IBar _bar;
                }
            }";

        var syntaxTree = SyntaxFactory.ParseSyntaxTree(str);

        var compilation = CSharpCompilation.Create("Sample", new[] { syntaxTree });

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

        var classDeclarationSyntax =
        semanticModel.SyntaxTree.GetRoot().DescendantNodes().OfType<ClassDeclarationSyntax>().First();

        var fieldDeclarationSyntax = classDeclarationSyntax.DescendantNodes().OfType<FieldDeclarationSyntax>().First();

        var declaredSymbol = semanticModel.GetDeclaredSymbol(fieldDeclarationSyntax.Declaration.Variables.First());

        // declaredSymbol (ISymbol) contains properties like IsDefinition, IsVirtual etc. but nothing like IsInterface.
    }
}

在 fieldDeclarationSyntax.Declaration.Type 上调用 GetTypeInfo 终于成功了。 完整的工作示例:

using System;
using System.Linq;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;

public class SanpleClass
{
    public static void Main()
    {
        var str =
            @"
            namespace Sample
            {
                public interface IBar
                {
                    void Do();
                }

                public class Foo
                {
                    private IBar _bar;
                }
            }";

        var syntaxTree = SyntaxFactory.ParseSyntaxTree(str);

        var compilation = CSharpCompilation.Create("Sample", new[] { syntaxTree });

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

        var classDeclarationSyntax =
            semanticModel.SyntaxTree.GetRoot().DescendantNodes().OfType<ClassDeclarationSyntax>().First();

        var fieldDeclarationSyntax = classDeclarationSyntax.DescendantNodes().OfType<FieldDeclarationSyntax>().First();

        var typeKind = semanticModel.GetTypeInfo(fieldDeclarationSyntax.Declaration.Type).Type.TypeKind;

        var isInterface = typeKind == TypeKind.Interface;

        Console.WriteLine($"Is Interface: {isInterface}");
    }
}