Ответ 1
Теперь, не имея лучшего решения, я использую следующее:
public static string GetFullMetadataName(this INamespaceOrTypeSymbol symbol)
{
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
вместо Insert
на StringBuilder
, но что-то, что нужно оставить для профилирования.