Il tuo esempio è un po 'troppo semplicistico per mostrare un po' della potenza delle funzioni locali. Prendi qualcosa di simile ad esempio:
class Processor
{
public void func(IEnumerable<MyObject> objectsToProcess)
{
foreach (var obj in objectsToProcess)
{
if (obj.IsFoo())
{
processEntity(obj);
obj.PostProcessFunction();
}
else if (obj.IsBar())
{
obj.DoSomeOtherPreProcessingThings();
processEntity(obj);
}
else if (obj.IsBaz())
{
obj.Frobinate();
}
else
{
obj.Slobrify();
processEntity(obj);
obj.Zorpalize();
}
}
void processEntity(MyObject obj) => (obj) {
//lots of code here you don't want to replicate
};
}
//lots of other public and private methods here
}
Supponiamo che la funzione processEntity
abbia un bel po 'di codice, qualcosa che non vorresti replicare. In quanto tale, ha perfettamente senso metterlo in una funzione.
Ma che tipo di modificatori di accesso dovrebbe avere? Diciamo anche che la funzione processEntity
non verrà mai chiamata dallo spazio pubblico, quindi rendiamola privata. Ma diciamo anche che non verrà mai chiamato da nessun'altra funzione membro. Dovrebbe essere ancora privato, ma può creare un po 'di problemi di manutenzione. Se vuoi cambiare questa funzione privata, devi assicurarti che non venga chiamata da nessun'altra parte (non particolarmente difficile con gli IDE moderni, ma comunque un carico cognitivo di cui devi occuparti). Inoltre lascia aperta la possibilità che lo sviluppo futuro utilizzi quella funzione, possibilmente in modo tale da rompere le cose o in modi che non gestiscono molte sottigliezze
Usando una funzione locale, comunica l'intento che dovrebbe essere utilizzato solo entro func
. Riduce anche i costi di manutenzione futuri dando a qualcuno che guarda alla classe meno che devono comprendere (a seconda di cosa stanno facendo).
Ci sono anche altre cose che puoi fare, come usare le variabili di chiusura.
void func2(int productId, string name)
{
string formatMySpecialMessage(int errorCode, int reasonCode) = (errorCode, reasonCode) => {
return $"An error ocurred while processing a request for item {productId}: {name}. The error was error code {errorCode}, {reasonCode}";
};
//lots of code with many error states that would use the formatMySpecialMessage function
}
Fare qualcosa come questo ti permette di riutilizzare una funzione e parte del contesto della tua funzione (l'ID prodotto e il nome in questo caso) senza dover passare quelle variabili in un'altra funzione per tutto il tempo.
Ci sono molti usi per loro. Se hai fatto sviluppo in Javascript probabilmente lo hai visto. Ho persino usato alcune funzioni locali come questa nel codice di produzione attuale.
Per tornare alla tua domanda originale, non c'è molta differenza tra i due esempi. Ma nessuno probabilmente dovrebbe fare manutenzione futura su un codice del genere. E quel codice è troppo semplicistico per giustificare veramente l'uso di una funzione locale.