Skip to main content
edited tags
Link
TylerH
  • 21.3k
  • 84
  • 84
  • 121
edited tags
Link
NPras
  • 4.2k
  • 1
  • 20
  • 33
Source Link
Jim W
  • 483
  • 5
  • 9

Roslyn's AllInterfaces returns nothing for List<> and Dictionary<>

In a source generator, I'd like to determine if a member is IEnumerable or IDictionary. In the sample below, the array member returns IEnumerable, etc. from AllInterfaces, but I get zero interfaces for List<> or Dictionary<>.

    using Microsoft.CodeAnalysis;
    using Microsoft.CodeAnalysis.CSharp;
    using Microsoft.CodeAnalysis.CSharp.Syntax;

    var sourceCode = @"
                        public class ArrayOptions
                        {
                            public class ArrayItem
                            {
                                public string ProfileName { get; set; } = """";
                            }

                            public List<ArrayItem> ProfilesList { get; set; } = new List<ArrayItem>();
                            public Dictionary<string, ArrayItem> ProfilesDictionary { get; set; } = new Dictionary<string,ArrayItem>();

                            public ArrayItem[] ProfilesArray { get; set; } = Array<ArrayItem>.Empty;
                        }
                    }
                ";

    var syntaxTree = CSharpSyntaxTree.ParseText(sourceCode);

    var compilation = CSharpCompilation.Create("RoslynSample")
        .AddReferences(
            MetadataReference.CreateFromFile(typeof(object).Assembly.Location),
            MetadataReference.CreateFromFile(typeof(Enumerable).Assembly.Location))
        .AddSyntaxTrees(syntaxTree);

    var semanticModel = compilation.GetSemanticModel(syntaxTree);

    var classDeclaration = syntaxTree.GetRoot()
        .DescendantNodes()
        .OfType<ClassDeclarationSyntax>()
        .First(c => c.Identifier.Text == "ArrayOptions");

    var classSymbol = semanticModel.GetDeclaredSymbol(classDeclaration) as INamedTypeSymbol;

    var properties = classSymbol!.GetMembers().OfType<IPropertySymbol>();

    foreach (var property in properties)
    {
        Console.WriteLine($"Property: {property.Name}, Type: {property.Type}");

        // only array has any interfaces not IList or List??
        var allInterfaces = property.Type.AllInterfaces;

        foreach (var interfaceSymbol in allInterfaces)
        {
            Console.WriteLine($"  Interface: {interfaceSymbol.ToDisplayString()}");
        }
    }