【问题标题】:Private methods using .NET reflection. Why?使用 .NET 反射的私有方法。为什么?
【发布时间】:2010-12-21 04:06:29
【问题描述】:

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

为什么首先允许这样做?这不是要打破“私人”就是“私人”的规则吗?

【问题讨论】:

  • 该链接已损坏。是不是搬到别的地方了?

标签: .net reflection methods private


【解决方案1】:

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

这是通常不应该使用诸如反射之类的变通方法来访问或修改privateprotected 成员的情况之一,但框架无论如何都允许这样做。一般来说,您应该有一个非常充分的理由来访问privateprotected 成员;例如,其中一个原因是实现了一个序列化程序,该序列化程序需要查看对象的内部状态以正确序列化对象。如果你不做这样的事情,你应该真正考虑重新实现你在里面闲逛的类,这样你就不需要在你的程序中使用反射。

【讨论】:

    【解决方案2】:

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

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

    【讨论】:

      【解决方案3】:

      是的,它确实违反了规则。如果有人这样做,我几乎不会在审查期间通过代码。

      使用反射来调用方法是很麻烦的,不是类型安全的,如果底层类对私有方法进行了重新设计,则很容易中断。

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

      【讨论】:

        【解决方案4】:

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

        有一些地方可能有用:

        • 遗留代码测试 - 例如,假设您正在使用遗留代码并且您希望通过单元测试来覆盖它。如果您不允许更改代码并且您想测试调用私有方法的一小部分功能很有用。
        • 生产代码中的黑客攻击 - 我曾经在 3rd 方控制中遇到过一个错误,在某些情况下未完成私有清理。使用私有调用我可以解决它。

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

        【讨论】:

          【解决方案5】:

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

          优点:

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

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

          缺点:

          1. 反射破坏了安全性(反编译程序集也是如此)。要获得应用程序代码和数据的完全安全性,您必须使用加密技术,而不仅仅是依赖 Private 或 Protected 关键字,因为如果单独使用,很容易通过反射或反编译来破解。

          2. 反射比静态引用(调用方法的正常方式)慢得多,并且消耗更多资源。因此,您应该避免反思,除非这是解决问题的唯一方法。

          反射是解决问题的唯一方法的示例如下:

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

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

          我希望这会有所帮助。 在此我要感谢 Francesco Balena 先生的精美书籍 Programming Microsoft Visual Basic 2005: The Language。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2022-11-27
            • 2012-04-02
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2010-12-14
            相关资源
            最近更新 更多