Hace poco aprendí que puedes crear algún método con parámetros ilimitados, por ejemplo:
SomeMethod(params int[] numbers);
pero mi pregunta es, ¿cuál es la diferencia entre eso y simplemente crear un método que recibe una lista o una matriz?
SomeMethod(int[] numbers);
SomeMethod(List<int> numbers);
tal vez tiene algún impacto en el rendimiento? No entiendo completamente ni veo de qué manera preferiría el que tiene parámetros ilimitados.
Una búsqueda rápida en google no ayudó, espero que me puedan ayudar.
params
también requiere que el tipo de argumento sea una matriz. Si necesita consumir una colección que no sea una matriz, puede tener más sentido proporcionar un noparams
argumento en su lugar.Console.Write
.Respuestas:
La diferencia entre
y
es que M puede llamarse así:
o así:
pero N solo puede llamarse de la segunda manera, no de la primera .
El impacto en el rendimiento es que, ya sea que llame
M
de la primera o de la segunda forma, de cualquier forma obtendrá una matriz creada. La creación de una matriz tiene un impacto en el rendimiento porque requiere tiempo y memoria. Recuerde que los impactos en el desempeño deben medirse contra los objetivos de desempeño; es poco probable que el costo de crear una matriz adicional sea el factor determinante que es la diferencia entre el éxito y el fracaso en el mercado.Es pura y enteramente una conveniencia para el autor del código que llama al método; es simplemente más corto y fácil de escribir
en lugar de escribir
Simplemente guarda algunas pulsaciones de teclas en el lado de la persona que llama. Eso es todo.
Algunas preguntas que no hizo pero que tal vez le gustaría saber la respuesta a:
Los métodos que permiten pasar un número variable de argumentos en el lado llamante se denominan variables . Los métodos de parámetros son cómo C # implementa métodos variables.
Cuando se enfrenta a un problema de resolución de sobrecarga, C # considerará las formas "normal" y "expandida", y la forma "normal" siempre gana si ambas son aplicables. Por ejemplo, considere esto:
y tenemos una llamada
Hay dos posibilidades aplicables. En forma "normal", llamamos
P
y pasamos una referencia nula para la matriz. En forma "expandida", llamamosP(new object[] { null })
. En este caso, la forma normal gana. Si recibimos una llamada,P(null, null)
entonces la forma normal no es aplicable y la forma expandida gana por defecto.Desafío : supongamos que tenemos
var s = new[] { "hello" };
y una llamadaP(s);
. Describa lo que sucede en el sitio de la llamada y por qué. ¡Te sorprenderías!Reto : supongamos que tenemos ambos
void P(object x){}
yvoid P(params object[] x){}
. ¿Qué haceP(null)
y por qué?Reto : supongamos que tenemos ambos
void M(string x){}
yvoid M(params string[] x){}
. ¿Qué haceM(null)
y por qué? ¿Cómo difiere esto del caso anterior?fuente
P(null)
vs.P((object)null)
vs.P((object[])null)
- ¿Dónde puedo encontrar una explicación para esta diferencia? Parece quenull
tenía algún tipo especial , que se convierte en matriz en lugar de objeto (P(null)
), pero encuentra la conversión a cadena o matriz de cadenas ambigua (M(null)
) ... lo que se siente muy extraño, esperaría que sea ambigua en ambos casos o seleccione la versión de un solo argumento (que no lo hace). Pero supongo que se trata más deparams
ser de alguna manera genérico , como la referencia universal (&&
) en las plantillas de C ++ y, por lo tanto, una mejor coincidencia (en Ch2, no en Ch3).object[]
sonobject
, pero no todosobject
sonobject[]
, porobject[]
lo tanto, es más específico.string[]
sonstring
". De hecho, NOstring[]
sonstring
y NOstring
sonstring[]
, porstring
lo que no es más específico o más general questring[]
, y obtenemos un error de ambigüedad cuando se nos pide elegir.object[]
sonobject
...object[]
es más específico, por lo queP(null)
va para la matriz más específica, thx, eso es lo que me faltaba. Encontré algunas reglas aquí: docs.microsoft.com/en-us/dotnet/csharp/language-reference/…Acabo de hacer un pequeño prototipo. La respuesta parece ser que
params
es simplemente azúcar sintáctica para pasar en una matriz. Eso no es realmente una sorpresa. Creé dos versiones del mismo método, donde la única diferencia es la palabra clave "params". La IL generada para ambos fue idéntica, excepto queSystem.ParamArrayAttribute
se aplicó a laparams
versión.Además, la IL generada en el sitio de la llamada también fue la misma entre que llamé al método con una declaración manual
new int[]
y llamé al método solo usando losparams
argumentos.Entonces, la respuesta parece ser "conveniencia". No parece haber ninguna diferencia en el rendimiento. También puede llamar a una
params
función con una matriz, por lo que tampoco es terriblemente sorprendente. Todo se reduce a si es más fácil para el consumidor de su método llamarlo con cualquier número de parámetros (psomeMethod(1, 2, 3)
. Ej. ) Que tener que crear siempre una colección primero (psomeMethod(new List<int>() { 1, 2, 3 } )
. Ej .).fuente
La función de parámetros ilimitados ofrece los siguientes beneficios en muchos escenarios:
Aquí hay un ejemplo donde la opción de parámetros ilimitados es una gran opción
Tenga en cuenta que debe crearse una aplicación para enviar correos electrónicos.
La función que envía el correo electrónico debe poder manejar valores únicos o múltiples para los campos 'Para', 'CC' y 'BCC'.
Si los tipos de parámetros se arreglan para ser matrices o listas para todos los campos (Para, CC, BCC), entonces la función de llamada se verá obligada a lidiar con toda la complejidad de definir 3 matrices o listas para llamar a la función del remitente del correo electrónico .
Incluso si la persona que llama desea enviar un correo electrónico a una sola dirección, la función del remitente del correo electrónico obligará a la persona que llama a definir y enviar 3 matrices diferentes como parámetros.
Si la función del remitente del correo electrónico adopta el enfoque de parámetros ilimitados, entonces la función de la persona que llama no necesita ocuparse de toda la complejidad.
El enfoque de parámetros ilimitados contribuye a mejorar el rendimiento de la aplicación en tiempo de ejecución al evitar la creación de matrices o listas donde sea innecesario.
fuente
Desde una perspectiva de estilo sin rendimiento , la
params
palabra clave es realmente agradable cuando se desea enviar una lista opcional de parámetros.Personalmente, usaría
params
cuando mi código fuera algo asíLo bueno de esto es que puedo usar este método por todas partes sin tener que crear una matriz o lista cada vez.
Yo usaría
array
olist
cuando sé que siempre pasaré esta función a un conjunto de datos que ya están juntos comoVeo el beneficio de
params
la flexibilidad que agrega. Puede ser un impacto relativamente menor en su código, pero sigue siendo una buena herramienta para tener.fuente
La convención de convocatoria es diferente. Por ejemplo ...
En el primer caso, puede pasar tantas entradas como parámetros separados al método. En el segundo, necesitaría crear una instancia de una lista y pasarla.
fuente