Metodi sovraccarichi in conflitto con parametri opzionali

Ho due metodi sovraccaricati, uno con un parametro facoltativo.

void foo(string a) { } void foo(string a, int b = 0) { } 

ora chiamo:

  foo("abc"); 

interessante il primo sovraccarico è chiamato. perché non il secondo sovraccarico con valore opzionale impostato su zero?

Per essere onesti, mi sarei aspettato che il compilatore portasse un errore, almeno un avvertimento per evitare l’esecuzione involontaria del metodo sbagliato.

Qual è la ragione di questo comportamento? Perché il team C # lo ha definito in questo modo?

Da MSDN :

Se due candidati sono giudicati ugualmente buoni, la preferenza va a un candidato che non ha parametri opzionali per i quali gli argomenti sono stati omessi nella chiamata. Questa è una conseguenza di una preferenza generale nella risoluzione del sovraccarico per i candidati che hanno meno parametri.

Un sovraccarico che non richiede l’inserimento automatico di parametri opzionali è preferito a quello che fa. Tuttavia, non esiste una tale preferenza tra la compilazione automatica di un argomento e la compilazione di più di uno – quindi, ad esempio, ciò causerà un errore in fase di compilazione:

 void Foo(int x, int y = 0, int z = 0) {} void Foo(int x, int y = 0) {} ... Foo(5); 

Si noti che Foo (5, 5) sarebbe stato risolto con il secondo metodo, in quanto non richiede l’inserimento automatico di alcun parametro opzionale.

Dalla sezione 7.5.3.2 della specifica C # 4:

Altrimenti se tutti i parametri di MP hanno un argomento corrispondente mentre gli argomenti predefiniti devono essere sostituiti per almeno un parametro opzionale in MQ allora MP è migliore di MQ.

Penso che nella maggior parte dei casi questo è il comportamento che la maggior parte delle persone si aspetterebbe, ad essere onesti. Diventa strano quando introducete i metodi della class base nel mix, ma è sempre stato così.

Immagina solo se fosse il contrario. Hai avuto un’applicazione. Aveva un metodo:

 void foo(string a) { } 

Everyting ha funzionato bene. Ora, vuoi aggiungere un altro sovraccarico con un parametro facoltativo:

 void foo(string a, int b = 0) { } 

Boom! Tutte le chiamate di metodo vanno al nuovo metodo. Ogni volta che lo vuoi o no. L’aggiunta di un overload di metodi potrebbe causare chiamate di metodo errate in tutta l’applicazione.

Dal mio punto di vista, in questo caso avresti molte più opportunità di infrangere il tuo codice (o di qualcun altro).

Inoltre, OptionalAttribute è stato ignorato in C # fino alla versione 4.0, ma è ansible utilizzarlo. E alcune persone lo hanno usato nel codice C # per supportare determinati scenari di interoperabilità con altri linguaggi, come Visual Basic, o per l’interoperabilità COM. Ora C # lo usa per i parametri opzionali. L’aggiunta di avvertimenti / errori potrebbe introdurre un cambio di rottura per quelle applicazioni.

Potrebbero esserci altri motivi, ma questo è solo ciò che mi viene in mente prima.