è un insetto?
Sì.
Congratulazioni, hai trovato un bug nella risoluzione dell'overload. Il bug si riproduce in C # 4 e 5; non si riproduce nella versione "Roslyn" dell'analizzatore semantico. Ho informato il team di test C # 5 e speriamo di poterlo esaminare e risolvere prima del rilascio finale. (Come sempre, nessuna promessa.)
Segue un'analisi corretta. I candidati sono:
0: C(params string[]) in its normal form
1: C(params string[]) in its expanded form
2: C<string>(string)
3: C(string, object)
Il candidato zero è ovviamente inapplicabile perché string
non convertibile in string[]
. Ne rimangono tre.
Dei tre, dobbiamo determinare un metodo migliore unico. Lo facciamo effettuando confronti a coppie dei tre candidati rimanenti. Ci sono tre di queste coppie. Tutti hanno elenchi di parametri identici una volta rimossi i parametri opzionali omessi, il che significa che dobbiamo passare al round di spareggio avanzato descritto nella sezione 7.5.3.2 della specifica.
Quale è meglio, 1 o 2? Il tiebreaker rilevante è che un metodo generico è sempre peggiore di un metodo non generico. 2 è peggio di 1. Quindi 2 non può essere il vincitore.
Quale è meglio, 1 o 3? Lo spareggio rilevante è: un metodo applicabile solo nella sua forma estesa è sempre peggiore di un metodo applicabile nella sua forma normale. Quindi 1 è peggio di 3. Quindi 1 non può essere il vincitore.
Quale è meglio, 2 o 3? Il tiebreaker rilevante è che un metodo generico è sempre peggiore di un metodo non generico. 2 è peggio di 3. Quindi 2 non può essere il vincitore.
Per essere scelto da una serie di più candidati idonei, un candidato deve essere (1) imbattuto, (2) battere almeno un altro candidato e (3) essere l'unico candidato che ha le prime due proprietà. Il terzo candidato non viene battuto da nessun altro candidato e batte almeno un altro candidato; è l'unico candidato con questa proprietà. Pertanto il terzo candidato è l' unico miglior candidato . Dovrebbe vincere.
Non solo il compilatore C # 4 sta sbagliando, come si nota correttamente che sta segnalando un bizzarro messaggio di errore. Che il compilatore abbia sbagliato l'analisi della risoluzione del sovraccarico è un po 'sorprendente. Che stia ottenendo il messaggio di errore sbagliato non è assolutamente sorprendente; l'euristica dell'errore del "metodo ambiguo" fondamentalmente sceglie due metodi qualsiasi dall'insieme candidato se non è possibile determinare un metodo migliore. Non è molto bravo a trovare la "vera" ambiguità, se in effetti ce n'è una.
Ci si potrebbe ragionevolmente chiedere perché sia così. È abbastanza complicato trovare due metodi che siano "inequivocabilmente ambigui" perché la relazione "migliore" è intransitiva . È possibile trovare situazioni in cui il candidato 1 è migliore di 2, 2 è migliore di 3 e 3 è migliore di 1. In tali situazioni non possiamo fare di meglio che sceglierne due come "ambigui".
Vorrei migliorare questa euristica per Roslyn, ma è una priorità bassa.
(Esercizio per il lettore: "Elaborare un algoritmo tempo lineare per identificare il miglior membro unico di un insieme di n elementi in cui la relazione migliore è intransitiva" è stata una delle domande che mi sono state poste il giorno in cui ho intervistato questo team. Non è un algoritmo molto difficile; provalo.)
Uno dei motivi per cui abbiamo rinunciato ad aggiungere argomenti facoltativi a C # per così tanto tempo è stato il numero di situazioni ambigue complesse che introduce nell'algoritmo di risoluzione dell'overload; a quanto pare non abbiamo capito bene.
Se desideri inserire un problema di Connect per monitorarlo, sentiti libero. Se vuoi solo che venga portato alla nostra attenzione, consideralo fatto. Seguirò i test il prossimo anno.
Grazie per avermelo fatto notare. Mi scuso per l'errore.
'Overloaded.ComplexOverloadResolution(string)'
riferisca al<string>(string)
metodo; Penso che si riferisca al(string, object)
metodo senza oggetto fornito.