2010-10-21 18 views
7

mi instinto me dice que no debería hacer lo siguiente. No recibo ninguna advertencia al respecto.Puedo modificar un parámetro del método pasado

void test(DateTime d) 
{ 
d = d.AddDays(2); 
//do some thing with d 
} 

o se trata más adecuada

void test(DateTime d) 
{ 
DateTime _d = d.AddDays(1); 
//do some thing with _d 
} 

Por alguna razón siempre he manejado pasar parámetros como en el segundo ejemplo. Pero no estoy seguro si es realmente absurdo ... tal vez es solo un código poco ético.

No estoy pensando que el método de llamada usaría el valor modificado. Alguien tiene alguna opinión

Respuesta

14

Los cambios en el valor de un parámetro son invisibles a la persona que llama, a menos que sea un parámetro ref o out.

Eso es no el caso si se realiza un cambio en un objeto de tipo de referencia que se refiere por un parámetro. Por ejemplo:

public void Foo(StringBuilder b) 
{ 
    // Changes the value of the parameter (b) - not seen by caller 
    b = new StringBuilder(); 
} 

public void Bar(StringBuilder b) 
{ 
    // Changes the contents of the StringBuilder referred to by b's value - 
    // this will be seen by the caller 
    b.Append("Hello"); 
} 

Por último, si el parámetro se pasa por referencia, el cambio es visto:

public void Baz(ref StringBuilder b) 
{ 
    // This change *will* be seen 
    b = new StringBuilder(); 
} 

Para más información sobre esto, vea mi article on parameter passing.

+0

Gracias por el artículo ... Lo leeré en mi vuelo esta noche – Brad

4

lo puede cambiar, pero el cambio no volverá a la persona que llama.

Si se trata de un ValueType -> El copia del objeto se envía

Si se trata de un RefernceType -> Copia de Referencia a objeto será enviado por el valor. De esta forma, las propiedades del objeto se pueden cambiar, pero no la referencia en sí misma; de lo contrario, la persona que llama no verá el cambio.

Si se envía ref -> La referencia se puede cambiar.

En C++ se puede utilizar const para evitar el cambio pero C# no tiene ese. Esto es solo para evitar que el programador intente cambiarlo por error, dependiendo de dónde se use el const.

+0

Eso depende de los detalles. En este ejemplo muy específico, dado que DateTime es una estructura y tiene semántica de valores, eso es cierto. Otros argumentos, con semántica de referencia, reflejarían ese cambio de nuevo a la persona que llama. –

+0

@Harper: no si el OP cambia el valor del parámetro, en lugar de hacer un cambio en el objeto * referido a * por el valor del parámetro. Vea mi respuesta para un ejemplo de la diferencia entre estos dos. –

+0

@Harper, 'foo = ...' no se reflejará en el sitio de llamada para struct o clase * a menos que * sea específicamente un parámetro 'ref' (o' out'). Lo que haga * a los miembros del tipo de referencia * lo reflejará, lo que haga * a la referencia en sí * no lo hará. –

0

Si desea poder acceder al valor original, utilice el segundo método.

Si no te importa el valor original, puedes usar cualquiera de ellos (aunque probablemente aún use el segundo).

De cualquier manera, usted no va a doler los valores de nadie más (incluso si se vuelve a asignar el valor, no va a hacer de nuevo a la persona que llama) en este caso.

Cuestiones relacionadas