如何在自定义Visual Studio CodeLens扩展中获取方法反射级信息
在Visual Studio 2022 CodeLens扩展中获取方法的完整反射信息
核心思路
要获取方法的所属类、可见性、类实现的接口等信息,不能用常规反射(依赖已编译程序集,而CodeLens运行时代码可能未编译),必须借助Roslyn语义分析API——它能直接从编辑器源代码中提取编译级别的符号信息,完全满足需求。
具体实现步骤
在CanCreateDataPointAsync方法中按以下流程获取信息:
获取Workspace与目标文档
通过descriptorContext.ServiceProvider获取Visual Studio的Workspace服务,再用descriptor.DocumentId定位当前代码文档。获取语义模型与方法符号
从文档中提取SemanticModel,再通过descriptor.Span定位到对应的方法符号(IMethodSymbol),这是获取所有类型信息的核心入口。提取目标信息
从IMethodSymbol及其包含类型(INamedTypeSymbol)中直接读取可见性、所属类、实现的接口等信息。
代码示例
修改你的CanCreateDataPointAsync方法如下:
public async Task<bool> CanCreateDataPointAsync(CodeLensDescriptor descriptor, CodeLensDescriptorContext descriptorContext, CancellationToken token) { if (descriptor.Kind != CodeElementKinds.Method) return false; // 获取Workspace服务 var workspace = descriptorContext.ServiceProvider.GetService<VisualStudioWorkspace>(); if (workspace == null) return false; // 获取当前文档与语义模型 var document = workspace.GetDocument(descriptor.DocumentId); if (document == null) return false; var semanticModel = await document.GetSemanticModelAsync(token); if (semanticModel == null) return false; // 定位到方法符号 var methodSymbol = semanticModel.GetEnclosingSymbol(descriptor.Span.Start, token) as IMethodSymbol; if (methodSymbol == null) return false; // 提取所需信息 // 方法可见性(Public/Private/Protected等) var methodAccessibility = methodSymbol.DeclaredAccessibility; // 所属类的名称与完整限定名 var containingType = methodSymbol.ContainingType; var className = containingType.Name; var fullClassName = containingType.ToDisplayString(); // 类实现的所有接口 var implementedInterfaces = containingType.AllInterfaces; foreach (var iface in implementedInterfaces) { var interfaceName = iface.Name; // 按需处理接口信息 } // 后续业务逻辑... return true; }
关键说明
- Roslyn vs 反射:Roslyn直接分析源代码,无需依赖编译后的程序集,适配CodeLens实时运行的场景;
- 符号信息完整性:
IMethodSymbol和INamedTypeSymbol包含了反射能获取的所有信息(修饰符、泛型参数、继承链、属性等); - 异步规范:所有涉及文档和语义模型的操作都传入
token,避免阻塞UI线程,符合VS扩展的性能要求。
内容的提问来源于stack exchange,提问作者MaverichG
相关产品推荐
相关产品推荐

