在Roslyn中获取完全限定的元数据名称
我需要获取特定符号的完整CLR名称。 这意味着对于generics类型,我需要在类型上附加`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版本上,通过在StringBuilder
上使用Append
而不是Insert
,上面的代码可能会更快,但这是留下进行性能分析的东西。