В .NET, почему я могу получить доступ к закрытым членам экземпляра класса внутри класса? - PullRequest
7 голосов
/ 11 апреля 2010

При очистке некоторого кода, написанного сегодня кем-то другим, я изменил модификатор доступа с Public на Private для переменной класса / member / field. Я ожидал длинный список ошибок компилятора, которые я использую для «рефакторинга / переделки / проверки» кода, который использовал эту переменную. Вообразите мое удивление, когда я не получил никаких ошибок. После рассмотрения выясняется, что другой экземпляр класса может получить доступ к закрытым членам другого экземпляра, объявленного в классе. Совершенно не исключено.

Это нормально? Я кодировал в .NET с самого начала и никогда не сталкивался с этой проблемой и не читал об этом. Возможно, я наткнулся на него раньше, но только «смутно заметил» и продолжаю. Может кто-нибудь объяснить мне это поведение? Я хотел бы знать «почему», я могу это сделать. Пожалуйста, объясните, не говорите мне правило. Я что-то не так делаю? Я обнаружил такое поведение в C # и VB.NET. Кажется, код использует преимущества доступа к закрытым переменным. Недостатком является то, что программист создал большую тарелку спагетти.

С уважением,

  • В полном замешательстве

Class Jack
    Private _int As Integer
End Class
Class Foo
    Public Property Value() As Integer
        Get
            Return _int
        End Get
        Set(ByVal value As Integer)
            _int = value * 2
        End Set
    End Property
    Private _int As Integer
    Private _foo As Foo
    Private _jack As Jack
    Private _fred As Fred
    Public Sub SetPrivate()
        _foo = New Foo
        _foo.Value = 4  'what you would expect to do because _int is private
        _foo._int = 3   'TOTALLY UNEXPECTED
        _jack = New Jack
        '_jack._int = 3 'expected compile error 
        _fred = New Fred
        '_fred._int = 3 'expected compile error 
    End Sub
    Private Class Fred
        Private _int As Integer
    End Class
End Class

Ответы [ 4 ]

13 голосов
/ 11 апреля 2010

Это "нормально". Private члены являются закрытыми для класса, а не для конкретного экземпляра.

10 голосов
/ 15 апреля 2010

Вы сказали:

Пожалуйста, объясните, не говорите мне правило.

Ну, вот мои два цента.

На мой взгляд, предпосылка частных членов класса заключается в том, что класс может внутренне знать о своей собственной реализации, не подвергая эту реализацию внешнему миру. Таким образом, один экземпляр класса вполне способен понять, как реализован другой экземпляр того же класса; поэтому он не ограничен в использовании этих знаний о реализации.

Что касается примеров манипулирования друг другом, я признаю, что это несколько необычно. Но возьмем для примера статические методы построения. Вы также ограничите их от доступа к закрытым членам экземпляров? Если это так, вы сделали много полезного кода невозможным. Если нет, неясно, почему статические методы должны иметь доступ к закрытым членам, а методы экземпляра не должны.

Другими словами, слово «частный» в ООП не предназначено для передачи идеи личной конфиденциальности , как у лиц, скрывающихся друг от друга. Скорее, думайте о классе как о «только для членов», вроде клуба , где есть определенные способы делать вещи, о которых знают только члены клуба.

1 голос
/ 15 апреля 2010

Проблема доступа связана с тем, где код обращается к частным членам, а не с тем, через что он получает к ним доступ.

У вас есть доступ к полю _foo._int в определении класса Foo, но не за его пределами.

Вас может удивить, что следующее расширение для вложенного класса Fred также допустимо.

Private Class Fred
    Private _int As Integer
    Private Sub Blah(ByVal foo As Foo)
        foo._int = 9
    End Sub
End Class
0 голосов
/ 11 апреля 2010

Это ожидаемое поведение. Вложенные классы могут получить доступ к закрытым членам класса контейнера.

...