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