see remarks net generate example cref c# parameter-passing params variadic-functions variadic

c# - remarks - ¿Por qué usar la palabra clave params?



see cref c# (7)

Sé que esta es una pregunta básica, pero no pude encontrar una respuesta.

¿Por qué usarlo? Si escribe una función o un método que la está utilizando, cuando la elimine, el código seguirá funcionando a la perfección. P.ej:

Con params:

static public int addTwoEach(params int[] args) { int sum = 0; foreach (var item in args) sum += item + 2; return sum; }

Sin params:

static public int addTwoEach(int[] args) { int sum = 0; foreach (var item in args) sum += item + 2; return sum; }


El uso de params permite llamar a la función sin argumentos. Sin params :

static public int addTwoEach(int[] args) { int sum = 0; foreach (var item in args) { sum += item + 2; } return sum; } addtwoEach(); // throws an error

Comparar con params :

static public int addTwoEach(params int[] args) { int sum = 0; foreach (var item in args) { sum += item + 2; } return sum; } addtwoEach(); // returns 0

En general, puede usar parámetros cuando el número de argumentos puede variar de 0 a infinito, y usar una matriz cuando el número de argumentos varía de 1 a infinito.


La adición de la palabra clave params en sí misma muestra que puede pasar varios parámetros mientras se llama a ese método, lo cual no es posible sin usarlo. Para ser más especifico:

static public int addTwoEach(params int[] args) { int sum = 0; foreach (var item in args) { sum += item + 2; } return sum; }

Cuando llame al método anterior, puede llamarlo por cualquiera de las siguientes formas:

  1. addTwoEach()
  2. addTwoEach(1)
  3. addTwoEach(new int[]{ 1, 2, 3, 4 })

Pero cuando elimine la palabra clave params, solo la tercera forma de las formas anteriores funcionará bien. Para el 1er y 2º caso obtendrás un error.


Le permite agregar tantos parámetros de tipo base en su llamada como desee.

addTwoEach(10, 2, 4, 6)

mientras que con la segunda forma tienes que usar una matriz como parámetro

addTwoEach(new int[] {10,2,4,6})


No es necesario crear métodos de sobrecarga, solo use un método único con parámetros como se muestra a continuación

// Call params method with one to four integer constant parameters. // int sum0 = addTwoEach(); int sum1 = addTwoEach(1); int sum2 = addTwoEach(1, 2); int sum3 = addTwoEach(3, 3, 3); int sum4 = addTwoEach(2, 2, 2, 2);


Un peligro con la palabra clave params es, si después de que se hayan codificado las llamadas al método,

  1. alguien quita accidentalmente / intencionalmente uno / más parámetros requeridos de la firma del método, y
  2. uno / más Parámetros requeridos inmediatamente antes de los Parámetros de parámetros antes del cambio de Firma eran de Tipo Compatible con el Parámetro de parámetros,

esas Llamadas continuarán compilando con una / más Expresiones previamente previstas para los Parámetros requeridos siendo tratados como el Parámetro opcional de parámetros. Acabo de encontrar el peor de los casos posibles: el parámetro params era de tipo object[] .

Esto es digno de mención porque los desarrolladores están acostumbrados a que el compilador se golpee las muñecas con un escenario mucho más común en el que los parámetros se eliminan de un método con todos los parámetros requeridos (porque el número de parámetros esperado cambiaría).

Para mí, no vale la pena el atajo. (Type)[] sin params trabajará con 0 hasta el infinito # de Parámetros sin necesidad de Anulaciones. El peor de los casos es que tendrá que agregar un , new (Type) [] {} a las Llamadas donde no se aplique.

Btw, imho, la práctica más segura (y la más legible) es:

  1. pase a través de Parámetros con nombre (que ahora podemos hacer incluso en C # ~ 2 décadas después de que pudiéramos en VB; P) (porque:

    1.1. es la única manera que garantiza la prevención de los valores no deseados pasados ​​a los Parámetros después del orden de Parámetros, el Tipo Compatible y / o el conteo después de que se hayan codificado las Llamadas,

    1.2. reduce esas posibilidades después de que cambie un significado de Parámetro, porque el nombre del nuevo identificador probable que refleja el nuevo significado está justo al lado del valor que se le pasa,

    1.3. evita tener que contar comas y saltar y retroceder de Call to Signature para ver qué Expresión se está pasando para qué Parámetro, y

    1.3.1. Por cierto, solo este motivo debería ser suficiente (en términos de evitar las frecuentes violaciones del principio DRY, propensas a errores, solo para leer el código, por no mencionar también modificarlo ), pero este motivo puede ser exponencialmente más importante si hay uno. Se pasan más expresiones que ellas mismas contienen comas, es decir, referencias de matrices multidimensionales o llamadas a funciones de múltiples parámetros. En ese caso, ni siquiera podría usar (lo que incluso si pudiera, aún estaría agregando un paso adicional por Parámetro por Llamada de Método) a Buscar todas las apariciones en una función de Selección en su editor para automatizar el conteo de comas para usted.

    1.4. si debe usar Parámetros Opcionales (parámetros o no), le permite buscar Llamadas donde se pasa un Parámetro Opcional en particular (y, por lo tanto, lo más probable es que no sea la posibilidad de que no sea el Valor Predeterminado).

(NOTA: Las razones 1.2 y 1.3 pueden facilitar y reducir las posibilidades de error incluso en la codificación de las llamadas iniciales, por no mencionar cuando las llamadas deben ser leídas y / o cambiadas))

y

  1. hágalo ONE - PARAMETER - PER - LINE para una mejor legibilidad (porque:

    2.1. es menos abarrotado, y

    2.2. evita tener que desplazarse a la derecha y atrás a la izquierda (y tener que hacerlo PER-LINE, ya que la mayoría de los mortales no pueden leer la parte izquierda de las múltiples líneas, desplazarse a la derecha y leer la parte derecha)).

    2.3. es coherente con la "Mejor práctica" en la que ya hemos evolucionado para las declaraciones de asignación, porque cada parámetro aprobado es en esencia una declaración de asignación (asignando un valor o referencia a una variable local). Al igual que aquellos que siguen las últimas "Mejores prácticas" en el Estilo de codificación no soñarían con codificar múltiples declaraciones de asignación por línea, probablemente no deberíamos (y una vez que "Mejores prácticas" no alcance mi "genio"; P ) hacerlo al pasar los parámetros.

NOTAS :

  1. Pasar en Variables cuyos nombres reflejen los Parámetros ''no ayuda cuando:

    1.1. está pasando Constantes Literales (es decir, un 0/1 simple, falso / verdadero o nulo que incluso las "Mejores Prácticas" no requieren que use una Constante Nombrada y su propósito no se puede deducir fácilmente del nombre del Método) )

    1.2. el Método es significativamente más bajo / más genérico que el Llamador, de modo que no querría / podría nombrar sus Variables iguales / similares a los Parámetros (o viceversa), o

    1.3. está reordenando / reemplazando los Parámetros en la Firma que pueden resultar en que las Llamadas anteriores aún se estén Compilando porque los Tipos siguen siendo compatibles.

  2. Tener una función de ajuste automático como VS solo elimina UNA (# 2.2) de las 8 razones que mencioné anteriormente. Antes de tan tarde como VS 2015, NO se auto-sangría (!?! ¿Realmente, MS?!?) Lo que aumenta la severidad de la razón # 2.1.

VS debe tener una opción que genere fragmentos de Método de Llamada con Parámetros Nombrados (uno por línea, por supuesto; P) y una opción de compilador que requiera Parámetros Nombrados (similar en concepto a Opción Explicita en VB que, por cierto, el requerimiento fue prolly una vez que se pensó igualmente indignante, pero ahora es muy requerido por "''Best Practices''"). De hecho, "back in my day";), en 1991, solo meses después de mi carrera, incluso antes de usar (o incluso haber visto) un idioma con Parámetros con nombre, tuve el anti-sheeple / "solo porque tu puedes, no significa que debe "/ no ciegamente" cortar los extremos del asado "lo suficiente como para simularlo (utilizando comentarios en línea) sin haber visto a nadie hacerlo. No tener que usar Parámetros Nombrados (como también otra sintaxis que guarda las pulsaciones del código fuente de "''preciosas'' '') es una reliquia de la era de la Tarjeta Perforada cuando la mayoría de estas sintaxis comenzaron. No hay excusa para eso con hardware moderno e IDE y un software mucho más complejo donde la facilidad de lectura es mucho, MUCHO más importante. "El código se lee mucho más seguido de lo que está escrito". Siempre y cuando no esté duplicando el código no actualizado automáticamente, es probable que cada pulsación de tecla guardada tenga un costo exponencial más cuando alguien (incluso usted mismo) intenta leerlo más tarde.


params también le permite llamar al método con un solo argumento.

private static int Foo(params int[] args) { int retVal = 0; Array.ForEach(args, (i) => retVal += i); return retVal; }

es decir, Foo(1); en lugar de Foo(new int[] { 1 }); . Puede ser útil para la taquigrafía en escenarios en los que es posible que deba pasar un solo valor en lugar de una matriz completa. Todavía se maneja de la misma manera en el método, pero da algunos dulces para llamar de esta manera.


Con params puedes llamar a tu método así:

addTwoEach(1, 2, 3, 4, 5);

Sin params , no puedes.

Además, puede llamar al método con una matriz como parámetro en ambos casos :

addTwoEach(new int[] { 1, 2, 3, 4, 5 });

Es decir, params permite usar un acceso directo al llamar al método.

Sin relación, puedes acortar drásticamente tu método:

public static int addTwoEach(params int[] args) { return args.Sum() + 2 * args.Length; }