为什么类实例可以改变私有成员变量?
class TestClass
{
private string _privateString = "hello";
void ChangeData()
{
TestClass otherTestClass = new TestClass();
otherTestClass._privateString = "world";
}
}
此代码在 C# 中编译,等效的代码在 PHP 中工作,但是有人可以解释为什么 otherTestClass._privateString
可以在此处更改吗?
我本以为类的实例在任何情况下都不应该能够更改私有成员变量,并且尝试访问 otherTestClass._privateString 会给出“由于保护级别而无法访问”错误。
但情况并非如此,那么为什么在自己的类中实例化一个对象可以让您访问私有成员呢?应该吗,这不会在一定程度上破坏封装吗?或者我错过了一些明显的东西?
- (我不是在问上面的类设计是否是好的实践,只是想知道其背后的理论。)
编辑 - 感谢您的回答和评论。为了澄清,我也有兴趣知道能够做到这一点是否被视为一个积极的功能,或者是否是为了更好的编译时检查/代码清晰度/因为大多数其他语言都是这样做的或其他什么的必要权衡。在我看来,理想情况下编译器会阻止或警告你这一点,但我离语言设计师还很远。任何关于这种方式如何让您做一些有用的事情(不违反封装)的例子都会很棒,否则这些事情会很困难或不可能。
class TestClass
{
private string _privateString = "hello";
void ChangeData()
{
TestClass otherTestClass = new TestClass();
otherTestClass._privateString = "world";
}
}
This code compiles in C# and the equivalent works in PHP, but can someone explain the reason why otherTestClass._privateString
can be changed here ?
I would have thought an instance of a class should not be able to change a private member variable under any circumstances, and that trying to access otherTestClass._privateString
would give an 'inaccessible due to protection level' error.
This is not the case though, so why does instantiating an object inside its own class let you access the private members ? And should it, doesn't this break encapsulation to an extent ? Or am I missing something obvious ?
- (I'm not asking if the above class design is good practice, just wondering about the theory behind it.)
Edit - Thanks for the answers and comments. To clarify, I'm also interested in knowing if being able to do this is regarded as a positive feature, or if it's a necessary tradeoff for better compile-time checking/code clarity/because most other languages do it that way or whatever. It seems to me ideally the compiler would prevent or warn you about this, but then I'm far from a language designer. Any examples of how it being this way lets you do something useful (without violating encapsulation) that would otherwise be difficult or impossible would be great.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
私有成员可以被该类的程序文本中的任何代码访问(包括嵌套类型中)。它与您正在处理的类的哪个实例无关。
我不认为这违反了封装性——API 仍然与实现分离,但实现“了解”自身,无论它正在查看哪个实例。
我相信在其他一些语言中,辅助功能并不是这样工作的,但 C# 和 Java 确实如此。 (Java 对于访问私有成员的规则略有不同,但您编写的翻译代码仍然有效。)
Private members are accessible to any code within the program text of that class (including within nested types). It has nothing to do with which instance of the class you're dealing with.
I don't believe this violates encapsulation - the API is still separated from the implementation, but the implementation "knows" about itself regardless of which instance it's looking at.
I believe that in some other languages this isn't how accessibility works, but it definitely is for C# and Java. (Java has slightly different rules about what can access private members, but the translated code for what you've written would still work.)
这是因为 C# 强制执行类级隐私,而不是对象级隐私。
大多数主流语言都执行相同的策略,即 C#、C++ 和 Java。我认为原因是:
1)因为开发者已经习惯了这种政策;
2)因为对象级隐私会变得过于乏味,而带来的好处却很少。
This is because C# enforces class-level privacy and not object-level privacy.
Most mainstream languages enforce the same policy, i.e. C#, C++ and Java. I think the reason are:
1) because developers are accustomed to that kind of policy;
2) because object-level privacy would become much too tedious in return of very few advantages.