¿Podría explicar cuál es el uso práctico de la internal
palabra clave en C #?
Sé que el internal
modificador limita el acceso al ensamblaje actual, pero ¿cuándo y en qué circunstancias debo usarlo?
fuente
¿Podría explicar cuál es el uso práctico de la internal
palabra clave en C #?
Sé que el internal
modificador limita el acceso al ensamblaje actual, pero ¿cuándo y en qué circunstancias debo usarlo?
Utilidad o clases / métodos auxiliares a los que le gustaría acceder desde muchas otras clases dentro del mismo ensamblado, pero que desea garantizar que el código en otros ensamblados no pueda acceder.
Desde MSDN (a través de archive.org):
Un uso común del acceso interno es el desarrollo basado en componentes porque permite que un grupo de componentes coopere de manera privada sin estar expuesto al resto del código de la aplicación. Por ejemplo, un marco para construir interfaces gráficas de usuario podría proporcionar clases de Control y Formulario que cooperen usando miembros con acceso interno. Como estos miembros son internos, no están expuestos al código que usa el marco.
También puede usar el modificador interno junto con el InternalsVisibleTo
atributo de nivel de ensamblaje para crear ensamblajes "amigos" que tengan acceso especial a las clases internas del ensamblado de destino.
Esto puede ser útil para la creación de conjuntos de prueba de unidad que luego se les permite llamar a los miembros internos del conjunto para que se prueben. Por supuesto, a ningún otro ensamblado se le otorga este nivel de acceso, por lo que cuando libera su sistema, se mantiene la encapsulación.
Si Bob necesita BigImportantClass, entonces Bob debe hacer que las personas que poseen el proyecto A se inscriban para garantizar que BigImportantClass se escriba para satisfacer sus necesidades, se pruebe para garantizar que satisfaga sus necesidades, se documente como un cumplimiento de sus necesidades y que ese proceso se implementará para garantizar que nunca se cambie y que ya no satisfaga sus necesidades.
Si una clase es interna, entonces no tiene que pasar por ese proceso, lo que ahorra presupuesto para el Proyecto A que pueden gastar en otras cosas.
El punto interno no es que le haga la vida difícil a Bob. Es que le permite controlar las costosas promesas que hace el Proyecto A sobre características, duración, compatibilidad, etc.
fuente
Otra razón para usar interno es si ofuscas tus binarios. El ofuscador sabe que es seguro codificar el nombre de la clase de cualquier clase interna, mientras que el nombre de las clases públicas no se puede codificar, porque eso podría romper las referencias existentes.
fuente
Si está escribiendo una DLL que encapsula una tonelada de funcionalidades complejas en una API pública simple, entonces se utiliza "interno" en los miembros de la clase que no deben exponerse públicamente.
Ocultar la complejidad (también conocida como encapsulación) es el concepto principal de la ingeniería de software de calidad.
fuente
La palabra clave interna se usa mucho cuando está creando un contenedor sobre código no administrado.
Cuando tiene una biblioteca basada en C / C ++ que desea importar, puede importar estas funciones como funciones estáticas de una clase y hacerlas internas, de modo que su usuario solo tenga acceso a su contenedor y no a la API original para que no pueda meterse con cualquier cosa. Como las funciones son estáticas, puede usarlas en todas partes del ensamblaje, para las múltiples clases de envoltura que necesita.
Puede echar un vistazo a Mono.Cairo, es un contenedor alrededor de la biblioteca de El Cairo que utiliza este enfoque.
fuente
Siendo impulsado por la regla de "usar el modificador tan estricto como pueda", uso el interno en todas partes donde necesito acceder, por ejemplo, al método de otra clase hasta que explícitamente necesito acceder a él desde otro ensamblado.
Como la interfaz de ensamblaje suele ser más estrecha que la suma de sus interfaces de clases, hay muchos lugares donde la uso.
fuente
Encuentro interno que está muy usado en exceso. realmente no debería exponer ciertas funciones solo a ciertas clases que no haría a otros consumidores.
Esto en mi opinión rompe la interfaz, rompe la abstracción. Esto no quiere decir que nunca se debe usar, pero una mejor solución es refactorizar a una clase diferente o usar de una manera diferente si es posible. Sin embargo, esto puede no ser siempre posible.
La razón por la que puede causar problemas es que otro desarrollador puede ser acusado de construir otra clase en el mismo ensamblado que el suyo. Tener elementos internos disminuye la claridad de la abstracción y puede causar problemas si se usa incorrectamente. Sería el mismo problema que si lo hicieras público. La otra clase que está desarrollando el otro desarrollador sigue siendo un consumidor, al igual que cualquier clase externa. La abstracción de clases y la encapsulación no son solo para protección para / de clases externas, sino para todas y cada una de las clases.
Otro problema es que muchos desarrolladores pensarán que pueden necesitar usarlo en otra parte del ensamblaje y marcarlo como interno de todos modos, aunque no lo necesiten en ese momento. Otro desarrollador puede pensar que está ahí para tomar. Por lo general, desea marcar privado hasta que tenga una necesidad definitiva.
Pero algo de esto puede ser subjetivo, y no digo que nunca deba usarse. Solo use cuando sea necesario.
fuente
Vi uno interesante el otro día, tal vez una semana, en un blog que no recuerdo. Básicamente no puedo tomar crédito por esto, pero pensé que podría tener alguna aplicación útil.
Digamos que desea que otra clase vea una clase abstracta pero que no desea que alguien pueda heredar de ella. Sellado no funcionará porque es abstracto por una razón, otras clases en ese ensamblado heredan de él. Privado no funcionará porque es posible que desee declarar una clase Parent en algún lugar del otro ensamblado.
Como puede ver, efectivamente permite que alguien use la clase Parent sin poder heredar.
fuente
Este ejemplo contiene dos archivos: Assembly1.cs y Assembly2.cs. El primer archivo contiene una clase base interna, BaseClass. En el segundo archivo, un intento de instanciar BaseClass producirá un error.
En este ejemplo, use los mismos archivos que usó en el ejemplo 1 y cambie el nivel de accesibilidad de BaseClass a público . También cambie el nivel de accesibilidad del miembro IntM a interno . En este caso, puede crear una instancia de la clase, pero no puede acceder al miembro interno.
fuente : http://msdn.microsoft.com/en-us/library/7c5ka91b(VS.80).aspx
fuente
Cuando tiene métodos, clases, etc. que deben ser accesibles dentro del alcance del ensamblaje actual y nunca fuera de él.
Por ejemplo, un DAL puede tener un ORM pero los objetos no deben exponerse a la capa empresarial, toda interacción debe hacerse a través de métodos estáticos y pasar los parámetros requeridos.
fuente
Un uso muy interesante de interno, con el miembro interno limitado, por supuesto, solo al conjunto en el que se declara, es obtener la funcionalidad de "amigo" hasta cierto punto. Un miembro amigo es algo que solo es visible para ciertos otros conjuntos fuera del conjunto en el que se declara. C # no tiene soporte incorporado para amigo, sin embargo, el CLR sí.
Puede usar InternalsVisibleToAttribute para declarar una asamblea de amigos, y todas las referencias dentro de la asamblea de amigos tratarán a los miembros internos de su asamblea declarante como públicos dentro del alcance de la asamblea de amigos. Un problema con esto es que todos los miembros internos son visibles; No puedes escoger y elegir.
Un buen uso para InternalsVisibleTo es exponer a varios miembros internos a un conjunto de prueba de unidad, eliminando así la necesidad de complejos trabajos de reflexión para probar esos miembros. Que todos los miembros internos sean visibles no es un gran problema, sin embargo, adoptar este enfoque ensucia mucho las interfaces de su clase y puede arruinar la encapsulación dentro del conjunto de declaración.
fuente
Como regla general, hay dos tipos de miembros:
fuente
Reducción de ruido, cuantos menos tipos expongas, más simple será tu biblioteca. La prueba de manipulación / seguridad es otra (aunque Reflection puede ganar contra ella).
fuente
Las clases internas le permiten limitar la API de su ensamblaje. Esto tiene beneficios, como hacer que su API sea más fácil de entender.
Además, si existe un error en su ensamblaje, hay menos posibilidades de que la solución introduzca un cambio importante. Sin clases internas, debería asumir que cambiar los miembros públicos de cualquier clase sería un cambio radical. Con las clases internas, puede suponer que modificar sus miembros públicos solo rompe la API interna del ensamblado (y cualquier ensamblado al que se haga referencia en el atributo InternalsVisibleTo).
Me gusta tener encapsulación a nivel de clase y a nivel de ensamblado. Hay algunos que no están de acuerdo con esto, pero es bueno saber que la funcionalidad está disponible.
fuente
Tengo un proyecto que usa LINQ-to-SQL para el back-end de datos. Tengo dos espacios de nombres principales: Biz y Data. El modelo de datos LINQ vive en datos y está marcado como "interno"; el espacio de nombres Biz tiene clases públicas que se ajustan a las clases de datos LINQ.
Entonces hay
Data.Client
, yBiz.Client
; este último expone todas las propiedades relevantes del objeto de datos, por ejemplo:Los objetos Biz tienen un constructor privado (para forzar el uso de métodos de fábrica) y un constructor interno que se ve así:
Puede ser utilizado por cualquiera de las clases de negocios en la biblioteca, pero el front-end (UI) no tiene forma de acceder directamente al modelo de datos, asegurando que la capa de negocios siempre actúe como intermediario.
Esta es la primera vez que realmente uso
internal
mucho, y está resultando bastante útil.fuente
Hay casos en los que tiene sentido formar miembros de clases
internal
. Un ejemplo podría ser si desea controlar cómo se instancian las clases; supongamos que proporciona algún tipo de fábrica para crear instancias de la clase. Puede hacer el constructorinternal
, de modo que la fábrica (que reside en el mismo ensamblaje) pueda crear instancias de la clase, pero el código fuera de ese ensamblaje no.Sin embargo, no veo ningún punto en hacer clases o miembros
internal
sin razones específicas, tan poco como tenga sentido hacerlaspublic
, oprivate
sin razones específicas.fuente
Lo único en lo que he usado la palabra clave interna es en el código de verificación de licencia de mi producto ;-)
fuente
Un uso de la palabra clave interna es limitar el acceso a implementaciones concretas del usuario de su ensamblaje.
Si tiene una fábrica u otra ubicación central para construir objetos, el usuario de su ensamblaje solo necesita tratar con la interfaz pública o la clase base abstracta.
Además, los constructores internos le permiten controlar dónde y cuándo se instancia una clase pública.
fuente
Qué tal este: por lo general, se recomienda que no exponga un objeto List a usuarios externos de un ensamblado, sino que exponga un IEnumerable. Pero es mucho más fácil usar un objeto List dentro del ensamblado, porque obtienes la sintaxis de la matriz y todos los demás métodos List. Por lo tanto, normalmente tengo una propiedad interna que expone una Lista para usar dentro del ensamblaje.
Se agradecen los comentarios sobre este enfoque.
fuente
Tenga en cuenta que cualquier clase definida como
public
se mostrará automáticamente en el intellisense cuando alguien mira el espacio de nombres de su proyecto. Desde una perspectiva API, es importante mostrar solo a los usuarios de su proyecto las clases que pueden usar. Use lainternal
palabra clave para ocultar cosas que no deberían ver.Si su
Big_Important_Class
proyecto A está destinado a usarse fuera de su proyecto, entonces no debe marcarlointernal
.Sin embargo, en muchos proyectos, a menudo tendrá clases que en realidad solo están destinadas a usarse dentro de un proyecto. Por ejemplo, puede tener una clase que contenga los argumentos de una invocación de subproceso parametrizada. En estos casos, debe marcarlos como
internal
si no fuera por otra razón que para protegerse de un cambio de API no deseado en el futuro.fuente
private
palabra clave solo se puede usar en clases o estructuras que se definen dentro de otra clase o estructura. Una clase definida dentro de un espacio de nombres solo se puede declararpublic
ointernal
.La idea es que, cuando diseñe una biblioteca, solo las clases destinadas a ser utilizadas desde el exterior (por los clientes de su biblioteca) deben ser públicas. De esta manera puedes ocultar clases que
etc.
Supongo que si está desarrollando soluciones internas, el uso de elementos internos no es tan importante, porque generalmente los clientes tendrán contacto constante con usted y / o acceso al código. Sin embargo, son bastante críticos para los desarrolladores de bibliotecas.
fuente
Cuando tiene clases o métodos que no encajan perfectamente en el Paradigma orientado a objetos, que hacen cosas peligrosas, que deben ser llamadas desde otras clases y métodos bajo su control, y que no desea que nadie más use .
fuente