Si va a utilizar estructuras, es una buena práctica hacerlas inmutables.
Hacer que todos los campos sean solo de lectura es una excelente manera de ayudar a (1) documentar que la estructura es inmutable, y (2) evitar mutaciones accidentales.
Sin embargo, hay una arruga, que en realidad en una extraña coincidencia que estaba planeando en los blogs sobre la próxima semana. Es decir: solo en un campo struct es una mentira. Uno espera que un campo de solo lectura no pueda cambiar, pero por supuesto que sí. "readonly" en un campo struct es la declaración que escribe cheques sin dinero en su cuenta. Una estructura no posee su almacenamiento, y es ese almacenamiento el que puede mutar.
Por ejemplo, tomemos su estructura:
public struct Pair
{
public readonly int x;
public readonly int y;
public Pair(int x, int y)
{
this.x = x;
this.y = y;
}
public void M(ref Pair p)
{
int oldX = x;
int oldY = y;
// Something happens here
Debug.Assert(x == oldX);
Debug.Assert(y == oldY);
}
}
¿Hay algo que le puede pasar a "algo que ocurre aquí" que hace que las afirmaciones de depuración para ser violados? Por supuesto.
public void M(ref Pair p)
{
int oldX = this.x;
int oldY = this.y;
p = new Pair(0, 0);
Debug.Assert(this.x == oldX);
Debug.Assert(this.y == oldY);
}
...
Pair myPair = new Pair(10, 20);
myPair.M(ref myPair);
¿Y ahora qué sucede? ¡La afirmación es violada! "this" y "p" se refieren a la misma ubicación de almacenamiento. La ubicación de almacenamiento está mutada, por lo que los contenidos de "esto" están mutados porque son la misma cosa. La estructura no es capaz de aplicar la función de solo lectura de xey debido a que la estructura no es propietaria del almacenamiento; el almacenamiento es una variable local que puede mutar libremente tanto como lo desee.
No se puede confiar en el invariante que un campo de sólo lectura en una estructura no se observa a cambiar; Lo único en lo que puede confiar es que no puede escribir código que lo cambie directamente. Pero con un pequeño trabajo furtivo como este, puedes cambiarlo indirectamente, todo lo que quieras.
Ver también excelente artículo en el blog de Joe Duffy en este tema:
http://joeduffyblog.com/2010/07/01/when-is-a-readonly-field-not-readonly/
'propiedades readonly'/miembros sólo se pueden establecer desde dentro del constructor (a más tardar). No se pueden establecer con la inicialización de la propiedad sintaxis. –
Es posible que desee comprobar [Tipos inmutables: comprender sus beneficios y usarlos] (http://codebetter.com/patricksmacchia/2008/01/13/immutable-types-understand-them-and-use-them/) – YetAnotherUser
'readonly' solo afecta al operador de asignación. No tiene una semántica tan fuerte como la palabra clave 'const' de C++. –