在解决方案中使用 Roslyn 检索所有类型 [英] Retrieve all Types with Roslyn within a solution

查看:41
本文介绍了在解决方案中使用 Roslyn 检索所有类型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有谁知道如何在解决方案中检索所有可用类型(语义)?创建多个项目的编译很容易.

Does anyone know how to retrieve all available types (the semantic) within a solution? The creation of the compilation out of several projects is easy.

MSBuildWorkspace workspace = MSBuildWorkspace.Create();
var solution = await workspace.OpenSolutionAsync(solutionPath, cancellationToken);
var compilations = await Task.WhenAll(solution.Projects.Select(x => x.GetCompilationAsync(cancellationToken)));

仅仅迭代所有 ClassDeclarations 对我来说是不够的,因为我想要所有类型以及它们之间的连接.

Just iterating over all ClassDeclarations is not enough for me because I want all types and the connection between them.

foreach (var tree in compilation.SyntaxTrees)
{
    var source = tree.GetRoot(cancellationToken).DescendantNodes();
    var classDeclarations = source.OfType<ClassDeclarationSyntax>();
}

推荐答案

对于给定的编译,您可以通过遍历所有 GetTypeMembers() 通过 Compilation.GlobalNamespace 访问所有可用类型code> 和 GetNamespaceMembers() 递归.这不是为您提供解决方案中的所有类型,而是从当前编译(项目)通过其所有引用提供的所有类型.

For a given compilation you can reach all available types through Compilation.GlobalNamespace by iterating over all GetTypeMembers() and GetNamespaceMembers() recursively. This is not giving you all the types in the solution, but all types that are available from the current compilation (project) through all its references.

为了不重新发明轮子,它是:

In order not to reinvent the wheel, it is:

IEnumerable<INamedTypeSymbol> GetAllTypes(Compilation compilation) =>
    GetAllTypes(compilation.GlobalNamespace);

IEnumerable<INamedTypeSymbol> GetAllTypes(INamespaceSymbol @namespace)
{
    foreach (var type in @namespace.GetTypeMembers())
        foreach (var nestedType in GetNestedTypes(type))
            yield return nestedType;

    foreach (var nestedNamespace in @namespace.GetNamespaceMembers())
        foreach (var type in GetAllTypes(nestedNamespace))
            yield return type;
}

IEnumerable<INamedTypeSymbol> GetNestedTypes(INamedTypeSymbol type)
{
    yield return type;
    foreach (var nestedType in type.GetTypeMembers()
        .SelectMany(nestedType => GetNestedTypes(nestedType)))
        yield return nestedType;
}

这篇关于在解决方案中使用 Roslyn 检索所有类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆