2009-09-25 5 views
8

Ho appena incontrato qualcosa con C# oggi a cui non avevo pensato prima. Ho due metodi nella mia classe, uno un sovraccarico dell'altro. Essi sono dichiarati in questo modo:Parola chiave C# params con due parametri dello stesso tipo

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

Nel mio codice, ho provato a chiamare il primo in questo modo:

RequirePermissions("Permission1", "Permission2"); 

... aspettavo di chiamare il primo sovraccarico. Bene, ha chiamato il secondo sovraccarico. L'unico modo che posso ottenere per chiamare il primo metodo, in questo caso è quello di passare manualmente un oggetto string [] in questo modo:

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

Ora, questo comportamento non mi confondere perché capisco che il compilatore può Non so quale metodo in realtà volevo chiamare in base ai miei parametri forniti. Ma non stavo attento che questo potrebbe essere passato inosservato nel mio codice. Sembra che Microsoft avrebbe dovuto fare in modo che il compilatore generasse un errore quando si è verificata una situazione come sopra. Qualcuno ha qualche idea su questo? C'è un altro modo per chiamare il primo sovraccarico oltre alla "soluzione" che ho postato?

+0

Dai un'occhiata qui- http://ayende.com/Blog/archive/2007/12/31/Tricky-Code.aspx e qui- http: //www.yoda.arachsys .com/csharp/teasers.html (no 6) – RichardOD

+1

Sono un po 'confuso dal tuo suggerimento. Pensi che l'avviso dovrebbe essere sull'ambigua * chiamata * o sull'insieme di * dichiarazioni * che potrebbero portare a una chiamata ambigua? –

risposta

2

Sì, sono d'accordo che probabilmente dovrebbe essere un avvertimento quando si usano array di argomenti a lunghezza variabile che causano un sovraccarico ambiguo - è un caso davvero limite, e le persone quasi certamente non intendono creare tali situazioni.

Inoltre, non so in alcun modo, a parte quello che hai postato, per evitare la risoluzione della chiamata che si verifica - oltre a evitare di farlo in primo luogo, che consiglio vivamente!

0

Non è possibile utilizzare i parametri ed essere espliciti con le proprie firme.

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

D'accordo con Adam, vorrei cambiare a qualcosa come:

public void RequirePermissions(params string[] permissions) 

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

Dannazione, non ho notato la tua risposta fino a dopo aver postato il mio. Le barre di scorrimento nei campioni di codice mi fanno rabbrividire gli occhi, immagino. – MusiGenesis

+0

@ scottm: apparentemente no. * Ho * votato * la tua * risposta. :) – MusiGenesis

7

Personalmente, mi piacerebbe fare in questo modo:

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

persone cadono troppo innamorato di sovraccarico a volte, e quando si combina questo con un amore per la parola chiave params, si aumenta semplicemente il livello di confusione per chiunque debba eventualmente prendere in consegna il proprio codice.

+0

+1 Buona idea, ancora più esplicita –

3

Sembra che non ci sia altro modo.

è possibile trovare una spiegazione a questo comportamento in C# spec http://www.jaggersoft.com/csharp_standard /17.5.1.4.htm e qui http://www.jaggersoft.com/csharp_standard/14.4.2.1.htm (paragrafo 2)

una matrice di parametri è esattamente equivalente a un parametro di valore (§17.5.1.1) dello stesso tipo.

e

La forma espansa di un metodo è disponibile solo se la forma normale del metodo è non applicabile solo se un metodo con la stessa firma la forma espansa non è già dichiarato nello stesso tipo