C# Roslyn 编译器 - 如何从 IdentifierNameSyntax 获取类型的命名空间?

标签 c# roslyn roslyn-code-analysis

假设我在代码中有一个调用,SomeClass.SomeStaticMethod<T>() ,这是一个 InvocationExpressionSyntax。

我将通用类型 T 的名称作为字符串(来自 IdentifierNameSyntax)。我试图获得 T 的符号,但我没有成功。

如何获取类型T的命名空间信息?

更新:@SJP 的回答是正确的。我想为那些想从 IdentifierNameSyntax 获取命名空间信息的人解释我的错误,其中包含类的标识符(类名):

我最初的目标是在 SomeClass.SomeMethod<T>() 中找到调用格式化并获取类型T的命名空间信息。

var namedTypeSymbol = context.Symbol as INamedTypeSymbol;
var reference = nameTypeSymbol.DeclaringSyntaxReferences.First();
var classSyntaxTree = reference.SyntaxTree;

var semanticModel = context.Compilation.GetSemanticModel(classSyntaxTree);
var genericNameSyntax = (GenericNameSyntax)((MemberAccessExpressionSyntax)node.Expression).Name;
var identifierNameSyntax = genericNameSyntax.TypeArgumentList.Arguments.First();
var typeInfo = semanticModel.GetTypeInfo(identifierNameSyntax);
var nameSpace = ((INamedTypeSymbol)typeInfo.Type).ContainingNamespace;
var nameSpaceName = nameSpace.ToString();

这是我的错误:

我试图获得像 <module_name>.<namespace_part_1>.<namespace_part_2> 这样的完整命名空间但是当我做的时候 namedTypeSymbol.ContainingNamespace.Name , 我只有 <namespace_part_2> .几个小时后,我发现获取完整的命名空间是像 namedTypeSymbol.ContainingNamespace.ToString() 这样完成的。 .

有时候最好的办法就是出去呼吸新鲜空气:)

最佳答案

您将需要语义模型来完成您的任务。假设您需要 SomeClass 的命名空间,那么您可以通过访问表达式的名称字段,从 MemberAccessExpressionSyntax 的命名空间中获取类型和名称,如下所示:

var semanticModel = await document.GetSemanticModelAsync()
var name = (GenericNameSyntax)((MemberAccessExpressionSyntax)node.Expression).Name;
var typeInfo = semanticModel.GetTypeInfo(name.TypeArgumentList.Arguments.First());
var nameSpace = ((INamedTypeSymbol)typeInfo.Type).ContainingNamespace;
var nameSpaceName = nameSpace.Name;

对于以下示例程序,这将导致变量 nameSpaceName 为“System”或“ConsoleApp1”(取决于调用),而所有其他信息都可以通过变量 nameSpace 访问。

namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            Program.DoStuff<string>();
            Program.DoStuff<Program>();
        }

        static void DoStuff<T>()
        {

        }
    }
}

关于C# Roslyn 编译器 - 如何从 IdentifierNameSyntax 获取类型的命名空间?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45613611/

相关文章:

c# - Roslyn:从代码分析器访问部分类的 XAML

c# - 如何更改 EnvDTE.Document 的文本?

c# - 如何使用 Roslyn 查找调用方法的参数是变量(通过 "var/string")还是内联字符串

c# - 录制一段固定时间的喊话

c# - asp.net 5/vnext 磁盘上没有 dll 的代码契约(Contract)

c# - 如何在Asp.net core中将数据从AuthorizationHandler传递到Controller

C# 仪器

compiler-errors - 在 VS 2017 中编译 MVC 项目时拒绝访问 roslyn 文件夹

c# - 如何查找字符串是否包含任何特殊字符?

c# - Paypal payKey 将我带到错误的付款