2014-11-24 83 views
10

我需要獲取特定符號的完整CLR名稱。這意味着對於泛型類型,我需要將`1,`2等附加到類型上。現在,ISymbol已經有一個屬性MetadataName這完全是。但它排除了周圍的類型和名稱空間,只給出了手頭符號的名稱。在Roslyn中獲取完全限定的元數據名稱

通常用於獲取完全限定名稱的選項,即通過ToDisplayString在此不太適用,因爲它不會在其各個部分使用MetadataName

有沒有像這樣的內置?或者,我必須將ContainingSymbol s與.之間的鏈連接起來? (以及是否有指向哪裏這個假設打破了?)

編輯:只注意到你需要在個別名之間的+,如果是包含在其他類型的類型,但除此之外,使用.應該工作,我猜。

+0

請在CodePlex上支持此功能的Roslyn問題:https://roslyn.codeplex.com/workitem/297 – JoshVarty 2014-11-25 05:13:44

+0

Roslyn團隊成員爲此創建了一個問題,請參見https: //github.com/dotnet/roslyn/issues/1891 – bkoelman 2015-04-09 19:16:10

回答

7

現在,有沒有更好的解決辦法,我使用了以下內容:

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

這似乎是現在的工作。羅斯林似乎有內部標記爲SymbolDisplayFormat,使之類的事情(最值得注意的是SymbolDisplayCompilerInternalOptions.UseArityForGenericTypes,但外界無法訪問。

上面的代碼可能會是最近的.NET版本快通過在StringBuilder使用Append代替Insert ,但這是需要分析的東西

+1

這對我來說似乎是對的。 – 2014-11-24 14:24:11

相關問題