2010-03-10 10 views
5

Tengo curiosidad sobre lo que es una buena práctica cuando se trata de ciertos escenarios que involucran tipos anidados en .NET.Tipos anidados que son públicos

Digamos que tiene una clase de Rueda, y la clase de Rueda tiene objetos de Cojinete. Un objeto Teniendo solo tiene sentido dentro de una Rueda y no desea permitir que se cree de forma independiente, por lo que tendría sentido tener la clase Teniendo anidada dentro del objeto Rueda. Sin embargo, supongamos que tiene un escenario donde ahora necesita leer una propiedad Wheel.Bearings fuera de la clase Wheel. Esto ahora requeriría hacer pública la clase Bearing anidada.

En esta situación, ¿cuál es la mejor opción?
1 - Crear una clase pública Teniendo anidado dentro de la clase de ruedas
2 - Crear una clase de rodamiento independiente que toma un objeto de la rueda en su constructor
3 - Crear un espacio de nombres de ruedas y crear una clase de rodamiento independiente dentro de este espacio de nombres.
4 - ¿Algo más?

ACTUALIZACIÓN: Estoy actualizando esto con más detalles y para reflejar algunas de las sugerencias hasta ahora. ClassParent es la clase principal, ClassChild es la clase infantil. ClassChild es SIEMPRE un hijo de ClassParent, no tiene sentido existir por sí mismo. El problema es que ClassChild tiene algunas propiedades que deben exponerse públicamente, mientras que el resto solo debe invocarse desde ClassParent. Un ejemplo es una función ClassChild.Delete que no debe exponerse públicamente porque solo debe invocarse desde ClassParent ya que ClassParent necesita realizar la limpieza y las modificaciones apropiadas.

Después de revisar las sugerencias, el diseño que he ideado me parece un poco sucio, así que pensé en pedirle su opinión. Tengo:

public class Parent 
{ 
    ChildNested childObj 

    public DeleteChild() 
    { 
     //expose this method publically 
     childObj.DeleteChild() 
     //other functionality 
    } 

    public Child GetChild() 
    { 
     //expose Child, not ChildNested publically 
     return childObj 
    } 

    private class ChildNested:Child 
    { 
     public Child() 
     { 
       Base.Child() 
     } 
     public DeleteChild() 
     { 
       Base.Delete() 
     } 
    } 

public abstract class Child 
{ 
protected Child() 
    { 
    } 
protected Delete() 
    { 
    } 
    public PublicPropertyToExpose() 
    { 
    }  
} 

Respuesta

8

El mejor diseño es crear una clase pública Bearing con un constructor de internal, y crear instancias de ella dentro de la clase Wheel.

Si la clase Bearing necesita tener acceso a los miembros privados de la clase Wheel, puede hacer que la clase pública Bearingabstract, a continuación, hacer una implementació concreto como una clase anidada private interior de Wheel.

En general, you should not make public nested types.

+0

+1. Estoy totalmente de acuerdo. Los tipos anidados son difíciles de leer, difíciles de seguir. Cuando programa contra ellos, siempre necesita especificar el tipo de salida, lo cual es bastante molesto. – Steven

+0

Pero, ¿y si el escenario fuera que Bearing nunca puede y no debería existir sin una rueda? Porque en este caso puedes crear un objeto Bearing sin una rueda. Un ejemplo es una clase de teclado y una clase de clave, nunca se puede tener una clave de teclado sin teclado. –

+0

¿Hay alguna forma de crear una clase que tenga dos (o más) clases públicas derivadas de ella, pero no sea derivable "públicamente", salvo que la clase base sea pública, con un constructor privado y luego tenga las clases derivadas? anidado dentro de ella? Al diseñar las jerarquías de clase, a menudo me encuentro en una esquina donde las cosas que quiero que sean públicas están atrapadas dentro de otras clases. ¿Alguna buena forma de evitar eso, más que darle a las cosas un alcance mayor de lo que realmente quiero? – supercat

1
  • Crear una clase de rodamiento independiente con constructor privado
  • Crear una clase de fábrica que va a crear una instancia de la clase Teniendo dado una clase de ruedas
+0

Alternativamente, tiene un método en la rueda que devuelve un rumbo, digamos "Crear birlar". –

1

me gustaría probar "orientación" de forma independiente, por lo que lo haría ir por la segunda opción.

1

Un rodamiento puede existir por sí mismo, porque probablemente sea lo suficientemente útil para ser utilizado en cualquier parte del mundo, fuera de una rueda.

Una rueda se agrega mediante el uso de rodamientos, pero una rueda no define un rodamiento. Los rodamientos son útiles y pueden usarse en otras cosas además de las ruedas.

El hecho de que necesite una propiedad pública para un Bearing indica que debe ser una clase pública, fuera de Wheel.

Además, ¿qué sucede cuando reinventa la rueda (todos lo hacemos ...). Tal vez use un nuevo "cojinete de aire", como el que existe en las microturbinas, ahora tiene múltiples tipos de cojinetes dentro de la clase Wheel, algunos de los cuales no se utilizan.

Colocaría el rodamiento dentro del mismo espacio de nombres, pero no dentro de la clase Wheel. Rara vez encuentro la necesidad de clases internas. Por lo general, una clase anónima rellena los vacíos que necesito.

Cuestiones relacionadas