23 Stimmen

Holen Sie Typ von 'var' mit Roslyn?

Ich habe eine .cs-Datei namens 'test.cs', die im Wesentlichen so aussieht:

namespace test
{
    public class TestClass
    {
        public void Hello()
        {
            var x = 1;
        }
    }
}

Ich versuche dies mit Roslyn zu analysieren und den Typ von x zu erhalten, der 'int' sein sollte, aber ich kann nur herausfinden, dass es vom Typ 'var' ist, ich scheine nicht den tatsächlichen zugrunde liegenden Typ zu bekommen.

Das ist im Grunde genommen der aktuelle Stand meines Codes

var location = "test.cs";
var sourceTree = CSharpSyntaxTree.ParseFile(location);

var root = (CompilationUnitSyntax)sourceTree.GetRoot();
foreach (var member in root.Members)
{
    //...zu einer Methode gelangen
    var method = (MethodDeclarationSyntax())member;
    foreach (var child in method.Body.ChildNodes())
    {
        if (child is LocalDeclarationStatementSyntax)
        {
            //var x = 1;
            child.Type.RealType()?
        }
    }
}

Wie kann ich den tatsächlichen Typ von child erhalten? Ich habe gelesen, dass ich einen SemanticModel oder eine Solution oder einen Workspace verwenden sollte, aber ich scheine nicht herauszufinden, wie ich meine Testlösung mit Roslyn laden und dann den Typ von 'x' erhalten kann.

Außerdem habe ich bisher keine wirklich gute Roslyn-Dokumentation gefunden, alles scheint auf verschiedene Versionen verteilt zu sein und nichts für Anfänger wie mich. Weiß jemand von einem 'Einstieg in Roslyn' oder einem ähnlichen Schnellstart, den ich lesen könnte?

27voto

andyp Punkte 6109

Um den tatsächlichen Typ für eine mit var deklarierte Variable zu erhalten, rufen Sie GetSymbolInfo() auf dem SemanticModel auf. Sie können eine vorhandene Lösung mit MSBuildWorkspace öffnen, dann deren Projekte und Dokumente auflisten. Verwenden Sie ein Dokument, um dessen SyntaxRoot und SemanticModel zu erhalten, suchen Sie dann nach VariableDeclarations und erhalten Sie die Symbole für den Typ einer deklarierten Variablen wie folgt:

var workspace = MSBuildWorkspace.Create();
var solution = workspace.OpenSolutionAsync("c:\\path\\to\\solution.sln").Result;

foreach (var document in solution.Projects.SelectMany(project => project.Documents))
{
    var rootNode = document.GetSyntaxRootAsync().Result;
    var semanticModel = document.GetSemanticModelAsync().Result;

    var variableDeclarations = rootNode
            .DescendantNodes()
            .OfType();
    foreach (var variableDeclaration in variableDeclarations)
    {
        var symbolInfo = semanticModel.GetSymbolInfo(variableDeclaration.Declaration.Type);
        var typeSymbol = symbolInfo.Symbol; // das Typsymbol für die Variable..
    }
}

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X