有没有办法使值只能由嵌套类 VB.NET 的父级访问?

发布于 2024-07-25 13:56:31 字数 1062 浏览 6 评论 0原文

总的来说,根据OOP范式,我对封装的理解基本上是这样的:

  1. 如果一个成员是私有的,那么它只能被类访问。
  2. 如果成员受保护,则只能由基类和任何派生类访问它。
  3. 如果成员是公开的,则任何人都可以访问。

如果我有一个嵌套类,我可以声明一个属性只能由该类及其嵌套的父类访问吗? 例如:

Public Class ContainerClass
    Public Class NestedClass
        Protected myInt As Integer ' <- this is what I am wondering about '
        Protected myDbl As Double ' <- this is what I am wondering about '

        Sub New()
            myInt = 1
            myDbl = 1.0
        End Sub
    End Class

    Private myNestedObject As New NestedClass

    ' this function is illegal '
    Public Sub GrowNestedObject(ByVal multiplier As Integer)
        myNestedObject.myInt *= multiplier
        myNestedObject.myDbl *= multiplier
    End Sub
End Class

在示例中,如果 myNestedObject.myInt 或 myNestedObject.myDbl 成员是 Private 或 Protected,我无法从 ContainerClass 的实例直接访问这些成员。 但是假设我不想将它们公开,因为这样它们就太暴露了:它们可以从任何地方更改,而不仅仅是在 ContainerClass 对象内。 声明它们为“朋友”仍然太弱,因为这将允许从应用程序中的任何位置更改它们。

有什么办法可以实现我在这里的目标吗? 如果没有,有人能想出更明智的方法来实现这样的目标吗?

In general, according to the OOP paradigm, my understanding of encapsulation basically says:

  1. If a member is private, it can only be accessed by the class.
  2. If a member is protected, it can only be accessed by the base class and any derived classes.
  3. If a member is public, it can be accessed by anyone.

If I have a nested class, can I declare a property to be accessible only to that class and the parent class it's nested within? For example:

Public Class ContainerClass
    Public Class NestedClass
        Protected myInt As Integer ' <- this is what I am wondering about '
        Protected myDbl As Double ' <- this is what I am wondering about '

        Sub New()
            myInt = 1
            myDbl = 1.0
        End Sub
    End Class

    Private myNestedObject As New NestedClass

    ' this function is illegal '
    Public Sub GrowNestedObject(ByVal multiplier As Integer)
        myNestedObject.myInt *= multiplier
        myNestedObject.myDbl *= multiplier
    End Sub
End Class

In the example, I cannot directly access myNestedObject.myInt or myNestedObject.myDbl from an instance of ContainerClass if those members are Private or Protected. But suppose I don't want to make them Public, because then they are TOO exposed: they can be altered from anywhere, not just within a ContainerClass object. Declaring them Friend would still be too weak as that would allow them to be altered from anywhere within the application.

Is there any way to accomplish what I am going for here? If not, can anyone think of a more sensible way to achieve something like this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

凡尘雨 2024-08-01 13:56:31

无法通过辅助功能修饰符的组合直接执行此操作。

我能想到的最好方法如下。 它涉及额外的间接级别。

  • 创建具有私有可访问性的嵌套接口。 这将只给予父类和嵌套子类访问权限
  • 将您想要访问的字段添加到该接口
  • 使嵌套类实现该接口
  • 使所有实现都具有私有可访问性

现在父类并且只有父类才能访问这些字段属性和方法。

例如:

Class Parent
    Private Interface Interface1
        ReadOnly Property Field1() As Integer
    End Interface

    Public Class Nested1
        Implements Interface1

        Private ReadOnly Property Field1() As Integer Implements Interface1.Field1
            Get
                Return 42
            End Get
        End Property
    End Class

    Sub New()
        Dim child As Interface1 = New Nested1
        Dim x = child.Field1
    End Sub
End Class

There is no way of doing this directly with a combination of accessibility modifiers.

The best way I can think of doing this is as follows. It involves an extra level of indirection.

  • Create a Nested Interface with Private accessibility. This will give only the Parent class and nested children access
  • Add the fields you want access to to that interface
  • Make the Nested class implement the interface
  • Make all of the implementations have private accessibility

Now the parent class and only the parent class will have access to those properties and methods.

For Example:

Class Parent
    Private Interface Interface1
        ReadOnly Property Field1() As Integer
    End Interface

    Public Class Nested1
        Implements Interface1

        Private ReadOnly Property Field1() As Integer Implements Interface1.Field1
            Get
                Return 42
            End Get
        End Property
    End Class

    Sub New()
        Dim child As Interface1 = New Nested1
        Dim x = child.Field1
    End Sub
End Class
喵星人汪星人 2024-08-01 13:56:31

根据 JaredPar 的回答,您可以使用 Private ChildClass 但使用仅显示其应显示内容的公共接口:

    Public Class ParentClass

        Public Interface IChildClass
            ReadOnly Property i() As Integer
            Sub SomeSub()
        End Interface

        Private Class ChildClass
           Implements IChildClass
           Public myInt As Integer 

           Public ReadOnly Property i() As Integer Implements IChildClass.i
               Get
                   Return myInt
               End Get
           End Property

           Public Sub SomeSub() Implements IChildClass.SomeSub
           End Sub
        End Class

    Public Shared Function GetNewChild() As IChildClass
        Dim myChild = New ChildClass()
        myChild.myInt = 3
        Return myChild
    End Function
End Class

用法:

Dim c As ParentClass.IChildClass = ParentClass.GetNewChild()
MessageBox.Show(c.i)
c.i = 2 ' Does not compile !
c.SomeSub()

Based on JaredPar's answer, you could use a Private ChildClass but a Public Interface that reveals only what it sould show :

    Public Class ParentClass

        Public Interface IChildClass
            ReadOnly Property i() As Integer
            Sub SomeSub()
        End Interface

        Private Class ChildClass
           Implements IChildClass
           Public myInt As Integer 

           Public ReadOnly Property i() As Integer Implements IChildClass.i
               Get
                   Return myInt
               End Get
           End Property

           Public Sub SomeSub() Implements IChildClass.SomeSub
           End Sub
        End Class

    Public Shared Function GetNewChild() As IChildClass
        Dim myChild = New ChildClass()
        myChild.myInt = 3
        Return myChild
    End Function
End Class

Usage :

Dim c As ParentClass.IChildClass = ParentClass.GetNewChild()
MessageBox.Show(c.i)
c.i = 2 ' Does not compile !
c.SomeSub()
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文