我需要获取特定符号的完整CLR名称。这意味着对于泛型类型,我需要附加到类型的`1
,`2
等。现在,ISymbol
已经有一个属性MetadataName
,它就是这样做的。但它排除了周围的类型和命名空间,只给出了手头符号的名称。
获取完全限定名称的常用选项,即通过ToDisplayString
在此处不起作用,因为它不会将MetadataName
用于其各个部分。
有没有这样的内置?或者我是否必须将ContainingSymbol
s链与.
连接在一起? (这个假设是否存在分解?)
编辑:注意到如果某个类型包含在另一个类型中,则需要在{@ 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版本上可能会更快,但是要留下来进行分析。