2014-11-24 6 views
10

Potrzebuję uzyskać pełną nazwę CLR konkretnego symbolu. Oznacza to, że dla typów ogólnych potrzebuję `1, `2 itp. Dołączonych do typów. Teraz, ISymbol ma już właściwość MetadataName, która dokładnie to robi. Ale wyklucza otaczające typy i przestrzenie nazw, podając tylko nazwę symbolu pod ręką.Uzyskaj w pełni kwalifikowaną nazwę metadanych w Roslyn

Zwykła opcja uzyskania w pełni kwalifikowanej nazwy, tj. Poprzez ToDisplayString, nie działa tutaj, ponieważ nie będzie używać MetadataName dla różnych jej części.

Czy jest coś takiego wbudowanego? Czy muszę po prostu połączyć łańcuch s z . pomiędzy? (I to nie wskazuje, gdzie to założenie zepsuje?)

EDIT: Właśnie zauważyłem, że trzeba + w między poszczególnymi nazwami, czy jest to rodzaj zawartych w inny typ, ale oprócz tego, używając . powinny działać, Zgaduję.

+0

Proszę o wsparcie mojej Roslyn Issue na CodePlex dla tej funkcji: https://roslyn.codeplex.com/workitem/297 – JoshVarty

+0

Członek zespołu Roslyn stworzył problem, zobacz https: //github.com/dotnet/roslyn/issues/1891 – bkoelman

Odpowiedz

7

Do teraz, nie mając lepsze rozwiązanie, Używam następujący:

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; 
} 

który wydaje się działać teraz. Roslyn wydaje się mieć wewnętrzne flagi dla SymbolDisplayFormat które umożliwiają tego rodzaju rzeczy (zwłaszcza SymbolDisplayCompilerInternalOptions.UseArityForGenericTypes, ale nie dostępnym na zewnątrz.

Powyższy kod mógłby prawdopodobnie być szybciej na najnowszych wersjach .NET za pomocą Append zamiast Insert na StringBuilder , ale to jest coś do zrobienia dla profilowania.

+1

Wydaje mi się to słuszne. –