Как определить, является ли тип FieldDeclarationSyntax интерфейсом в Roslyn? - PullRequest
3 голосов
/ 11 марта 2019

Допустим, есть класс, который содержит приватное поле типа интерфейса. При анализе кода выше с 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.
    }
}

1 Ответ

2 голосов
/ 11 марта 2019

Вызов GetTypeInfo для fieldDeclarationSyntax.Declaration.Type наконец-то добился цели. Полный рабочий пример:

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}");
    }
}
...