【发布时间】:2010-12-21 04:06:29
【问题描述】:
我之前多次在公共方法上使用反射,但我从未意识到也可以调用私有方法。请参阅Reflection with private members。
为什么首先允许这样做?这不是要打破“私人”就是“私人”的规则吗?
【问题讨论】:
-
该链接已损坏。是不是搬到别的地方了?
标签: .net reflection methods private
我之前多次在公共方法上使用反射,但我从未意识到也可以调用私有方法。请参阅Reflection with private members。
为什么首先允许这样做?这不是要打破“私人”就是“私人”的规则吗?
【问题讨论】:
标签: .net reflection methods private
C# 中的private 确实只是语言规范的一部分;在 C# 语言中,以及在 Visual Basic 语言或任何其他合理的 .NET 语言(包括 CIL,所有 .NET 语言编译成的语言)中,都无法访问 private(或 protected,如果您不在派生类中)成员语言中。但是,仅仅因为该语言不支持公开访问 private 或 protected 成员并不意味着底层框架不能提供对这些成员的访问。
这是通常不应该使用诸如反射之类的变通方法来访问或修改private 或protected 成员的情况之一,但框架无论如何都允许这样做。一般来说,您应该有一个非常充分的理由来访问private 或protected 成员;例如,其中一个原因是实现了一个序列化程序,该序列化程序需要查看对象的内部状态以正确序列化对象。如果你不做这样的事情,你应该真正考虑重新实现你在里面闲逛的类,这样你就不需要在你的程序中使用反射。
【讨论】:
仅当代码在完全信任(或相关权限)下运行时才允许。否则,将抛出 MethodAccessException。
该框架完全能够适当地限制访问 - 当您在完全信任下运行或当您拥有特定权限时它不会这样做。请参阅"Security Considerations for Reflection" 了解更多详细信息,了解何时可以执行此操作。
【讨论】:
是的,它确实违反了规则。如果有人这样做,我几乎不会在审查期间通过代码。
使用反射来调用方法是很麻烦的,不是类型安全的,如果底层类对私有方法进行了重新设计,则很容易中断。
总之,我同意,这是个坏主意!
【讨论】:
这是您从框架中获得的高级功能。在生产代码中使用它来调用方法是非常少见的,它破坏了成员隐藏的优点。
有一些地方可能有用:
提供此功能的框架没有错,但在非必须的地方使用它是错误的。
【讨论】:
反射是 .NET 中的一项强大功能,但也有其缺点。
优点:
Reflection 允许访问所有成员(包括私有成员和受保护成员),前提是您至少具有 ReflectionPermission 安全性。 (当您的应用程序从同一驱动器而不是 Internet 访问反射程序集时,可以获得此权限。)
在极少数情况下,反射是执行任务的唯一方法。
缺点:
反射破坏了安全性(反编译程序集也是如此)。要获得应用程序代码和数据的完全安全性,您必须使用加密技术,而不仅仅是依赖 Private 或 Protected 关键字,因为如果单独使用,很容易通过反射或反编译来破解。
反射比静态引用(调用方法的正常方式)慢得多,并且消耗更多资源。因此,您应该避免反思,除非这是解决问题的唯一方法。
反射是解决问题的唯一方法的示例如下:
假设您的应用程序动态编译代码(例如当您绘制用户在运行时提供的函数时)。在这种情况下,加载程序集和类型的唯一方法是通过反射。
您想要克隆一个对象。您需要使用反射来访问其私有字段。
我希望这会有所帮助。 在此我要感谢 Francesco Balena 先生的精美书籍 Programming Microsoft Visual Basic 2005: The Language。
【讨论】: