2008-09-20 16 views
40

Soy un nuevo desarrollador de C# y .Net. Recientemente, creé un snap de MMC con C# y me gustó lo fácil que fue hacerlo, especialmente después de escuchar muchas historias de terror de otros desarrolladores de mi organización sobre lo difícil que es hacer en C++.¿Debo usar visibilidad interna o pública de forma predeterminada?

Prácticamente pasé por todo el proyecto en algún momento e hice que cada instancia de la palabra clave "pública" fuera "interna", salvo que el runtime lo requiriera para ejecutar el snapin. ¿Cuál es su sensación al respecto, si generalmente las clases y los métodos son públicos o internos?

Respuesta

35

Creo en blackboxes cuando sea posible. Como programador, quiero un blackbox bien definido que pueda ingresar fácilmente en mis sistemas y hacer que funcione. Le doy valores, llamo a los métodos apropiados y luego obtengo mis resultados.

Para ese fin, deme solo la funcionalidad que la clase necesita para exponer al trabajo.

Considere un ascensor. Para que se vaya al piso, presiono un botón. Esa es la interfaz pública para la caja negra que activa todas las funciones necesarias para llevar el ascensor al piso deseado.

+0

+1 para una gran analogía. –

+0

además de eso, no se activó antes de llamar ;-) – izbrannick

0

Depende de la cantidad de control que tenga sobre el código que lo consume. En mi desarrollo de Java, hago que todas mis cosas sean públicas por defecto porque los getters son molestos. Sin embargo, también tengo el lujo de poder cambiar cualquier cosa en mi base de código cuando quiera. En el pasado, cuando tuve que liberar el código para los consumidores, siempre he usado variables privadas y getters.

1

Debe tender a exponer lo menos posible a otras clases, y pensar cuidadosamente acerca de lo que expone y por qué.

0

No elija una selección "predeterminada" que mejor se adapte a las necesidades de visibilidad para esa clase en particular. Cuando se elige una nueva clase en Visual Studio, la plantilla se crea como:

class Class1 
{ 
} 

que es privada (ya que no se especifica el ámbito de aplicación). Depende de usted especificar el alcance de la clase (o dejarla como privada). Debe haber una razón para exponer la clase.

+0

¿En qué circunstancias elegiría interna, pública o privada? ¿Qué necesidades particulares pueden influenciarlo para elegir uno? –

+0

interno y privado son idénticos para clases no anidadas, hasta donde yo sé: ambos son visibles solo para todo el conjunto. (¿o hace una diferencia al usar el atributo InternalsVisibleTo?) – Tobi

+5

"Los tipos de nivel superior, que no están anidados en otros tipos, solo pueden tener acceso interno o público. La accesibilidad predeterminada para estos tipos es interna". (http://msdn.microsoft.com/en-us/library/ba0a1yw2.aspx) – Auron

0

Me gusta exponer las cosas lo menos posible. Privado, protegido, interno, público: dé a las clases, variables, propiedades y funciones la menor cantidad de visibilidad que necesitan para que todo funcione.

Voy a poner algo de visibilidad en esa cadena hacia el público solo cuando haya una buena razón para hacerlo.

4

Prefiero evitar las clases de marcado como public a menos que explícitamente quiera que mi cliente las consuma, y ​​estoy dispuesto a apoyarlas.

En lugar de marcar una clase como internal, dejo la accesibilidad en blanco. De esta manera, public se destaca a la vista como algo notable. (La excepción, por supuesto, son las clases anidadas, que deben marcarse para que sean visibles incluso en el mismo ensamblaje).

7

Creo que debe pecar de parte de las clases y miembros internos. Siempre puede aumentar la visibilidad de un elemento pero disminuirlo puede causar problemas. Esto es especialmente cierto si está construyendo un marco para otros.

Sin embargo, debe tener cuidado para no ocultar la funcionalidad útil de sus usuarios. Hay muchos métodos útiles en .NET BCL que no se pueden usar sin recurrir a la reflexión.Sin embargo, al ocultar estos métodos, se reduce el área superficial de lo que se debe probar y mantener.

1

¿Hay alguna razón por la que necesite usar Internal en lugar de Private? Se da cuenta de que Internal tiene alcance de nivel de ensamblaje. En otras palabras, las clases/miembros internos son accesibles para todas las clases en un conjunto de clases múltiples.

Como han dicho otras respuestas, en general, obtenga el nivel de encapsulación más alto posible (es decir, privado) a menos que realmente necesite interno/protegido/público.

11

Lo que hizo es exactamente lo que debe hacer; brinde a sus clases la visibilidad más mínima posible. Diablos, si realmente quiere ir por completo, puede hacer todointernal (como máximo) y usar InternalsVisibleTo attribute, para que pueda separar su funcionalidad pero no exponerla al mundo exterior desconocido.

La única razón para hacer las cosas públicas es que está envasado de su proyecto en varios archivos DLL y/o EXE y (por cualquier razón) no le importa usar InternalsVisibleTo, o va a crear una biblioteca para su uso por terceros. Pero incluso en una biblioteca para uso de terceros, debe intentar reducir el "área de superficie" siempre que sea posible; Cuantas más clases tenga disponibles, más confusa será su biblioteca.

En C#, una buena manera de asegurarse de que está utilizando la mínima visibilidad posible es dejar de lado los modificadores de visibilidad hasta que los necesite. Todo en C# se predetermina a la menor visibilidad posible: interna para las clases y privada para los miembros de la clase y las clases internas.

1

Encontré un problema utilizando las clases internas tanto como sea posible. No puede tener los métodos, propiedades, campos, etc. de ese tipo (o tipo de parámetro o tipo de devolución) más visibles que los internos. Esto lleva a tener constructores que son internos, así como propiedades. Esto no debería ser un problema, pero de hecho, al usar Visual Studio y el diseñador xaml, hay problemas. El diseñador ha detectado errores falsos positivos debido a que los métodos no son públicos, las propiedades de control del usuario no parecen visibles para el diseñador. No sé si otros ya han tenido problemas como este ...

+1

Esto está mal. Puede tener métodos y propiedades públicos en una clase interna; de hecho, es recomendado por muchas personas. – kjbartel

1

Debe tratar de hacerlos lo más visibles posible, pero como dice Mike arriba, esto causa problemas con UserControls y el uso del Diseñador VS con esos controles en formularios u otros UserControls.

Por lo tanto, como regla general, mantenga todas las clases y UserControls que no esté agregando usando el Diseñador solo tan visible como sea necesario. Si está creando un UserControl que desea usar en el Diseñador (incluso si está dentro del mismo ensamblaje) necesitará asegurarse de que la clase UserControl, su constructor por defecto y cualquier propiedad y evento se hagan públicos para el diseñador. para trabajar con eso

Tuve un problema recientemente donde el diseñador seguiría eliminando la línea this.myControl = new MyControl() del método InitializeComponent() porque UserControl MyControl se marcó como interno junto con su constructor.

Realmente es un error, porque aunque estén marcados como internos, todavía se muestran en la Caja de herramientas para agregarlos en el Diseñador, ya sea que Microsoft solo necesita mostrar controles públicos con constructores públicos, o necesitan hacerlo funcionar con controles internos también.

0

Estoy completamente en desacuerdo con las respuestas hasta el momento. Siento que interna es una idea horrible, que impide que otro ensamblaje herede tus tipos, o incluso que uses tus tipos internos si surge la necesidad de una solución alternativa.

Hoy, tuve que usar la reflexión para llegar al interior de un System.Data.DataTable (tengo que construir un rayo de tabla de datos rápido, sin todas sus comprobaciones), y tuve que usar el reflejo, ya que ni un solo tipo estaba disponible para mí; todos fueron marcados como internos.

+1

'interno' existe para que los proveedores de API (como MS) puedan escribir clases sin preocuparse por extraños al azar que usan su código. Cada vez que una API se hace pública, el proveedor ya no puede cambiar fácilmente las firmas. Cuando 'interno ', si MS elige, pueden cambiar su código sin temor a romper el código de otras personas. Es decir, a menos que estén usando la reflexión para "engañar". –

+0

Afirmo que puede hacer lo mismo con los miembros privados y protegidos para que al menos cuando (y digo "cuando", no "si") alguien se sumerja, pueden usar tipeo fuerte en lugar de reflexión. –

+1

@Pedar, ¿cómo es que el uso de 'private' hace que sea más fácil usar una tipificación fuerte en lugar de una reflexión? 'private' es incluso ** menos ** accesible que' interno'. Y si usa 'protected', ahora forma parte del ** contrato ** de la API y MS tendrá prohibido cambiarlo. Creo que ignoró ese punto que hice. –

2

La mayoría de las clases deben ser internal, pero la mayoría de los miembros no privados deben ser public.

La pregunta que debe hacer acerca de un miembro es "si la clase se creó public ¿me gustaría que el miembro sea expuesto?". La respuesta suele ser "sí" (así que public) "porque las clases sin ningún miembro accesible no son de mucha utilidad. internal miembros tienen un rol; son 'acceso de puerta trasera' destinado solo a parientes cercanos que viven en la misma asamblea.

Incluso si su clase sigue siendo interna, es bueno ver cuáles son los miembros de la puerta delantera y cuáles están detrás de la puerta. Y si alguna vez lo cambias a público no vas a tener que volver y pensar cuáles son cuáles.

Cuestiones relacionadas