2012-06-07 23 views
5

Quiero crear una clase anidada que solo pueda ser visible e instanciada desde la clase padre.
Pero también quiero poder usar una instancia de la clase anidada a través de una variable pública de la clase padre.
Intenté hacer que la clase anidada sea privada o hacer que el constructor de la clase anidada sea privado, pero no se compilará.
¿Es posible hacer esto en .NET?Clases privadas anidadas

Esto compila y funciona, pero la clase anidada puede ser utilizado por cualquier persona:

Public Class OuterClass 
     Public X As Integer = 123 
     Public NestedClassInstance As New NestedClass(Me) 

     Public Class NestedClass 
      Private Parent As OuterClass 

      Public Sub New(ByVal _Parent As OuterClass) 
       Parent = _Parent 
      End Sub 

      Public Sub GetParentX() 
       Debug.WriteLine("X = " & Parent.X.ToString) 
      End Sub 
     End Class 
    End Class 

    Sub Main() 
     Dim OuterClassInstance As New OuterClass 
     OuterClassInstance.NestedClassInstance.GetParentX() 
    End Sub 
+0

Lo único especial de una clase anidada es que puede acceder a los miembros privados y protegidos de la clase que lo contiene (siempre que tenga una referencia a uno). ¿Es esta la funcionalidad de la clase anidada de la que te preocupabas o intentabas hacer otra cosa? –

+0

Principalmente trato de mantener la clase anidada fuera de Intellisense, y también tengo un seguro que no puede ser instanciado excepto por la clase principal. – mcu

+0

Para mí, las definiciones de clases privadas anidadas solo deberían estar disponibles para la clase de retención, de la misma manera que las variables privadas, ya que son privadas para esa clase. Pero si la clase de retención crea una instancia y la asigna a una variable pública dentro de la clase de retención, la instancia debe ser accesible para cualquier persona como campo de la clase de retención. Simplemente parece un comportamiento de objeto muy natural para mí. Oh bien. – mcu

Respuesta

6

Normalmente, la clase anidada privada implementa una interfaz o hereda otra clase, y la clase interfaz/base queda expuesta. Esto es útil cuando desea ocultar la implementación a la clase principal. Algo como esto:

Module EntryPoint 
    Sub Main() 
     Dim OuterClassInstance As New OuterClass 
     OuterClassInstance.NestedClassInstance.GetParentX() 
    End Sub 
End Module 

Public Class OuterClass 
    Public X As Integer = 123 
    Public NestedClassInstance As ISomeImplementation = New NestedClass(Me) 

    Private Class NestedClass 
     Implements ISomeImplementation 
     Private Parent As OuterClass 

     Public Sub New(ByVal _Parent As OuterClass) 
      Parent = _Parent 
     End Sub 

     Public Sub GetParentX() Implements ISomeImplementation.GetParentX 
      Debug.WriteLine("X = " & Parent.X.ToString) 
     End Sub 
    End Class 
End Class 

Public Interface ISomeImplementation 
    Sub GetParentX() 
End Interface 
+0

Eso funciona en su mayor parte, gracias. Solo tiene una deficiencia que encontré. Si la clase anidada tiene campos públicos, no puedo usarlos a través de una interfaz a menos que los implemente como propiedades. – mcu

+0

También moví la interfaz dentro de la clase principal. Lo hizo más autónomo. – mcu

3

No se puede tener una clase anidada privada que también se expone a través de una interfaz pública.

Es una o ambas proposiciones: la clase anidada es privada o no lo es.

Una opción es declarar una interfaz con el contrato que desea que implemente la clase anidada (con algunas herramientas de refactorización puede extraer una interfaz de una clase) y exponer la interfaz, manteniendo la clase anidada en privado.

0

Si usted está tratando de mantener a los clientes la utilización de su objeto fuera de su biblioteca y luego simplemente hacer el constructor friend. De esa forma, solo el código de tu Asamblea puede crear el objeto.

+0

Hmm, traté de usar un constructor privado, pero la clase padre tampoco pudo crear una instancia. – mcu

+0

Use amigo entonces. Editaré mi respuesta. – tcarvin

+0

amigo limita el acceso al conjunto, por lo que puede o no funcionar para el OP –