当我右键单击一个符号并运行 Find Usages ReSharper 命令时,ReSharper 似乎经常将大部分时间花在搜索 resx 文件上。在进度对话框可见的大部分时间里,该对话框中显示的文件名是解决方案中的各种 .resx 文件。
ReSharper 实际上是在搜索 .resx 文件吗?为什么要这样做,为什么要花这么长时间?我可以改变这种行为吗?
设置:ReSharper 8.2.0.2160 C# 版。 Visual Studio 2013 高级版。
我试过的:
最佳答案
这一切的答案都归功于 ReSharper 的底层架构。在处理文件时,ReSharper 会构建一个抽象的语法树,树中的每个节点可以有一个或多个对语义模型中的元素的引用。换句话说,Foo
在表达式 new Foo(42)
中将引用描述名为 Foo
的类的语义元素。 .每个文件都有很多引用,因为元素(变量、参数、方法、属性、CSS 类、HTML 颜色、文件系统路径等)的任何使用都有一个或多个对该元素声明的引用。
这些引用资料非常强大。它们通过简单地导航到引用的目标来启用 Ctrl+单击导航。它们可以通过显示在代码中当前位置满足引用的候选目标来提供代码完成。
当然,它们还通过查找针对特定元素的所有引用来支持 Find Usages。但这需要向后工作,从目标到引用。蛮力方法需要检查每个文件中每个引用的目标,试图找到目标。这显然无法扩展,而且数据集太大而无法缓存。
为了让 Find Usages 在合理的时间范围内运行,ReSharper 还维护了所有文件中使用的所有单词的单词索引(这也有助于正常的“转到”导航)。当您对符号调用 Find Usages(例如问题截图中的 EnterDate
)时,ReSharper 使用单词索引来缩小它需要搜索的文件的范围 - 它会查找 EnterDate
,并且仅使用包含该词的文件。一旦它有一个减少的文件子集要搜索,它就需要找到任何以原始元素为目标的引用。为此,它遍历子集中每个文件的语法树。检查每个节点的引用是否与我们正在寻找的符号名称匹配,例如EnterDate
.如果匹配,则解析引用,并检查目标是否匹配相同的元素 - EnterDate
类(class)、属性(property)或任何实际情况。如果它确实指向预期目标,则将其添加到用法集合中,并显示给用户。
(事情比这稍微复杂一点,因为一个引用可能有多个名称,例如,如果您尝试在 [Pure]
上查找用法,ReSharper 需要查找 Pure
或 PureAttribute
的任何用法。幸运的是,这些替代方法名称也存储在单词索引中,用于帮助减少要搜索的文件。检查引用时,所有替代名称都被检查)
因此,如果您有一个包含文本 EnterDate
的 .resx 文件,将搜索对 EnterDate
的引用您正在寻找的元素 - ReSharper 将遍历 .resx 文件的语法树,并检查每个引用以查看它是否匹配 EnterDate
.
我们检查所有文件,即使对用户来说很明显目标元素不可能在该文件中使用,因为我们允许跨语言引用。也就是说,VB 文件可以引用 C# 元素,HTML 文件可以引用 CSS 元素,XAML 文件可以引用 C# 方法元素,等等。所以没有对“合理”使用进行过滤。例如,如果 EnterDate
是一个类,您作为用户可以知道它不太可能在 .resx 文件中,但 ReSharper 无法知道这一点。毕竟,在 type
中使用类名完全没问题。 web.config 文件的属性,或作为 typeof
的参数在 VB 文件中。或者插件可以添加一个引用提供程序,允许在 .resx 文件中使用类型名。因此,我们保持简单并搜索所有候选引用,即使它在进度对话框中看起来可能很奇怪。
关于resharper - 为什么 ReSharper Find Usages 命令会搜索 resx 文件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29012368/