3

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

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

4

5 回答 5

4

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

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

于 2009-11-28T06:28:35.567 回答
4

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

该框架完全能够适当地限制访问 - 当您在完全信任下运行或具有特定权限时它不会这样做。有关何时可以执行此操作的更多详细信息,请参阅“反射的安全注意事项” 。

于 2009-11-28T07:52:21.420 回答
1

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

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

所以简而言之,我同意,这是一个坏主意!

于 2009-11-28T06:26:30.240 回答
1

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

有一些地方可能有用:

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

提供此功能的框架没有任何问题,但在非必须的情况下使用它是错误的。

于 2009-11-28T06:28:43.730 回答
1

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

优点:

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

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

缺点:

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

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

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

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

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

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

于 2012-07-06T13:59:14.307 回答