为什么甚至可以使用反射在C#中更改私有成员或运行私有方法?

为什么甚至可以使用反射在C#中更改私有成员或运行私有方法?,c#,.net,reflection,C#,.net,Reflection,我最近遇到了一个问题,我在使用C#时遇到了这个问题,通过使用设置一个私有成员来解决 我惊讶地发现,在C#中,设置私有成员/字段和运行私有方法是允许的,也是可能的。这不是如何做这些事情的问题,它们都有很好的记录,我的问题是:为什么 如果将字段/成员/方法设置为private/internal,为什么C#作为一种语言允许将这些字段设置在范围之外?我认为这会引发某种例外。如果类希望更改或设置它们,难道没有方法或构造函数吗?因为访问修饰符是用来帮助记录要向使用者或继承者公开的API的 它们不是安全/访问

我最近遇到了一个问题,我在使用C#时遇到了这个问题,通过使用设置一个私有成员来解决

我惊讶地发现,在C#中,设置私有成员/字段和运行私有方法是允许的,也是可能的。这不是如何做这些事情的问题,它们都有很好的记录,我的问题是:为什么


如果将字段/成员/方法设置为private/internal,为什么C#作为一种语言允许将这些字段设置在范围之外?我认为这会引发某种例外。如果类希望更改或设置它们,难道没有方法或构造函数吗?

因为访问修饰符是用来帮助记录要向使用者或继承者公开的API的


它们不是安全/访问控制机制。

可见性修饰符不是为了安全

它们只是为了使结构化API/代码库的工作更有效,而不是让程序员陷入废话的泥潭,并且只公开消费者应该关心的事情。

不可能阻止有人这样做。你可以让它变得更难,你可以强迫他们使用不安全的代码,并开始盲目地设置位。毕竟,这是他们的程序/机器,他们可以做这样的事情


语言的设计使得你很难射中自己的脚,做坏事。但这并不会使它们成为不可能,这样做也会限制用户做一些不同寻常但仍然可取的事情。

反射是您与编译代码交互的方式。如果反射尊重源语言对隐私的期望,那么就需要另一种机制,就像它没有那样。一路下来的海龟

首先假设它所做的是它的本意,然后重新评估你的假设,即做一些没有人愿意做的不同的事情是一种误导

好问题

我的答案是:访问修饰符和可见性是API设计的一部分。通过反射,您可以完全控制几乎所有的事情,包括绕过API和在底层修改数据

访问修饰符可以使您的类免受外部意外更改的影响。您可以“意外地”调用方法或访问公共成员。有了反思,你很难坚持你做事情是偶然的


如果这种对反射的低级别访问是不可能的,那么我们都知道和喜欢的很多东西实际上是不可能的。

私人反射要求您获得基本上完全信任。完全信任意味着完全信任。如果你完全相信自己在做正确的事情,那为什么这不起作用呢


(事实上,私有反射的安全模型实际上比我在这里描述的要复杂得多,但这并不影响我的观点:这种能力受策略的约束。有关反射和安全策略如何交互的概述,请参阅(MSDN)。

有时,你不得不作弊

如果需要设置,可以很容易地说类应该有一个setter,但是如果不能添加一个呢?如果它不是你的类,它是一个专有库,你需要解决其中的一个bug怎么办?我并不是说你应该做这样的事情,事实上我会说你几乎肯定不应该做,但有时候让事情发挥作用的唯一方法就是无耻的欺骗。在这些情况下,这些机制的存在极为有益

但是,您应该始终质疑它们的使用,并且当然要注意,违反对象的公共API很可能会进一步导致问题,而且可能是错误的。除了在前面提到的场景中,这是在一些您无法更改的代码中使某些内容工作的唯一方法

<> P>一个值得注意的是C++及其派生类有很强的访问控制,但是有很多OOP语言没有。例如,Perl 5对象完全对外部干扰开放,私有方法和数据仅按惯例存在——Perl程序员知道,在第三方对象的hashref中乱搞可能会破坏一些东西,所以他们通常不会这样做。不过,与C#的反射功能一样,有时只要稍微调整一下不应该触摸的东西,就可以解决很多问题


但我再次重申,你几乎肯定不应该这样做。这些功能不适合日常使用。

我甚至无法通过反射物看到自己的脸。好的,我可以在视频中观看自己,但这是由一种叫做照相机的光学设备完成的,它还可以使用反射技术

如果我生病了,当医生需要X光来诊断和治疗我的疾病时,我可能已经死了,但是各种各样的反射都无法看到我的隐私。我也永远看不见自己

X射线(或类似的东西)可以观察我的内心,没有它我永远做不到

我宁愿说这比反思更现实。但是是的,我不能用我的眼睛直接看到真实的我,我所见过的每一个我都是某种反射。(深入思考,眼睛也能反映现实。)

因此,反射应该与现实相关,没有特定的视图。您可以假设使用者代码在面向对象的规则中仅限于BindingFlags.Public

在真实的宇宙中,几乎没有什么是不可能的;对我们来说,可能和不可能之间的唯一区别是,它是否可以由人类完成,因为我们是人类