2009-09-25 7 views
8

Acabo de encontrar algo con C# hoy en día que no había pensado antes. Tengo dos métodos en mi clase, uno es una sobrecarga del otro. Se declaran así:Palabra clave de C# params con dos parámetros del mismo tipo

1) public void RequirePermissions(params string[] permissions)... 
2) public void RequirePermissions(string message, params string[] permissions)... 

En mi código, he intentado llamar a la primera de ellas, así:

RequirePermissions("Permission1", "Permission2"); 

... esperando que llame a la primera sobrecarga. Bueno, llamó a la segunda sobrecarga. La única manera de que pueda conseguirlo para llamar al primer método, en este caso es pasar manualmente un objeto de cadena [], así:

RequirePermissions(new string[] { "Permission1", "Permission2" }); 

Ahora, este comportamiento no se me confunden porque entiendo que el compilador puede No diga a qué método realmente quería llamar en función de mis parámetros proporcionados. Pero si no tuviera cuidado, esto podría haber pasado desapercibido en mi código. Parece que Microsoft debería haber hecho que el compilador arrojara un error cuando se encontraba en una situación como la de arriba. ¿Alguien tiene alguna idea sobre esto? ¿Hay alguna otra manera de llamar a la primera sobrecarga que no sea la "solución" que publiqué?

+0

Eche un vistazo aquí- http://ayende.com/Blog/archive/2007/12/31/Tricky-Code.aspx y aquí- http: //www.yoda.arachsys .com/csharp/teasers.html (no 6) – RichardOD

+1

Estoy un poco confundido por su sugerencia. ¿Cree que la advertencia debería estar en la * llamada * ambigua, o en el conjunto de * declaraciones * que podría conducir a una llamada ambigua? –

Respuesta

2

Sí, estoy de acuerdo, debería ser una advertencia cuando el uso de arreglos de argumentos de longitud variable provoca una sobrecarga ambigua: es un caso marginal y la gente casi con certeza no pretende crear tales situaciones.

Tampoco sé de ninguna manera, aparte de la que publicaste, para evitar la resolución de llamadas que se produce, salvo para evitar hacerlo en primer lugar, ¡lo que recomiendo!

0

No podría usar params y ser explícito con sus firmas.

public void RequirePermissions(string[] permissions)... 
public void RequirePermissions(string message, string[] permissions).. 
7

Coincidiendo con Adam, que cambiaría a algo así como:

public void RequirePermissions(params string[] permissions) 

public void RequirePermissionsWithMessage(string message, params string[] permissions) 
+0

Maldita sea, no noté tu respuesta hasta después de haber publicado la mía. Las barras de desplazamiento en muestras de código hacen que mis ojos se vuelvan vidriosos, supongo. – MusiGenesis

+0

@scottm: aparentemente no. * Yo * voté * tu * respuesta. :) – MusiGenesis

7

En lo personal, me gustaría hacerlo de esta manera:

1) public void RequirePermissions(params string[] permissions)... 
2) public void RequireMessageAndPermissions(string message, 
     params string[] permissions)... 

La gente cae demasiado enamorado sobrecarga, a veces, y cuando combina eso con amor por la palabra clave params, solo aumenta el nivel de confusión para quien eventualmente tenga que hacerse cargo de su código.

+0

+1 Buena idea, aún más explícita –

3

Parece que no hay otra manera.

usted puede encontrar una explicación a este comportamiento en C# spec http://www.jaggersoft.com/csharp_standard /17.5.1.4.htm y aquí http://www.jaggersoft.com/csharp_standard/14.4.2.1.htm (párrafo 2)

una matriz de parámetros es precisamente equivalente a un valor de parámetro (§17.5.1.1) del mismo tipo.

y

la forma expandida de un método sólo está disponible si la forma normal del método no es aplicable y sólo si un método con la misma firma que la forma expandida no está ya declaró en el mismo tipo

Cuestiones relacionadas