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

时间:2010-04-10 23:38:40

标签: .net class-design

在清理其他人今天编写的代码时,我在类变量/ member / field上将访问修饰符从Public更改为Private。我期待一长串编译器错误,我用它来“重构/返工/审查”使用此变量的代码。想象一下,当我没有收到任何错误时,我感到惊讶。在审阅之后,事实证明,Class的另一个实例可以访问Class中声明的另一个实例的私有成员。完全不被接受。

这是正常的吗?我从一开始就在.NET中编写代码,从未遇到过这个问题,也没有读过它。我之前可能偶然发现它,但只是“模糊地注意到”并继续前进。 任何人都可以向我解释这个行为吗?我想知道“为什么”我能做到这一点。请解释,不要只是告诉我规则。我做错了什么?我在C#和VB.NET中都发现了这种行为。代码似乎利用了访问私有变量的能力。缺点是程序员创造了一大块Spaghetti。

此致

  • 完全困惑

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 个答案:

答案 0 :(得分:13)

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

答案 1 :(得分:10)

你说:

  

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

嗯,这是我的两分钱。

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

至于相互操纵的情况,我会承认这有点不寻常。但是以静态构造方法为例。您是否也会限制这些访问实例的私有成员?如果是这样,你就无法提供许多有用的代码。如果没有,则不清楚为什么静态方法应该能够访问私有成员,但实例方法不应该。

换句话说,OOP中的“私人”一词并不意味着传达个人隐私的概念,就像在彼此隐藏的个人中一样。更确切地说,将一个班级视为“仅限会员”类别的俱乐部,其中有某种方式可以做只有俱乐部成员知道的事情。

答案 2 :(得分:1)

访问问题是关于代码访问私有成员的位置,而不是访问它们的内容。

您可以访问_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

答案 3 :(得分:-1)

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

相关问题