我之前在公共方法上多次使用反射,但我从未意识到也可以调用私有方法。请参阅 Reflection with private members 。
为什么首先允许这样做?难道这不会打破“私人”的“私人”规则吗?
答案 0 :(得分:4)
private
实际上只是语言规范的一部分;在C#语言中,以及在Visual Basic语言或任何其他敏感的.NET语言(包括CIL,所有.NET语言编译的内容)中,都禁止访问private
(或protected
,如果您不在派生类中)语言。但是,仅仅因为该语言不支持公开访问private
或protected
成员并不意味着底层框架无法提供对这些成员的访问权限。
这是其中一个通常不应该使用反射等变通方法访问或修改private
或protected
成员的情况之一,但框架允许一个无论如何。通常,您应该非常有充分理由访问private
或protected
成员;例如,一个这样的原因是实现了一个序列化器,它需要查看对象的内部状态才能正确地序列化对象。如果你没有做那样的事情,你应该真正重新考虑重新实现你内心深处的课程,这样你就不需要在程序中使用反射。
答案 1 :(得分:4)
仅当代码在完全信任(或具有相关权限)下运行时才允许这样做。否则,将抛出MethodAccessException
。
该框架完全能够适当地限制访问 - 当您在完全信任下运行或具有特定权限时,它不会这样做。有关何时能够执行此操作的详细信息,请参阅"Security Considerations for Reflection"。
答案 2 :(得分:1)
使用反射来调用方法是slllloooow,而不是类型安全的,并且如果底层类具有重写的私有方法,则容易中断。
总之,我同意,这是一个坏主意!
答案 3 :(得分:1)
这是您从框架中获得的高级功能。在生产代码中使用它来调用方法非常罕见,它打破了成员隐藏的优势。
有些地方可能会有用:
提供此功能的框架没有任何问题,但在不是必须的地方使用它是错误的。
答案 4 :(得分:1)
反射是.NET中一个强大的功能,但也有它的缺点。
<强>优点:强>
反射允许访问所有成员(包括私有成员和受保护成员),前提是您至少拥有 ReflectionPermission 安全性。 (当您的应用程序从同一驱动器访问反射的程序集而不是从Internet访问时,可以获得此权限。)
在极少数情况下,反射是执行任务的唯一方法。
<强>缺点:强>
反射会破坏安全性(反编译程序集也是如此)。要获得应用程序代码和数据的完全安全性,您必须使用加密技术,而不仅仅依赖于私有或受保护的关键字,因为如果单独使用,可以通过反射或反编译轻松破解。
与静态引用(通常称为方法的方式)相比,反射速度慢得多并消耗更多资源。因此,除非这是解决问题的唯一方法,否则应避免反思。
示例当反射是解决问题的唯一方法时:
假设您的应用程序动态编译代码(例如,当您绘制用户在运行时提供的函数时)。在这种情况下,加载程序集和类型的唯一方法是通过反射。
您想克隆一个对象。您需要使用反射来访问其私有字段。
我希望这会有所帮助。 我应该感谢Francesco Balena先生的精美书籍“Microsoft Visual Basic 2005编程:语言”。