Andrew es correcto; Me limitaré a agregar un par de detalles adicionales.
En primer lugar, la forma correcta de pensar en los parámetros out/ref es que son alias para las variables. Es decir, cuando tiene un método M (ref int q) y lo llama M (ref x), q y x son dos nombres diferentes para exactamente la misma variable. Una variable es una ubicación de almacenamiento; usted almacena algo en q, también lo está almacenando en x, porque son dos nombres diferentes para la misma ubicación.
En segundo lugar, la alternativa que está describiendo se denomina referencia de "copiado/copiado". En este esquema, hay dos ubicaciones de almacenamiento y el contenido de una se copia al inicio de la llamada de función, y se copia de nuevo cuando termina. Como observa, la semántica de copiar-en-copiar-salir es diferente de la semántica de las referencias de alias cuando se lanzan excepciones.
También son diferentes en situaciones extrañas como esta:
void M(ref int q, ref int r)
{
q = 10;
r = 20;
print (q);
}
...
M(ref x, ref x);
En aliasing, X, Q y R son todos iguales ubicación de almacenamiento, por lo que este imprime 20. En copy-in-copia-afuera referencia , esto imprimiría 10, y el valor final de x dependería de si la copia fue de izquierda a derecha o de derecha a izquierda.
Finalmente, si mal no recuerdo, existen situaciones raras y extrañas en la implementación de árboles de expresiones donde implementamos la semántica de copia en la copia en parámetros de ref. Debería revisar ese código y ver si puedo recordar exactamente cuáles son esos escenarios.
Hmm ... eso no es lo que esperaba, ¡pero la prueba lo confirma! +1. –
Esta es información útil. : O – Sapph
Recuerdo micro-optimizar un método que recibió un parámetro 'out'. El método fue llamado en un bucle muy cerrado y quería eliminar la inicialización requerida cada vez que se llamaba, ya que el parámetro no cambiaba, así que hice que tomara un parámetro 'ref' y funcionó de manera mensurable peor. ¿Alguien tiene una explicación para esto, o fue un golpe de suerte? – JulianR