我一直试图在整个解决方案中找到对方法的所有引用。有人会认为SymbolFinder.FindReferencesAsync
将ISymbol作为参数进行搜索,而解决方案对象会这样做,但它不会...
所有文章和SO问题/答案似乎都指出它是解决方案。它适用于查找包含它的程序集内的方法的所有引用,但不适用于引用它的任何项目。我有一个理论认为,这是因为当您创建引用时,方法的符号在引用程序集中是不同的,并且它们希望您获取该符号,然后使用SymbolFinder.FindSourceDeclarationsAsync
将其解析为您正在查找的实际符号对于。
如果是这样的话我真的不知道如何去做?也许以某种方式得到程序集中所有符号的列表,然后对每个人进行FindSource调用并比较它以查看它是否引用了您的MethodSymbol?我当然希望不会!
这是一个简单的例子
public void Find2()
{
string solutionPath = @"C:\Projects\RoslynTestTargetProject\RoslynTestTargetProject.sln";
var msWorkspace = MSBuildWorkspace.Create();
var solution = msWorkspace.OpenSolutionAsync(solutionPath).Result;
var methodProjectComp = solution.Projects.Single(x => x.Name == "RoslynTestTargetProject").GetCompilationAsync().Result;
// I have loaded these all kinds of different ways but it never impacts the end result
var classWithMethodToSearchFor = methodProjectComp.GetTypeByMetadataName("RoslynTestTargetProject.Class1");
var methodToSearchFor = classWithMethodToSearchFor.GetMembers("GetPerson").First() as IMethodSymbol;
var references = SymbolFinder.FindReferencesAsync(methodToSearchFor, solution).Result;
var callers = SymbolFinder.FindCallersAsync(methodToSearchFor, solution).Result;
int c = references.Select(x => x.Locations.Count()).Sum();
}
这是我正在搜索的方法的类和一个对它的引用。
public class Class1
{
public Class1() {}
public Person GetPerson(Guid id) => new Person();
public IEnumerable<Person> GetPeople(IEnumerable<Guid> ids) => ids.Select(x => GetPerson(x));
}
对它的另一个引用只是一个简单的控制台项目,其中包含以下内容:
public static void GetPersonOutsideReference()
{
var c = new Class1();
c.GetPerson(Guid.NewGuid());
}
我希望Find2方法结束时的计数为类中的引用返回2,1,而另一个项目中的引用返回1,但它始终为1.
答案 0 :(得分:0)
我想出了一种方法,这似乎是正确的。我还没有看到解决方案或答案,它为您提供解决方案中的所有参考资料。
首先,您需要在项目中查询方法所属的类型(类)。正如我在我的问题中提到的那样,尽管多个项目可能引用和使用它们相同的类型,但它们对于该类型没有相同的符号。所以你需要做的是通过传递MetadataName来询问每个编译是否具有匹配的类型。
foreach (var project in solution.Projects)
{
var compilation = project.GetCompilationAsync().Result;
// Look for a reference to the Class in the Assembly
var classRef = compilation.GetTypeByMetadataName("RoslynTestTargetProject.Class1");
如果引用不为null,则表示正在程序集中使用该类型。现在,您可以检查您对该编译特定方法的符号引用,如下所示:
//For Methods
var refs = SymbolFinder.FindReferencesAsync(mSymbol, solution).Result;
//For Constructors
var refs = classRef.Constructors.Select(m => SymbolFinder.FindReferencesAsync(m, solution).Result).ToList();