在 Roslyn 中获取完全限定的元数据名称
本文关键字:元数据 Roslyn 获取 | 更新日期: 2023-09-27 18:31:54
我需要获取特定符号的完整CLR名称。这意味着对于泛型类型,我需要将`1
、`2
等附加到类型中。现在,ISymbol
已经有一个属性MetadataName
可以做到这一点。但它排除了周围的类型和命名空间,只给出了手头符号的名称。
获取完全限定名称的常用选项,即通过 ToDisplayString
在这里不太有效,因为它不会将MetadataName
用于其各个部分。
有没有内置这样的东西?还是我必须将ContainingSymbol
链与中间的.
连接起来?(这个假设有没有被打破的地方?
编辑:刚刚注意到,如果它是另一种类型中包含的类型,则需要在单个名称之间+
,但除此之外,我想使用.
应该有效。
目前,没有更好的解决方案,我正在使用以下内容:
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
,但这需要留给分析。