Почему закрытая переменная-член может быть изменена экземпляром класса? - PullRequest
27 голосов
/ 22 ноября 2010
class TestClass
{
    private string _privateString = "hello";
    void ChangeData()
    {
        TestClass otherTestClass = new TestClass();
        otherTestClass._privateString = "world";
    }
}

Этот код компилируется в C #, а эквивалент работает в PHP, но может кто-нибудь объяснить причину, по которой otherTestClass._privateString можно изменить здесь?

Я бы подумал, что экземпляр класса не сможет изменить личную переменную-член ни при каких обстоятельствах, и что попытка доступа к otherTestClass._privateString приведет к ошибке «недоступен из-за уровня защиты».

Однако это не тот случай, так почему создание экземпляра объекта внутри его собственного класса позволяет вам получить доступ к закрытым членам?И разве это не нарушает степень инкапсуляции?Или я упускаю что-то очевидное?

  • (я не спрашиваю, является ли приведенный выше дизайн класса хорошей практикой, просто интересуюсь теорией, стоящей за этим.)

Редактировать - Спасибо за ответы и комментарии.Чтобы уточнить, мне также интересно узнать, рассматривается ли возможность сделать это как положительную особенность, или это необходимый компромисс для лучшей проверки во время компиляции / ясности кода /, потому что большинство других языков делают это таким образом или как-то еще.Мне кажется, что в идеале компилятор мог бы предотвратить или предупредить вас об этом, но тогда я далек от языкового дизайнера.Любые примеры того, как это позволяет вам делать что-то полезное (без нарушения инкапсуляции), что в противном случае было бы трудно или невозможно, было бы замечательно.

Ответы [ 2 ]

35 голосов
/ 22 ноября 2010

Закрытые члены доступны для любого кода в тексте программы этого класса (в том числе во вложенных типах).Он не имеет никакого отношения к тому, с каким экземпляром класса вы имеете дело.

Я не верю, что это нарушает инкапсуляцию - API по-прежнему отделен от реализации, но реализация «знает» о себе независимо от того,на какой экземпляр он смотрит.

Я считаю, что в некоторых других языках это не , как работает доступность, но это определенно для C # и Java.(У Java немного другие правила доступа к закрытым членам, но переведенный код того, что вы написали, все равно будет работать.)

9 голосов
/ 22 ноября 2010

Это связано с тем, что C # обеспечивает конфиденциальность на уровне класса, а не конфиденциальность на уровне объекта.

Большинство основных языков применяют одну и ту же политику, то есть C #, C ++ и Java.Я думаю, что причина:

1) потому что разработчики привыкли к такой политике;

2) потому что конфиденциальность на уровне объектов станет слишком утомительной в обмен на очень мало преимуществ.

...