En .NET, un método de instancia estructura es semánticamente equivalente a un método estático con una estructura ref
un parámetro adicional de la estructura tipo. Por lo tanto, teniendo en cuenta las declaraciones:
struct Blah {
public int value;
public void Add(int Amount) { value += Amount; }
public static void Add(ref Blah it; int Amount; it.value += Amount;}
}
El método llama:
someBlah.Add(5);
Blah.Add(ref someBlah, 5);
son semánticamente equivalentes, excepto por una diferencia: solamente se permitirá a esta última llamada si someBlah
es una ubicación de almacenamiento mutable (variable, campo, etc.) y no si se trata de una ubicación de almacenamiento de solo lectura, o un valor temporal (resultado de leer una propiedad, etc.).
Esto enfrentó a los diseñadores de lenguajes .NET con un problema: no permitir el uso de cualquier función miembro en las estructuras de solo lectura sería molesto, pero no querían permitir que las funciones miembro escribieran a las variables de solo lectura. Decidieron "punt", y lo hacen de modo que llamar a un método de instancia en una estructura de solo lectura hará una copia de la estructura, invocar la función sobre eso y luego descartarla. Esto tiene el efecto de ralentizar llamadas a métodos de instancia que no escriben la estructura subyacente, y hacer que un intento de utilizar un método que actualice la estructura subyacente en una estructura de solo lectura produzca semántica rota diferente de lo que se lograría si se pasa la estructura directamente. Tenga en cuenta que el tiempo extra tomado por la copia casi nunca arrojará la semántica correcta en casos que no hubieran sido correctos sin la copia.
Uno de mis principales problemas en .net es que todavía hay (al menos 4.0, y probablemente 4.5) todavía ningún atributo a través del cual una función de miembro de estructura puede indicar si modifica this
.La gente discute sobre cómo las estructuras deberían ser inmutables, en lugar de proporcionar las herramientas para permitir que las estructuras ofrezcan métodos de mutación seguros. Esto, a pesar del hecho de que las llamadas estructuras "inmutables" son una mentira. Todos los tipos de valores no triviales en ubicaciones de almacenamiento mutables son mutables, como todos los tipos de valores encuadrados. Hacer una estructura "inmutable" puede obligar a uno a reescribir una estructura completa cuando uno solo quiere cambiar un campo, pero desde struct1 = struct2
muta struct1 copiando todos los campos públicos y privados de struct2, y no hay nada que sea la definición de tipo para la estructura puede hacer para evitar que (excepto que no tenga ningún campo) no haga nada para evitar una mutación inesperada de los miembros de la estructura. Además, debido a problemas de enhebrado, las estructuras tienen una capacidad muy limitada para imponer cualquier tipo de relación invariable entre sus campos. En mi humilde opinión, generalmente sería mejor para una estructura permitir el acceso arbitrario al campo, dejando en claro que cualquier código que reciba una estructura debe verificar si sus campos cumplen con todas las condiciones requeridas, en lugar de tratar de evitar la formación de estructuras que no cumplan con las condiciones.
Ver Eric Lippert ["Mutating Readonly Structs"] (http://blogs.msdn.com/b/ericlippert/archive/2008/05/14/mutating-readonly-structs.aspx) –
* ¿Por qué? esperar dos 1s? Dijiste que querías que fuera de solo lectura, ¿por qué quieres que cambie? –