通过针对具有公共成员的修改后的程序集进行编译来访问私有成员的反射的替代方法

Cab*_*row 6 c# reflection unsafe private access-modifiers

概括

我寻找一种通过反射访问私人成员的替代方法,似乎我找到了一个。
剩下的问题是:

  1. 无论环境如何,它总是有效吗?
  2. 有什么理由不使用它?

寻找替代方案的原因

使用反射或一些稍微简化它的反射工具是以编程工作和计算资源方面的开销为代价的。特别是如果您需要使用私有类型的实例,它会变得非常麻烦。
此外,您还失去了IDE 的代码完成和其他功能的优势。即使是简单的拼写错误也可能导致错误,因为您使用字符串进行反射。

替代方法

获取原始程序集并将私有/非公共成员更改为公共成员(通过 IL 编辑器、反编译器或 Cecil)。
将这个修改后的程序集添加到您的引用中,然后您就可以轻松开发,因为编译器认为您可以访问它们(对于这个版本,您可以访问它们)。
然而,如果您针对原始程序集使用已编译的程序集,则这只适用于类型,因为如果您访问其他私有成员,则会在运行时遇到访问冲突异常。
除非您启用“允许不安全代码”,否则它似乎不再关心访问修饰符。
我没有找到有关此功能的任何信息(?),但此选项和代码中相关的不安全关键字通常主要用于指针。

对我来说它有效,但我不知道这种行为在其他情况下(例如不同的操作系统和 CLR 版本)是否一致。
另外,如果还有其他原因不使用此技术。

大会宣传员

我编写了一个工具来创建程序集的副本,其中所有成员都是公共的(类型、方法、字段、属性的 getter 和 setter)。

https://github.com/CabbageCrow/AssemblyPublicizer

它使用起来很简单,在 Windows 上您甚至可以将程序集拖放到 exe 上。

潜在的工作流程

  1. 公开原始程序集(使用工具)
  2. 使用公开的程序集作为参考
  3. 开发时无需任何思考即可访问私人成员,并对此感到高兴
  4. 启用“允许不安全代码”进行编译
    请参阅https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/compiler-options/unsafe-compiler-option
  5. 将您自己的程序集与原始未修改的程序集一起使用,它仍然可以神奇地访问私有成员。