2009-09-25 10 views
8

Je viens de rencontrer quelque chose avec C# aujourd'hui auquel je n'avais pas pensé auparavant. J'ai deux méthodes dans ma classe, une surcharge de l'autre. Ils sont déclarés comme ceci:C# params mot-clé avec deux paramètres du même type

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

Dans mon code, j'ai essayé d'appeler le premier comme ceci:

RequirePermissions("Permission1", "Permission2"); 

... attendre pour appeler la première surcharge. Eh bien, il a appelé la deuxième surcharge. La seule façon que je peux obtenir pour appeler la première méthode dans ce cas est de passer manuellement une chaîne objet [] comme ceci:

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

Maintenant, ce comportement ne me confondez pas parce que je comprends que le compilateur peut Ne pas dire quelle méthode je voulais réellement appeler en fonction de mes paramètres fournis. Mais n'étais-je pas prudent, cela aurait pu passer inaperçu dans mon code. Il semble que Microsoft aurait dû lancer une erreur au compilateur lorsqu'il a rencontré une situation comme ci-dessus. Quelqu'un at-il des idées à ce sujet? Existe-t-il un autre moyen d'appeler la première surcharge autre que la "solution" que j'ai affichée?

+0

Jetez un oeil ici- http://ayende.com/Blog/archive/2007/12/31/Tricky-Code.aspx et ici- http: //www.yoda.arachsys .com/csharp/teasers.html (no 6) – RichardOD

+1

Je suis un peu confus par votre suggestion. Pensez-vous que l'avertissement devrait être sur l'appel ambigu *, ou sur l'ensemble des * déclarations * qui pourraient mener à un appel ambigu? –

Répondre

2

Oui, je suis d'accord qu'il devrait probablement être un avertissement lorsque l'utilisation de tableaux d'arguments de longueur variable provoque une surcharge ambiguë - c'est vraiment un cas limite, et les gens ne veulent certainement pas créer de telles situations.

Je ne sais pas d'autre façon, autre que celle que vous avez posté, pour éviter la résolution d'appel qui se produit - autre que d'éviter de le faire en premier lieu, que je recommande fortement!

0

Vous ne pouviez pas utiliser les paramètres et être explicite avec vos signatures.

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

Convenir avec Adam, je changerais à quelque chose comme:

public void RequirePermissions(params string[] permissions) 

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

Merde, n'a pas remarqué votre réponse jusqu'à ce que j'ai posté le mien. Les barres de défilement dans les échantillons de code font miroiter mes yeux, je suppose. – MusiGenesis

+0

@scottm: apparemment pas. * J'ai * voté * votre * réponse. :) – MusiGenesis

7

Personnellement, je le ferais de cette façon:

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

Les gens tombent aussi amoureux surcharger parfois, et quand vous combinez cela avec un amour pour le mot-clé params, vous augmentez simplement le niveau de confusion pour celui qui finit par prendre le contrôle de votre code.

+0

+1 Bonne idée, encore plus explicite –

3

Il semble qu'il n'y ait pas d'autre solution.

Vous pouvez trouver des explications à ce comportement en C# spec http://www.jaggersoft.com/csharp_standard /17.5.1.4.htm et ici http://www.jaggersoft.com/csharp_standard/14.4.2.1.htm (paragraphe 2)

un tableau de paramètres est précisément équivalent à un paramètre de valeur (§17.5.1.1) du même type.

et

La forme développée d'une méthode est disponible uniquement si la forme normale de la méthode n'est pas applicable et que si une méthode avec la même signature que la forme développée est pas déjà déclaré dans le même type