使用Roslyn查找解决方案所有项目中某方法的全部引用问题
解决SymbolFinder.FindReferencesAsync无法跨项目查找方法引用的问题
我之前也踩过完全一样的坑!当时折腾了好几天,查遍了各种文章和问答,都指向SymbolFinder.FindReferencesAsync,结果它只在方法所在的程序集里找引用,其他引用该项目的项目里的调用完全搜不到,差点怀疑人生。
后来才搞明白问题的核心:你用的ISymbol可能是单个项目编译出来的“局部符号”,而不是整个解决方案级的符号。SymbolFinder.FindReferencesAsync看似接收Solution参数,但如果你的Symbol是从某一个项目的Compilation里拿的,它就只会在那个项目的范围内查找,根本不会遍历整个解决方案的其他项目。
给你几个关键的解决步骤:
确保获取的是解决方案级的ISymbol
别从单个项目的Compilation里获取符号,要通过Workspace的SymbolService来获取,这样拿到的符号是关联整个解决方案的。比如:// 假设你有目标方法所在的Document和光标位置 var symbolService = solution.Workspace.Services.GetService<ISymbolService>(); var targetSymbol = await symbolService.FindSymbolAtPositionAsync( targetDocument, targetPosition, CancellationToken.None );调用FindReferencesAsync时确保遍历整个解决方案
调用方法的时候,除了传入Solution,还要注意如果你的解决方案是大型项目,可能有些项目是延迟加载的,最好先预加载所有项目:// 预加载所有项目(可选,针对大型解决方案) foreach (var project in solution.Projects) { await solution.GetRequiredProjectAsync(project.Id, CancellationToken.None); } // 查找跨项目的所有引用 var allReferences = await SymbolFinder.FindReferencesAsync( targetSymbol, solution, CancellationToken.None );遍历结果时注意处理不同位置的引用
拿到结果后,你可以遍历每个引用的位置,获取对应的文档和代码行:foreach (var reference in allReferences) { foreach (var location in reference.Locations) { var document = solution.GetDocument(location.DocumentId); if (document != null) { var lineSpan = await document.GetLineSpanAsync(location.Location.SourceSpan); Console.WriteLine($"找到引用:{document.FilePath} 第 {lineSpan.StartLinePosition.Line + 1} 行"); } } }
你的推测大概率是对的——问题就出在符号的“作用域”上。局部符号只能在自己的项目里被识别,而解决方案级的符号才能打通跨项目的引用关系。按上面的步骤调整后,应该就能找到所有项目里的方法引用了。
内容的提问来源于stack exchange,提问作者jrandomuser
相关产品推荐
相关产品推荐

