reflection是否打破了私有方法的想法,因为私有方法可以在类之外访问?

反思是否打破了私有方法的想法? 因为可以从类外部访问私有方法吗? (也许我不明白反思的意思或错过别的东西,请告诉我) http://en.wikipedia.org/wiki/Reflection_%28computer_science%29

编辑:如果relection打破了私有方法的想法 – 我们是否仅将私有方法用于程序逻辑而不用于程序安全性?

谢谢

我们是否仅将私有方法用于程序逻辑而不用于程序安全性?

目前尚不清楚“程序安全”的含义。 安全无法在真空中讨论; 您在考虑哪些资源来防范哪些威胁?

CLR代码访问安全系统旨在保护用户数据资源免受在用户机器上运行恶意部分可信代码的威胁。

因此,CLR中的reflection,访问控制和安全性之间的关系是复杂的。 简单而不完全准确,规则如下:

  • 完全信任意味着完全信任。 完全受信任的代码可以访问进程中的每一位内存。 这包括私人领域。

  • 在部分信任中反映私有部分的能力由许可控制; 如果没有授予,则部分信任代码可能不会对私有进行反思。

有关详细信息,请参见http://blogs.msdn.com/b/shawnfa/archive/2006/09/29/777047.aspx 。

  • 桌面CLR支持称为“受限跳过可见性”的模式,其中reflection和安全系统交互的规则略有不同。 基本上,如果部分受信任的代码从具有相同较少信任的程序集的类型访问私有字段,则具有使用私有reflection权的部分受信任的代码可以通过reflection访问私有字段。

看到

http://blogs.msdn.com/b/shawnfa/archive/2006/10/05/using-lightweight-codegen-from-partial-trust.aspx

详情

执行摘要是:您可以充分锁定部分受信任的代码,使其无法使用reflection来查看私有内容。 您无法锁定完整的信任代码; 这就是为什么它被称为“完全信任”。 如果你想限制它,那就不要相信它

那么:确保私有字段保护它免受低信任代码试图读取它的威胁,从而窃取用户的数据吗? 是的 它是否保护它免受高信任代码读取它的威胁? 。 如果代码既受用户信任又对用户不利,那么用户就会遇到大问题 。 他们不应该信任该代码。

请注意,例如,将字段设为私有不会保护代码中的密码不会受到拥有代码且对您有敌意的用户的影响 。 安全系统保护好用户免受恶意代码的侵害 。 它不能保护恶意用户的 良好代码 。 如果你想私下制作一些东西以保护用户,那么你就是傻瓜的差事。 如果你想让它变得私密,以防止那些诱使用户运行恶意低信任代码的邪恶黑客的秘密,那么这是一个很好的技巧。

Reflection确实提供了绕过Java的访问保护修饰符的方法,因此违反了在C ++和Java中实现的严格封装 。 然而,这并不像你想象的那么重要。

访问保护修改器旨在帮助程序员开发模块化的良好分解系统,而不是不妥协的门卫。 有时候很有理由打破严格的封装,例如unit testing和框架开发

虽然最初可能很难理解访问保护修饰符很容易被绕过,但请记住,有许多语言( Python , Ruby等)根本没有它们。 这些语言用于构建大型复杂系统,就像提供访问保护的语言一样。

关于访问保护修饰符是一种帮助还是一种障碍,存在一些争论。 即使您确实重视访问保护,也可以将其视为助手,而不是制作或破坏您的项目。

是的,但这不是问题。

封装不是关于安全性或秘密,而是关于组织事物。

反思不是“正常”编程的一部分。 如果你想用它来打破封装,你接受风险(版本问题等)

只有在没有更好(更少侵入性)的方法来完成某些事情时,才应该使用反思。

反思是系统级的“工具”,如持久性映射,应该隐藏在经过良好测试的库中。 我会发现在正常的应用程序代码中使用reflection可疑。

我开始说“这不是问题”。 我的意思是:只要您按预期使用reflection。 小心点。

这就像你的房子。 锁只能阻止诚实的人或不愿意选择锁的人。

数据是数据,如果有人确定,他们可以对您的代码做任何事情。 直译任何东西。

所以,是的,reflection将允许人们做你不希望他们用你的代码做的事情,例如访问私有字段和方法。 然而,重要的是人们不会意外地这样做。 如果他们使用reflection,他们知道他们正在做他们可能不打算做的事情,就像没有人意外地扣上你前门上的锁一样。

不,反思并没有打破私人方法的想法。 至少本身不是。 没有任何东西可以说reflection不能遵守访问限制。

设计糟糕的reflection打破了私有方法的想法,但这与reflection本身没有任何关系: 任何设计糟糕的东西都会破坏私有方法的概念。 特别是,私有方法的糟糕设计也可能明显打破私有方法的想法。

设计糟糕是什么意思? 好吧,正如我上面所说,没有什么可以阻止你使用一种语言,其中reflection服从访问限制。 这个问题是,例如调试器,分析器,覆盖工具,IntelliSense,IDE,工具通常需要能够违反访问限制。 由于没有办法向不同的客户提供不同版本的reflection,大多数语言选择安全工具。 (E是反例,它绝对没有任何reflection能力,作为有意识的设计选择。)

但是,谁说你不能向不同的客户展示不同版本的反思? 嗯,问题很简单,在经典的reflection实现中,所有对象都可以反映自己,并且因为每个对象只有一个,所以只能有reflection版本。

那么, 糟糕设计的想法会在哪里出现? 那么,请注意上段中的“负责”一词。 每个对象都有责任自我反思。 此外,每个对象都负责首先编写的任何对象。 换句话说:每个对象至少有两个职责。 这违反了面向对象设计的基本原则之一:单一责任原则。

解决方案相当简单:分解对象。 原始对象只负责它最初编写的内容。 还有另一个对象(称为Mirror,因为它是反映其他对象的对象),它负责reflection。 现在,反思的责任被分解为一个单独的对象,是什么阻止我们拥有一个,而不是两个,三个, 多个镜像对象? 尊重访问限制的访问限制,只允许对象反映自身但不反映任何其他对象,只允许内省(即只读),只允许反映只读的呼叫站点信息(即分析器),它提供对整个系统的完全访问权限,包括违反访问限制(对于调试器),只能提供对方法名称和签名的只读访问权限并且遵守访问限制(对于IntelliSense)等等…

作为一个很好的奖励,这意味着镜子本质上是reflection能力(在能力安全意义上)。 IOW:在长达十年的调和安全性和运行时动态元编程的过程中,镜子是圣杯。

Mirrors的概念最初是在Self中发明的,从而将其转移到Animorphic Smalltalk / Strongtalk ,然后是Newspeak 。 有趣的是,Java调试接口基于Mirrors,因此Java(或者更确切地说是JVM)的设计者清楚地了解它们,但是Java的反思被打破了。

正如其他已经说过的那样。

但是,我记得在Java中可能有一个安全管理器处于活动状态,如果您没有权限,可能会阻止您访问任何私有方法,即使使用reflection也是如此。 如果运行本地JVM,则此类管理器通常不处于活动状态。

是的,反思打破了这个想法。 本地语言也有一些技巧来破坏OOP规则,例如,在C ++中,可以使用指针技巧更改私有类成员。 但是,通过使用这些技巧,我们得到的代码可能与未来的类版本不兼容 – 这是我们为破坏OOP规则而付出的代价。

是的,reflection可能被用来违反封装,甚至导致不正确的行为。 请记住,需要信任程序集来执行reflection,因此仍然存在一些保护措施。

是的,它打破了封装,如果你想要它。 但是,它可以很好地使用 – 比如为私有方法编写unit testing,或者有时 – 正如我从自己的经验中学到的 – 绕过第三方API中的错误:)

请注意封装!=安全性。 封装是面向对象的设计概念,仅用于改进设计。 为了安全起见,java中有SecurityManager 。

我认为这是一个意见问题,但是如果你使用reflection来解决开发人员在课堂上实施的封装,那么你就是在挫败目的。

因此,为了回答你的问题,它打破了封装(或信息隐藏)的想法,它简单地声明私有属性/方法是私有的,因此它们不能在类外部被破坏。

是。 reflection打破了封装原则。 这不仅是为了访问私有成员,而是暴露一个类的整个结构。

Reflection使得任何CLR类都可以检查和操作其他CLR类的属性和字段,但不一定要明智地这样做。 一个类可能会掩盖属性和字段的含义,或者通过让它们以非显而易见的方式相互依赖,静态字段,底层OS信息等来保护它们免受篡改。

例如,类可以在某个变量中为其主窗口保留OS句柄的加密版本。 使用reflection,另一个类可以看到该变量,但是在不知道加密方法的情况下,它无法识别它所属的窗口或使变量引用另一个窗口。

我见过自称充当“通用序列化器”的课程; 如果应用于像数据存储容器类这样缺少“可序列化”属性但其他方面完全简单的东西,它们会非常有用。 如果应用于任何创作者努力掩盖事物的类,他们将产生gobbledygook。

是的,它确实破坏了封装。 但在某些情况下使用它有很多充分的理由。

例如:

我在一些网站上使用MSCaptcha ,但它在标签周围呈现了一个与我的HTML 混淆的

。 然后我可以使用标准的标签并使用reflection来获取validation码的图像ID的值来构造URL。

图像ID是私有属性,但使用reflection我可以获得该值。

通过private / protected / package / public进行访问控制主要不是为了安全。

它可以帮助好人做正确的事,但不会阻止坏人做错事。

通常我们假设其他人都是好人,我们将他们的代码包含在我们的应用程序中。

如果你不能相信你所包含的图书馆的人,那你就搞砸了。