2010-04-15 7 views
6

He estado mirando a través de un cierto código en un proyecto de código abierto recientemente y encontraron muchas ocurrencias de este tipo de código:C# Copia variable de instancia de variable local en funciones de la misma clase

class SomeClass 
{ 
    private int SomeNumber = 42; 

    public ReturnValue UseSomeNumber(...) 
    { 
     int someNumberCopy = this.SomeNumber; 
     if (someNumberCopy > ...) 
     { 
      // ... do some work with someNumberCopy 
     } 
     else 
     { 
      // ... do something else with someNumberCopy 
     } 
    } 
} 

¿Hay algún beneficio real para hacer una copia de la variable de instancia?

+7

Uno de los beneficios es la seguridad de rosca libre de bloqueo – adrianm

+1

No es típico ver este patrón utilizado para copiar un campo entero, pero veo y uso esto a menudo cuando hago referencia a campos que podrían establecerse como nulos en otro hilo. Es solo una pequeña parte de un diseño seguro para subprocesos, pero esto es importante para evitar condiciones de carrera difíciles de encontrar. –

+1

@Dan: o, para crear condiciones de carrera difíciles de encontrar. Cuando haces una copia, terminas con una raza * diferente *. Ahora la carrera es que la copia está hecha, y luego se cambia el valor original, y ahora la función hace un cálculo sobre datos obsoletos. –

Respuesta

7

No, a menos que no desee cambiar el valor de SomeNumber y tenga la intención de actualizar someNumberCopy. Como si fuera a repetir el número de veces e hiciera decrecer algunaNumberCopy a cero para hacer un seguimiento del recuento.

Supongo que copiar la variable de esa manera podría protegerlo de alguna función externa que modifique SomeNumber y la cambie sin su conocimiento mientras realiza una operación. Podría ver esto si se supone que la clase debe usarse en una aplicación de subprocesos múltiples. Tal vez no de la forma en que lo haría, pero podría haber sido la intención del autor.

0

La única ventaja que veo es por tener una "versión de sólo lectura" de la variable sólo para ese método

0

no. deja este trabajo para el optimizador.

1

¿El // ... do some work with someNumberCopy está haciendo algo con someNumberCopy? ¿Está cambiando el valor? ¿Se está transfiriendo a un método que podría cambiar el valor?

De lo contrario, no, no hay ningún beneficio.

9

Posiblemente esto es parte del programa de subprocesos múltiples. Aunque este código no es seguro para subprocesos, garantiza que una vez que se asigna la variable de copia, no se modifique por otros subprocesos, y todo el código de función después de esto se ejecuta de forma coherente.

código similar con los eventos se vuelve crítica en el entorno multi-hilo:

 
MyEvent e = this.myEvent; 

if (e != null) 
{ 
    e(); 
} 

Aquí, sin hacer una copia local, es posible conseguir una excepción nula-puntero, si el evento será nulo después de evaluar la nula, y antes de invocar

+0

Ni siquiera pensé en el hilo múltiple cuando estaba mirando el código, así que gracias por tu respuesta. Ahora que lo he visto ahora, resulta que el uso real es que la variable de instancia ya es de solo lectura y establecida por el constructor, y el valor no se cambia. Ahora me parece que esto se puede haber hecho para cambiar el nombre de la variable para que el código sea más fácil de leer. –

1

Olvidó algunos detalles importantes.
Si tiene varios hilos con el acceso y someNumber este escenario:

int someNumberCopy = this.SomeNumber; 
    if (someNumberCopy > x) 
    { 
     // do some work with someNumberCopy 
     // that relies on (someNumberCopy > x) == true 
    } 

entonces es importante hacer una copia.

1

Podría ser útil si this.SomeNumber pueden ser modificados por otro hilo, pero durante la duración de este método es de vital importancia que el someNumberCopy no se puede cambiar (que puede estar fuera de sincronía con SomeNumber), entonces esto podría ser viable, de lo contrario No veo una razón para eso.

Cuestiones relacionadas