3

我希望在一组已编译的 .net 程序集中找到特定类的关联源文件。

例如

MyAsm.Namespace.Foo  -> C:\Source\foo.cs
MyAsm.Namespace.Bar  -> C:\Source\Code\MoreCode\Common.cs
MyAsm.Namespace2.Bar -> C:\Source\Code\MoreCode\Common.cs
...

我有程序集反射/提取我对使用标准System.Reflection功能感兴趣的类型信息。

我现在需要找到该类的原始 .cs 源文件。虽然我有一个蛮力解决方案作为解决方法,但它的速度慢得让人无法接受。

我希望在大约 5 秒内完成整个过程。目前,反射提取部分需要不到 1 秒,“文件关联”需要几分钟。我不认为在 4 秒内扫描几个 MB 是不合理的。

不幸的是,有一些警告可以防止走捷径。

  • 我不知道文件的名称,所以我需要dir / s *.cs每次运行来枚举所有潜在的源文件。

  • 类名并不总是与源文件匹配,它可以提示可能的位置,但不能保证工作。

  • 在某些情况下,多个类在同一个文件中定义。

  • 有 ~20k .cs 文件/63MB 的源代码。

  • 我需要大约 10k 个类/它们的文件之间的关联。

  • 我不希望使用其中声明的文件名/类来增量构建数据库,因为文件内容会发生变化,并且我将很难维护这个数据库等(尽管如果一切顺利,我可能不得不走这条路否则失败)。

  • 这将在操作系统上运行,不会启用 Windows 搜索/索引,所以那里也没有乐趣。

我试过的:

  • 使用 findstr.exe - 太慢了

  • 创建一个 .net 应用程序,将所有文件加载到内存中。- 太慢找不到 *.cs / 加载所有文件,一旦文件在内存中就快速扫描文件。

  • 从所有较小的文件创建一个大的源文件,加载它,扫描等 - 再一次,太慢了。构建文件需要几分钟,加载后很快。

  • 读取 PDB 文件 - 我正在研究 PDB2XML.exe,虽然它确实输出文件名并且运行速度很快,但我看不到如何将类与文件名相关联。

那么,是否有人对 PDB2XML 有其他建议、魔法或一些经验?

4

4 回答 4

2

这并不能完全解决您面临的问题,因为您想获取任意类的文件路径,但这对我来说很容易使用,它只是从源位置获取指向某个文件的指针。我在单元测试中使用它,所以性能并不是非常重要。

var x = new StackTrace(true);
var file = x.GetFrame(0).GetFileName();
于 2013-06-27T17:54:30.003 回答
1

如果文件在磁盘上,恕我直言,使用 PDB 是您的最佳选择。文件名(由ISymbolDocument.URL表示)与序列点相关。序列点与方法(包括属性获取/设置)相关,而不是类。当然,一个 .NET 类源可以存储在多个文件中。所以你必须浏览一个类型的所有成员(例如使用反射)来确定所有相应的文件。

于 2012-10-24T14:35:37.680 回答
1

如果您能够编辑源。您可以使用反射和 System.Runtime.CompilerServices.CallerFilePath 来完成。只需将属性添加到每个文件的源中即可。您可能需要为部分类考虑一些巧妙的方法。

此示例提供了放置属性的源文件和行号。

[AttributeUsage(AttributeTargets.All, Inherited = false, AllowMultiple = false)]
public sealed class SourceInfoAttribute : Attribute
{
    public SourceInfoAttribute([CallerLineNumber]int sourceLineNumber = 0, [CallerFilePath] string sourceFilePath = "")
    {
        SourceLineNumber = sourceLineNumber;
        SourceFilePath = sourceFilePath;
    }

    internal int SourceLineNumber { get; set; }
    internal string SourceFilePath { get; set; }
}    
于 2019-07-26T18:23:43.927 回答
0

我不知道 .NET 中的文件名和程序集名称之间有任何关系,实际上可能在一个文件中定义了多个程序集,所以如果不实际查看每个源代码,我不知道如何做到这一点文件并搜索类定义或维护正在运行的索引。

于 2012-10-24T14:12:08.423 回答