L'overload è l'unico modo per avere argomenti di funzione predefiniti in C#?
-
09-06-2019 - |
Domanda
È vero che l'unico modo per gestire gli argomenti delle funzioni predefinite è tramite l'overload delle funzioni?
Ad esempio, in PHP posso fare questo:
function foo($x, $y=0)
{
}
Il modo migliore per gestirlo in C# sarebbe questo?
void foo(int x)
{
foo(x, 0);
}
void foo(int x, int y)
{
}
Modificare
Trasformato l'esempio C# in C# effettivo (grazie Blair Conrad)
Soluzione
Sì, sarebbe meglio, tranne per il fatto che ometteresti il , come altri hanno sottolineato.Per chi è interessato alla logica alla base della mancanza di valori dei parametri predefiniti, vedere la spiegazione di @Giovanni Galbo.$
s sui nomi dei parametri
Altri suggerimenti
Giusto per soddisfare qualche curiosità:
Da Perché C# non supporta i parametri predefiniti?:
In linguaggi come C++, un valore predefinito può essere incluso come parte della dichiarazione del metodo:
processo void (dipendente, bonus bool = false)
Questo metodo può essere chiamato con:
a.Processo(dipendente, vero);
O
a.Processo(dipendente);
nel secondo caso il parametro bonus è impostato su false.
C# non ha questa funzionalità.
Uno dei motivi per cui non disponiamo di questa funzionalità è legato a un'implementazione specifica della funzionalità.Nel mondo C++, quando l'utente scrive:
a.Processo(dipendente);
il compilatore genera
a.process(dipendente, false);
In altre parole, il compilatore prende il valore predefinito specificato nel prototipo del metodo e lo inserisce nella chiamata al metodo: è proprio come se l'utente scrivesse "false" come secondo parametro.Non c'è modo di modificare il valore predefinito senza forzare l'utente della classe a ricompilare, il che è un peccato.
Il modello di sovraccarico funziona meglio in questo senso.L'autore del framework definisce semplicemente due metodi separati e quello a parametro singolo chiama il metodo a due parametri.Ciò mantiene il valore predefinito nel framework, dove può essere modificato se necessario.
Sarebbe possibile per un compilatore prendere qualcosa di simile alla definizione C++ e produrre gli sovraccarichi, ma ci sono alcuni problemi con questo approccio.
Il primo è che la correlazione tra il codice scritto dall'utente e il codice generato dal compilatore è meno evidente.Generalmente cerchiamo di limitare la magia quando possibile, poiché rende il lavoro più difficile per i programmatori.Il secondo problema ha a che fare con cose come i commenti sui documenti XML e IntelliSense.Il compilatore dovrebbe avere regole speciali su come generare commenti doc per i metodi sovraccarichi e IntelliSense dovrebbe avere intelligenza per comprimere i metodi sovraccaricati in un unico metodo.
Scrivere da soli gli sovraccarichi è un po' meno conveniente, ma pensiamo che sia una soluzione accettabile.
Per quanto riguarda il estratto dalle domande frequenti su C#:
La maggior parte dei problemi elencati sono stati risolti per VB.Net (in particolare i problemi relativi a IntelliSense e ai commenti xml), il che significa che sono davvero false piste... è disponibile del codice per il team C# che risolverà il problema.
Un altro motivo ha a che fare con la forzatura dell'utente di una classe a ricompilare, ma anche questa è una falsa pista.Se tu modifica un valore predefinito nella classe del framework e l'utente lo fa non devi ricompilare, rischi l'utente non sapendo che il valore predefinito è cambiato. Ora hai un potenziale bug nel codice che non viene visualizzato fino al runtime.In altre parole, l’alternativa di sovraccaricare la funzione è almeno altrettanto negativa.Naturalmente, ciò presuppone anche un'implementazione specifica della funzionalità, ma è l'implementazione suggerita nelle faq.
Pertanto è necessario valutare il motivo rimanente ("cercare di limitare la magia") rispetto al fatto (che riconoscono) che scrivere gli sovraccarichi è "un po' meno conveniente".Personalmente, dico di inserire la funzionalità e di lasciare che sia il programmatore a decidere se utilizzarla o meno.
Gli argomenti predefiniti fanno parte di C++, ma a partire da C# 3.5 gli argomenti predefiniti non sono ancora supportati: sarà necessario eseguire l'overload.Sono disponibili in VB.Net dalla versione 1.0.
SÌ.
O al curry.
Oppure astrarre in una classe e utilizzare lì i valori predefiniti.
No, AFAIK C# non supporta l'override e sì, questo è il modo consigliato per ottenere lo stesso effetto.
Come sottolineato, questo non è attualmente disponibile in C#, tuttavia sarà presente in C# 4.0, come spiega Sam Ng sul suo blog:
questo non fa il lavoro?
void foo(int x):this(x, 0){}
void foo(int x, int y){
// code here
}