使用.NET反射的私有方法。为什么?

时间:2009-11-28 06:18:12

标签: .net reflection methods private

我之前在公共方法上多次使用反射,但我从未意识到也可以调用私有方法。请参阅 Reflection with private members

为什么首先允许这样做?难道这不会打破“私人”的“私人”规则吗?

5 个答案:

答案 0 :(得分:4)

C#中的

private实际上只是语言规范的一部分;在C#语言中,以及在Visual Basic语言或任何其他敏感的.NET语言(包括CIL,所有.NET语言编译的内容)中,都禁止访问private(或protected,如果您不在派生类中)语言。但是,仅仅因为该语言不支持公开访问privateprotected成员并不意味着底层框架无法提供对这些成员的访问权限。

这是其中一个通常不应该使用反射等变通方法访问或修改privateprotected成员的情况之一,但框架允许一个无论如何。通常,您应该非常有充分理由访问privateprotected成员;例如,一个这样的原因是实现了一个序列化器,它需要查看对象的内部状态才能正确地序列化对象。如果你没有做那样的事情,你应该真正重新考虑重新实现你内心深处的课程,这样你就不需要在程序中使用反射。

答案 1 :(得分:4)

仅当代码在完全信任(或具有相关权限)下运行时才允许这样做。否则,将抛出MethodAccessException

该框架完全能够适当地限制访问 - 当您在完全信任下运行或具有特定权限时,它不会这样做。有关何时能够执行此操作的详细信息,请参阅"Security Considerations for Reflection"

答案 2 :(得分:1)

是的,它确实违反了规则。如果有人这样做,我几乎不会在评论期间传递代码。

使用反射来调用方法是slllloooow,而不是类型安全的,并且如果底层类具有重写的私有方法,则容易中断。

总之,我同意,这是一个坏主意!

答案 3 :(得分:1)

这是您从框架中获得的高级功能。在生产代码中使用它来调用方法非常罕见,它打破了成员隐藏的优势。

有些地方可能会有用:

  • 传统代码测试 - 例如,假设您正在使用旧代码,并且希望使用单元测试来覆盖它。如果您不允许更改代码并且您想要测试一小部分功能,则调用私有方法很有用。
  • 生产代码中的黑客 - 我遇到过第三方控件中的错误,在某些情况下,私有清理没有完成。使用私有调用我可以解决它。

提供此功能的框架没有任何问题,但在不是必须的地方使用它是错误的。

答案 4 :(得分:1)

反射是.NET中一个强大的功能,但也有它的缺点。

<强>优点:

  1. 反射允许访问所有成员(包括私有成员和受保护成员),前提是您至少拥有 ReflectionPermission 安全性。 (当您的应用程序从同一驱动器访问反射的程序集而不是从Internet访问时,可以获得此权限。)

  2. 在极少数情况下,反射是执行任务的唯一方法。

  3. <强>缺点:

    1. 反射会破坏安全性(反编译程序集也是如此)。要获得应用程序代码和数据的完全安全性,您必须使用加密技术,而不仅仅依赖于私有或受保护的关键字,因为如果单独使用,可以通过反射或反编译轻松破解。

    2. 与静态引用(通常称为方法的方式)相比,反射速度慢得多并消耗更多资源。因此,除非这是解决问题的唯一方法,否则应避免反思。

    3. 示例当反射是解决问题的唯一方法时:

      1. 假设您的应用程序动态编译代码(例如,当您绘制用户在运行时提供的函数时)。在这种情况下,加载程序集和类型的唯一方法是通过反射。

      2. 您想克隆一个对象。您需要使用反射来访问其私有字段。

      3. 我希望这会有所帮助。 我应该感谢Francesco Balena先生的精美书籍“Microsoft Visual Basic 2005编程:语言”。