unassigned stored parameter example c# .net .net-3.5 params

stored - ref out c#



¿Por qué pasar el método null a params resulta en una matriz de parámetro nulo? (5)

Consulte la especificación de C #, sección 10.6.1.4 Matrices de parámetros :

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 que sea convertible implícitamente (§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 que se puede convertir implícitamente (§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.

Como null es implícitamente convertible a string[] , se usará como matriz.

Además:

Al realizar una resolución de sobrecarga, un método con una matriz de parámetros puede ser aplicable en su forma normal o en su forma expandida (§7.5.3.1). La forma expandida de un método está disponible solo si la forma normal del método no es aplicable y solo si un método con la misma firma que el formulario expandido aún no está declarado en el mismo tipo.

lo que aclara que el compilador de hecho primero intenta usar el método con un argumento de matriz (forma normal) antes de intentar usar el argumento como un elemento de matriz (forma expandida).

Tengo un método que utiliza la palabra clave params , así:

private void ParamsMethod(params string[] args) { // Etc... }

Luego, llamo al método usando varias combinaciones de argumentos:

// Within the method, args is... ParamsMethod(); // - a string array with no elements ParamsMethod(null); // - null (Why is this?) ParamsMethod((string)null); // - a string array with one element: null ParamsMethod(null, null); // - a string array with two elements: null and null ParamsMethod("s1"); // - a string array with one element: "s1" ParamsMethod("s1", "s2"); // - a string array with two elements: "s1" and "s2"

Entiendo todos los casos, excepto el segundo. ¿Puede alguien explicar por qué ParamsMethod(null) hace que los args sean null , en lugar de una matriz con un elemento nulo?


De la especificación del lenguaje:

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 que sea convertible implícitamente (§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 que se puede convertir implícitamente (§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.

Como null en ParamsMethod(null) puede convertirse implícitamente en (string[])null , la primera regla es la que se aplica.


La razón para esto es que puede pasar una matriz del tipo apropiado a un argumento de params . Dado que null se puede convertir a cualquier tipo, y la sintaxis de la matriz tiene prioridad, se obtiene el valor null de su parámetro.

Por supuesto, convertirlo de forma explícita en una string hace que se convierta en un elemento de la matriz en lugar de la propia matriz.

Puedes probarlo y ver:

private void DoSomething(params IEnumerable[] arr) { // ... } ... DoSomething(new IEnumerable[] {new int[] {}}); // arr[0] isn''t IEnumerable[], it''s int[].

Y aquí hay una demostración en línea.


Puede pasar una matriz a un parámetro params; de hecho, es preferible (es decir, si pasa un objeto [] a un método que toma el objeto params [], es el parámetro completo , no solo el elemento individual). Null es válido como una asignación a una matriz, por lo tanto, ese enlace gana.

Básicamente, necesitarás ser más explícito.


Un parámetro params solo sirve para proporcionar una forma conveniente de especificar valores: aún puede pasar una referencia de matriz directamente.

Ahora, null se puede convertir a la string[] o a la string , por lo que ambas interpretaciones son válidas; depende de la especificación que se prefiera. La especificación establece en la sección 10.6.1.4 que:

  • El argumento dado para una matriz de parámetros puede ser una expresión única que sea convertible implícitamente 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, [...]

En otras palabras, el compilador comprueba si el argumento es válido primero como el tipo de parámetro "normal" y solo crea una matriz si es necesario.