2015-10-29 181 views
2

我們可以從Microsoft.CodeAnalysis.CSharp.Syntax.TypeSyntax獲取System.Type或實質上完全限定的類型名稱嗎?問題是,TypeSyntax返回類型的名稱,因爲它是用可能不是完全合格的類名稱的代碼編寫的,我們無法從中找到類型。我們可以從Microsoft.CodeAnalysis.CSharp.Syntax.TypeSyntax獲取System.Type嗎?

+1

請注意,您無法輕鬆獲取System.Type,但可以獲取Microsoft.CodeAnalysis.ITypeSymbol。喬希的回答已經給出了一個很好的解釋。請注意,在大多數情況下,System.Type實際上並不是您想要的,因爲這意味着您的流程中會以不需要的方式加載類型。 –

回答

5

要獲得一段語法的全限定名稱,您需要使用SemanticModel來獲得對其符號的訪問權限。我已經在我的博客上撰寫了語義模型指南:Learn Roslyn Now: Introduction to the Semantic Model

根據您的previous question,我假設您正在查看字段。

var tree = CSharpSyntaxTree.ParseText(@" 
class MyClass 
{ 
    int firstVariable, secondVariable; 
    string thirdVariable; 
}"); 

var mscorlib = MetadataReference.CreateFromFile(typeof(object).Assembly.Location); 
var compilation = CSharpCompilation.Create("MyCompilation", 
    syntaxTrees: new[] { tree }, references: new[] { mscorlib }); 

//Get the semantic model 
//You can also get it from Documents 
var model = compilation.GetSemanticModel(tree); 

var fields = tree.GetRoot().DescendantNodes().OfType<FieldDeclarationSyntax>(); 
var declarations = fields.Select(n => n.Declaration.Type); 
foreach (var type in declarations) 
{ 
    var typeSymbol = model.GetSymbolInfo(type).Symbol as INamedTypeSymbol; 
    var fullName = typeSymbol.ToString(); 
    //Some types like int are special: 
    var specialType = typeSymbol.SpecialType; 
} 

您還可以得到符號的聲明本身(而不是用於對聲明的類型)通過:

var declaredVariables = fields.SelectMany(n => n.Declaration.Variables); 
foreach (var variable in declaredVariables) 
{ 
    var symbol = model.GetDeclaredSymbol(variable); 
    var symbolFullName = symbol.ToString(); 
} 

最後一點:這些符號調用.ToString()給你他們的完全合格名稱,但不包括其完全限定的元數據名稱。 (嵌套類在之前,其類名和泛型處理方式不同)。

+1

爲了獲取元數據名稱,我有一個方法[在這裏](http://stackoverflow.com/a/27106959/73070),據我所知,仍然沒有公開訪問的方法在Roslyn中獲取。 – Joey

+0

我經常在我自己的代碼中使用它:) – JoshVarty

相關問題