代码之家  ›  专栏  ›  技术社区  ›  AMissico

在.NET中,我为什么可以访问类实例中的私有成员?

  •  7
  • AMissico  · 技术社区  · 14 年前

    在清理今天由其他人编写的代码时,我将访问修饰符从 Public Private 在类变量/成员/字段上。我期望有一长串编译器错误列表,用于“重构/返工/检查”使用此变量的代码。想象一下,当我没有发现任何错误时,我会感到惊讶。检查之后,发现类的另一个实例可以访问在类中声明的另一个实例的私有成员。完全没有例外。

    这是正常的吗?我从一开始就在.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 回复  |  直到 14 年前
        1
  •  13
  •   user200783    14 年前

    这是“正常的”。 Private 成员是类的私有成员,而不是特定实例的私有成员。

        2
  •  10
  •   Dan Tao    14 年前

    你说:

    请解释一下,不要只是告诉我规则。

    好吧,这是我的两分钱。

    正如我所看到的,类的私有成员的前提是类可以在内部意识到自己的实现,而不会将该实现暴露给外部世界。因此,类的一个实例完全能够理解同一类的另一个实例的实现方式;因此,不限制利用该实现知识。

    至于互相操纵的例子,我承认这有点不寻常。但以静态构造方法为例。您还会限制这些访问实例的私有成员吗?如果是这样,那么就不可能提供很多有用的代码。如果不是,就不清楚为什么静态方法应该能够访问私有成员,但实例方法不应该。

    换句话说,OOP中的“private”一词并不是用来表达 个人隐私 就像个人互相躲藏一样。更确切地说,把一个类看作是一种“仅成员”的类型 俱乐部 在那里有一些只有俱乐部成员知道的事情。

        3
  •  1
  •   Enigmativity    14 年前

    访问的问题是代码访问私有成员的位置,而不是访问私有成员的方式。

    您可以访问 _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
    
        4
  •  -1
  •   Pierreten    14 年前

    这是预期行为。嵌套类可以访问容器类的私有成员。