在 Roslyn 中获取完全限定的元数据名称

本文关键字:元数据 Roslyn 获取 | 更新日期: 2023-09-27 18:31:54

我需要获取特定符号的完整CLR名称。这意味着对于泛型类型,我需要将`1`2等附加到类型中。现在,ISymbol已经有一个属性MetadataName可以做到这一点。但它排除了周围的类型和命名空间,只给出了手头符号的名称。

获取完全限定名称的常用选项,即通过 ToDisplayString 在这里不太有效,因为它不会将MetadataName用于其各个部分。

有没有内置这样的东西?还是我必须将ContainingSymbol链与中间的.连接起来?(这个假设有没有被打破的地方?

编辑:刚刚注意到,如果它是另一种类型中包含的类型,则需要在单个名称之间+,但除此之外,我想使用.应该有效。

在 Roslyn 中获取完全限定的元数据名称

目前,没有更好的解决方案,我正在使用以下内容:

public static string GetFullMetadataName(this ISymbol s) 
{
    if (s == null || IsRootNamespace(s))
    {
        return string.Empty;
    }
    var sb = new StringBuilder(s.MetadataName);
    var last = s;
    s = s.ContainingSymbol;
    while (!IsRootNamespace(s))
    {
        if (s is ITypeSymbol && last is ITypeSymbol)
        {
            sb.Insert(0, '+');
        }
        else
        {
            sb.Insert(0, '.');
        }
        sb.Insert(0, s.OriginalDefinition.ToDisplayString(SymbolDisplayFormat.MinimallyQualifiedFormat));
        //sb.Insert(0, s.MetadataName);
        s = s.ContainingSymbol;
    }
    return sb.ToString();
}
private static bool IsRootNamespace(ISymbol symbol) 
{
    INamespaceSymbol s = null;
    return ((s = symbol as INamespaceSymbol) != null) && s.IsGlobalNamespace;
}

这似乎暂时有效。Roslyn似乎有内部标志,用于支持这种事情的SymbolDisplayFormat(最着名的是SymbolDisplayCompilerInternalOptions.UseArityForGenericTypes,但外部无法访问。

上面的代码在最近的 .NET 版本上可能会更快,方法是使用 Append 而不是StringBuilder上的Insert,但这需要留给分析。