salida referencia por parametros entrada c# pass-by-reference params pass-by-value

referencia - C#Resultados inconsistentes usando la palabra clave params



params c# (3)

Dado el siguiente método:

static void ChangeArray(params string[] array) { for (int i = 0; i < array.Length; i++) array[i] = array[i] + "s"; }

Esto funciona si lo llamo pasar una serie de cadenas:

string[] array = {"Michael", "Jordan"} // will become {"Michaels", "Jordans"} ChangeArray(array);

Pero no funcionará si lo llamo usando argumentos de cadena:

string Michael = "Michael"; string Jordan = "Jordan"; ChangeArray(Michael, Jordan); // This will NOT change the values of the variables

Entiendo que el compilador envolverá a Michael y Jordan en una matriz, ¿no deberían los resultados ser iguales en ambos casos?


Esto es raro (no lo sabía), pero como se especifica .

Una matriz de parámetros permite que los argumentos se especifiquen de una o dos formas en una invocación de método:

El argumento dado para una matriz de parámetros puede ser una expresión única de un tipo que sea convertible implícitamente (Sección 6.1) al tipo de matriz de parámetros. En este caso, la matriz de parámetros actúa exactamente como un parámetro de valor.

Alternativamente, la invocación puede especificar cero o más argumentos para la matriz de parámetros, donde cada argumento es una expresión de un tipo que es convertible implícitamente (Sección 6.1) al tipo de elemento de la matriz de parámetros. En este caso, la invocación crea una instancia del tipo de matriz de parámetros con una longitud correspondiente al número de argumentos, inicializa los elementos de la instancia de matriz con los valores de argumento dados y utiliza la instancia de matriz recién creada como el argumento real.


La razón es que la string es un tipo inmutable: se pasan string instancias de string que se envuelven en una matriz. La matriz ahora contiene dos nuevas cadenas (con los mismos valores que las originales pero diferentes instancias). Cuando cambia la matriz, estas copias se desechan y la ranura de la matriz tendrá una nueva cadena. Cuando su función vuelve, la matriz temporal se desecha. Por lo tanto, las cadenas de entrada originales nunca se modifican (no podrían ser de ninguna manera, ya que la string es, de nuevo, inmutable).

Editar Realicé una edición de esta respuesta siguiendo el argumento de Lee en los comentarios (dejaré la respuesta simplemente para mantener la siguiente discusión completa). La parte inmutable es, de hecho, irrelevante para el problema. El principal problema subyacente es que los cambios se realizan en la matriz temporal que se desecha.


Su segundo ejemplo es esencialmente:

string Michael = "Michael"; string Jordan = "Jordan"; { var tmp = new string[] {Michael, Jordan}; ChangeArray(tmp); }

asi que; en realidad, los valores dentro de tmp se cambiaron ... pero tmp se descartó después, por lo que no se ve nada. params no emula ref - no hará una actualización de posición en las variables originales. O en código, no es el siguiente:

string Michael = "Michael"; string Jordan = "Jordan"; { var tmp = new string[] {Michael, Jordan}; ChangeArray(tmp); Michael = tmp[0]; Jordan = tmp[1]; }

Si necesita que se comporte de esa manera, codifíquelo así o, en su lugar, utilice una sobrecarga que tome parámetros de ref .