En C #, siempre he pensado que las variables no primitivas se pasan por referencia y los valores primitivos se pasan por valor.
Entonces, al pasar a un método cualquier objeto no primitivo, cualquier cosa que se haga al objeto en el método afectaría al objeto que se pasa. (C # 101 cosas)
Sin embargo, he notado que cuando paso un objeto System.Drawing.Image, ¿este no parece ser el caso? Si paso un objeto system.drawing.image a otro método, y cargo una imagen en ese objeto, entonces dejo que ese método salga del alcance y vuelva al método de llamada, ¿esa imagen no se carga en el objeto original?
¿Por qué es esto?
Respuestas:
Los objetos no se pasan en absoluto. Por defecto, el argumento se evalúa y su valor se pasa, por valor, como el valor inicial del parámetro del método al que está llamando. Ahora, el punto importante es que el valor es una referencia para los tipos de referencia, una forma de llegar a un objeto (o nulo). Los cambios a ese objeto serán visibles desde la persona que llama. Sin embargo, cambiar el valor del parámetro para referirse a un objeto diferente no será visible cuando use el valor de pasar por valor, que es el valor predeterminado para todos los tipos.
Si desea usar paso por referencia, debe usar
out
oref
, si el tipo de parámetro es un tipo de valor o un tipo de referencia. En ese caso, efectivamente la variable en sí se pasa por referencia, por lo que el parámetro usa la misma ubicación de almacenamiento que el argumento, y el llamante ve los cambios en el parámetro en sí.Entonces:
Tengo un artículo que entra en muchos más detalles en esto . Básicamente, "pasar por referencia" no significa lo que crees que significa.
fuente
ref
yout
desde c #, ¿está bien decir que c # pasa los parámetros de la misma manera que java, es decir, siempre por valor? ¿Hay alguna diferencia con Java?Una muestra de código más para mostrar esto:
Y la salida:
fuente
Se han agregado muchas buenas respuestas. Todavía quiero contribuir, podría aclarar un poco más.
Cuando pasa una instancia como argumento al método, pasa la
copy
de la instancia. Ahora, si la instancia que pasa es unvalue type
(reside en elstack
) pasa la copia de ese valor, por lo que si lo modifica, no se reflejará en la persona que llama. Si la instancia es un tipo de referencia, pasa la copia de la referencia (nuevamente reside enstack
) al objeto. Entonces tienes dos referencias al mismo objeto. Ambos pueden modificar el objeto. Pero si dentro del cuerpo del método, crea una instancia de un nuevo objeto, su copia de la referencia ya no se referirá al objeto original, sino al nuevo objeto que acaba de crear. Entonces terminarás teniendo 2 referencias y 2 objetos.fuente
Supongo que es más claro cuando lo haces así. Recomiendo descargar LinqPad para probar cosas como esta.
Y eso debería dar salida
WontUpdate
Nombre: Egli, Apellido: Becerra
Actualizar implícitamente
Nombre: Favio, Apellido: Becerra
Actualizar explícitamente
Nombre: Favio, Apellido: Becerra
fuente
Cuando pasa el
System.Drawing.Image
objeto type a un método, en realidad está pasando una copia de referencia a ese objeto.Entonces, si dentro de ese método está cargando una nueva imagen, está cargando usando una referencia nueva / copiada. No estás haciendo cambios en el original.
fuente
¿Cómo pasaste el objeto al método?
¿Estás haciendo algo nuevo dentro de ese método para el objeto? Si es así, debe usar el
ref
método.El siguiente enlace te da una mejor idea.
http://dotnetstep.blogspot.com/2008/09/passing-reference-type-byval-or-byref.html
fuente
In Pass By Reference ¡Solo agrega "ref" en los parámetros de la función y una cosa más debería declarar la función "static" porque main es static (#
public void main(String[] args)
)!fuente