【问题标题】:Get fully-qualified metadata name in Roslyn在 Roslyn 中获取完全限定的元数据名称
【发布时间】:2014-11-24 13:23:51
【问题描述】:

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

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

有这样的内置功能吗?还是我必须将ContainingSymbols 链与. 连接起来? (这个假设是否存在失效点?)

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

【问题讨论】:

标签: c# roslyn


【解决方案1】:

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

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

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

【讨论】:

    猜你喜欢
    • 2018-02-03
    • 1970-01-01
    • 2015-02-23
    • 2016-09-30
    • 2017-06-20
    • 1970-01-01
    • 1970-01-01
    • 2018-08-11
    • 1970-01-01
    相关资源
    最近更新 更多