使用 Roslyn 获取 class 定义的通用 属性 类型的名称

Getting the name of a type of generic property of class definition using Roslyn

我有一个 class 定义如下:

class Derived
{
    public int t { get; set; }
    public List<Child> Childs { get; set; }
}

我想为 class 的每个 属性 获取 System.Type。这是我目前拥有的:

var properties = node.DescendantNodes().OfType<PropertyDeclarationSyntax>();

var symbolDisplayFormat = new SymbolDisplayFormat(
    typeQualificationStyle: SymbolDisplayTypeQualificationStyle.NameAndContainingTypesAndNamespaces
);

foreach (var property in properties) 
{
    var typeSymbol = context.SemanticModel.GetSymbolInfo(property.Type).Symbol as INamedTypeSymbol;
    string name = typeSymbol.ToDisplayString(symbolDisplayFormat);
}

其中节点是 ClassDeclarationSyntax

此代码适用于 属性 t;返回 属性 类型的名称 System.Int32。但是,对于 属性 Childs(它是一个带有通用参数的类型),我得到一个 null typeSymbol,这不是这个 属性 的 System.Type 那是预期的。

如何使用 Roslyn 从 class 定义中获取泛型类型 属性 的类型?

您应该使用 SemanticModel.GetTypeInfo 而不是 SemanticModel.GetSymbolInfo 从节点检索相应的 ITypeSymbol

...
foreach (var property in properties) 
{
    var info = context.SemanticModel.GetTypeInfo(property);
    var typeSymbol = info.Type ?? info.ConvertedType; 
    ...
}

如果你想要泛型的(第一个)参数类型,你可以使用:

TypeSyntax type = (property.Type as GenericNameSyntax).TypeArgumentList.Arguments[0];

我设法通过以下方式获取通用类型信息:

if (type is INamedTypeSymbol nType) //type is ITypeSymbol
{
    bool isGeneric = nType.IsGenericType;
    int typeArgumentsCount = nType.TypeArguments.Count();
    ...
}