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

时间:2014-11-24 13:23:51

标签: c# roslyn

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

获取完全限定名称的常用选项,即通过ToDisplayString在此处不起作用,因为它不会将MetadataName用于其各个部分。

有没有这样的内置?或者我是否必须将ContainingSymbol s链与.连接在一起? (这个假设是否存在分解?)

编辑:注意到如果某个类型包含在另一个类型中,则需要在{@ 1}}之间使用+,但除此之外,使用.应该有效,我想。

1 个答案:

答案 0 :(得分:11)

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

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,但外部无法访问。

Append上使用Insert代替StringBuilder,上面的代码在最近的.NET版本上可能会更快,但是要留下来进行分析。

相关问题