variable enum define constantes constant .net language-design library-design

.net - define - enum c#



¿Dónde están los readonly/const en.NET? (5)

He notado una buena cantidad de parámetros usando struct.

Una cosa que vale la pena mencionar aquí es que C # exagera la diferencia entre estructura y clase en comparación con C ++, al exagerar la diferencia entre los tipos de valor y los tipos de referencia. En C #, todas las clases son tipos de referencia y todas las estructuras son tipos de valor. En .Net, todo se pasa por valor de forma predeterminada.

El resultado de esta distinción para los tipos de valor es que todos los tipos de valor se copian cuando se pasan a una función. Si pasa una estructura a una función, se le garantiza que la función no cambiará su estructura original porque la función solo funciona con una copia. Agregar const a tal parámetro es tonto.

Los tipos de referencia también se pasan por valor. O, más específicamente, la referencia en sí misma se pasa por valor. Así que tienes una copia de la referencia, pero apunta (se refiere a) el mismo objeto. Por lo tanto, los cambios realizados en el objeto por la función persistirán después de que la función finalice.

En superficie, agregar una opción const , al menos para los tipos de referencia, parece una buena idea. Donde se pone un poco turbio es con efectos secundarios. O, mejor dicho, ¿cómo se aplica esto? Obviamente, es bastante fácil decir que su código no puede usar los generadores de propiedades. Pero ¿qué pasa con otros métodos? Cualquier método de llamada podría necesitar cambiar el objeto. Incluso los captadores de propiedades pueden tener un efecto secundario que cambia algo (supongamos que implementas una función de seguridad para tener en cuenta cuando se accedió a algo por última vez). ¿Vas a negar el acceso de lectura a una propiedad debido al efecto secundario?

En C ++ verá void func(const T& t) todas partes. Sin embargo, no he visto nada similar en .NET. ¿Por qué?

He notado una buena cantidad de parámetros usando struct. Pero no veo funciones con readonly / const. De hecho, ahora que lo probé, no pude usar esas palabras clave para hacer una función que prometa no modificar una lista que se pasa. ¿No hay forma de prometer a la persona que llama que esta función nunca modificará el contenido de la lista? ¿No hay forma de decir que llame al código y diga que esta lista nunca debe modificarse? (Sé que puedo clonar la lista o consultar la documentación, pero me gusta compilar errores en algún momento)



El problema es que la corrección const tal como se usa en C / C ++ solo es impuesta por el compilador. Y fácilmente evitado por cierto. El CLR realmente hace cumplir la seguridad de tipos en el código administrado, no en el compilador. Necesariamente porque el .NET Framework es compatible con muchos idiomas. El sistema de tipos y las reglas de interacción se establecen en el CLI, una infraestructura de lenguaje común que necesita servir a muchos objetivos y maestros.

La corrección de const es rara en los idiomas actuales. Personalmente, solo conozco C ++, un lenguaje que no se traslada a la CLI. Hacer cumplir las reglas en lenguajes que no tienen nada que ver con la sintaxis es difícil. Algo tan simple como los tipos integrales sin firmar que no estaban en el CLS dejaron una marca notable en el diseño de los ensamblajes de la base.

La inmutabilidad (real, no falsificada con un compilador) mantiene a los equipos de MSFT pensando. Es popular, sé que el equipo de C # lo ha estado pensando. Bueno para la concurrencia, etcétera. Eric Lippert hizo una serie de publicaciones de blog de 11 partes , aunque se desvaneció un poco. Demasiado grande para un chico y su audiencia. Si habrá un movimiento real para implementarlo, confío en que lo analicen y lo hagan funcionar. Algún día. Un poco de lenguaje


No hay ningún modificador const para los parámetros del método en C #. Si desea tener algo similar a const garantiza que puede usar tipos inmutables en sus interfaces. Por ejemplo, un método puede aceptar un IEnumerable<T> lugar de un tipo de colección mutable. También puede consultar ReadOnlyCollection .


La inmutabilidad sigue siendo un área donde C # está madurando. Hasta ahora, C # no ha adoptado la semántica const de C ++ ... que en realidad creo que es algo bueno. El comportamiento de const en C ++ a menudo dificultaba el diseño de jerarquías de clase que funcionaran de la manera que usted quería. No era raro ver el código salpicado con const_cast<> para eludir la constness donde no era deseable. Con suerte, los diseñadores de C # inventarán una alternativa más simple pero todavía expresiva.

En la actualidad, no hay ninguna característica de lenguaje que marque los parámetros u objetos pasados ​​a los métodos como inmutables. Lo mejor que puedes hacer es pasar un objeto usando una interfaz (o mejor aún un contenedor) que solo permite operaciones de lectura.

Para algunas de las colecciones estándar en .NET, puede usar el contenedor ReadOnlyCollection , que encapsuló cualquier tipo de colección ICollection mutable dentro de un contenedor de solo lectura.

La creación de tipos inmutables requiere planificación y conocimiento de las características del lenguaje. Por ejemplo, la palabra clave readonly es tu amigo. Le permite declarar miembros de una clase o estructura como inmutables. Desafortunadamente, esta inmutabilidad solo se aplica a la referencia, no a los miembros del objeto referenciado. Lo que esto significa es que puedes declarar:

private readonly int[] m_Values = new int[100]; public void SomeMethod() { m_Values = new int[50]; // illegal, won''t compile! m_Values[10] = 42; // perfectly legal, yet undesirable }

En el ejemplo anterior, la referencia a la matriz es inmutable, pero los elementos individuales de la matriz no lo son. Este comportamiento se extiende más allá de las matrices, por supuesto.

Una práctica que me ha resultado útil al diseñar tipos inmutables, es separar el comportamiento inmutable en su propia interfaz, que luego es implementada por una clase que administra los datos. La interfaz solo expone las propiedades de obtención y los métodos que están garantizados para no mutar el estado del objeto. Entonces es posible pasar instancias de su tipo a métodos como parámetros de ese tipo de interfaz. Esta es una forma débil de soporte de inmutabilidad, ya que el método llamado a menudo puede convertir la referencia al tipo mutable . Una alternativa mejor, pero más engorrosa, es crear una implementación de envoltura que implemente la misma interfaz y mantenga una referencia a la instancia real (como hace ReadOnlyCollection ). Esto es más trabajo pero proporciona una garantía más fuerte para la inmutabilidad.

El enfoque que elija utilizar depende de qué tan importantes sean las garantías de inmutabilidad y cuánto tiempo y esfuerzo esté dispuesto a gastar para llegar allí.

Si está interesado en leer más sobre este tema, Eric Lippert tiene una excelente serie de artículos sobre la inmutabilidad en C # .