27
class TestClass
{
    private string _privateString = "hello";
    void ChangeData()
    {
        TestClass otherTestClass = new TestClass();
        otherTestClass._privateString = "world";
    }
}

此代码在 C# 中编译,在 PHP 中等效工作,但有人可以解释为什么otherTestClass._privateString可以在这里更改的原因吗?

我会认为一个类的实例在任何情况下都不应该能够更改私有成员变量,并且尝试访问otherTestClass._privateString会给出“由于保护级别而无法访问”错误。

但事实并非如此,那么为什么在其自己的类中实例化一个对象可以让您访问私有成员?而且,这不会在一定程度上破坏封装吗?还是我错过了一些明显的东西?

  • (我不是在问上面的类设计是否是好的实践,只是想知道它背后的理论。)

编辑- 感谢您的回答和评论。澄清一下,我也很想知道能够做到这一点是否被认为是一个积极的特性,或者它是否是更好的编译时检查/代码清晰度的必要权衡/因为大多数其他语言都是这样做的或其他方式。在我看来,理想情况下编译器会阻止或警告你,但我离语言设计师还很远。任何关于这种方式的示例都可以让您做一些有用的事情(不违反封装),否则这些事情会很困难或不可能。

4

2 回答 2

35

该类的程序文本中的任何代码(包括嵌套类型)都可以访问私有成员。它与您正在处理的类的哪个实例无关。

我不相信这违反了封装——API 仍然与实现分离,但实现“知道”自身,无论它正在查看哪个实例。

我相信在其他一些语言中,这不是可访问性的工作方式,但它绝对适用于 C# 和 Java。(Java 关于什么可以访问私有成员的规则略有不同,但是您编写的翻译后的代码仍然可以工作。)

于 2010-11-22T11:15:13.217 回答
9

这是因为 C# 强制执行类级别的隐私,而不是对象级别的隐私。

大多数主流语言都执行相同的策略,即 C#、C++ 和 Java。我认为原因是:

1)因为开发者习惯了那种策略;

2)因为对象级别的隐私会变得过于乏味,以换取很少的优势。

于 2010-11-22T11:20:34.777 回答