È una funzione interna giustificata in questa situazione

4

Sono nuovo ai concetti di programmazione funzionale in C #, ma ho una certa esperienza con le funzioni di ordine superiore tramite Haskell, Scala, Python e Ruby. Attualmente sto utilizzando una vecchia base di codice .NET 2.0 con un sacco di duplicati. La maggior parte è semplice "copia / incolla" con alcune variabili modificate. Sto cercando di condensare il più possibile.

Un pezzo di codice all'interno di una routine su cui sto lavorando ora è un po 'come questo, ad esempio:

if (PostProcess.UsesFirstPass)
{
    w.WriteLine(V1 + " = 0" + " !! SET FOO");
    w.WriteLine(V2 + " = 0" + " !! SET BAR");
    w.WriteLine(V3 + " = 0" + " !! SET BAZ");
    if (PostProcess.IsSpecial){
        w.WriteLine(V3 + " = 20" + " !! INCREASE BAZ");
    }
    w.WriteLine(V4 + " = 0" + " !! SET QUUX");
}
if (PostProcess.UsesSecondPass)
{
    w.WriteLine(V5 + " = 0" + " !! SET FOO");
    w.WriteLine(V6 + " = 0" + " !! SET BAR");
    w.WriteLine(V7 + " = 0" + " !! SET BAZ");
    if (PostProcess.IsSpecial){
        w.WriteLine(V7 + " = 20" + " !! INCREASE BAZ");
    }
    w.WriteLine(V8 + " = 0" + " !! SET QUUX");
}
if (PostProcess.UsesFinalPass)
{
    w.WriteLine(V9 + " = 0" + " !! SET FOO");
    w.WriteLine(V10 + " = 0" + " !! SET BAR");
    w.WriteLine(V11 + " = 0" + " !! SET BAZ");
    if (PostProcess.IsSpecial){
        w.WriteLine(V11 + " = 20" + " !! INCREASE BAZ");
    }
    w.WriteLine(V12 + " = 0" + " !! SET QUUX");
}

Dove una delle "V" che vedi è una variabile di stringa definita in precedenza. Fa parte di un metodo abbastanza grande. Potrei scrivere un altro metodo chiamato, per esempio, WriteVariables() e passare le informazioni richieste e chiamarlo tre volte, ma si applica solo a questa sezione di metodo. Penso che questo sarebbe un posto dove scrivere una funzione interiore anonima avrebbe senso.

L'ho fatto per testarlo e sembra che funzioni bene. Ora ho un singolo delegato che assomiglia a qualcosa:

private delegate void WriteCutVars(string V1, 
    string V2, string V3, string V4, CuttingParameters cutParam);

// snip //

WriteCutVars WriteVars = (Va, Vb, Vc, Vd) => {
    w.WriteLine(Va + " = 0" + " !! SET FOO");
    w.WriteLine(Vb + " = 0" + " !! SET BAR");
    w.WriteLine(Vc + " = 0" + " !! SET BAZ");
    if (PostProcess.IsSpecial){
        w.WriteLine(Vc + " = 20" + " !! INCREASE BAZ");
    }
    w.WriteLine(Vd + " = 0" + " !! SET QUUX");
}
if (Process.UsesFirstPass) WriteVars(V1, V2, V3, V4);
if (Process.UsesSecondPass) WriteVars(V5, V6, V7, V8);
if (Process.UsesFinalPass) WriteVars(V9, V10, V11, V12);

Le mie domande principali:

  • È un uso corretto delle funzioni interiori?
  • È accettabile quando sono l'unico laureato in CS in una squadra di per lo più ingegneri meccanici?
posta KChaloux 10.08.2012 - 21:49
fonte

3 risposte

6

La tua implementazione mi sembra ragionevole.

Tuttavia, se la maggior parte delle altre persone che sviluppano il software ha un'esperienza di programmazione avanzata limitata, è possibile che si desideri utilizzare una funzione regolare anziché anonima, poiché sarà più ovvio che cosa sta succedendo.

Quando sei lo sviluppatore senior e il resto della tua squadra ha un livello di abilità significativamente più basso; assicurandosi che capiscano come funziona il tuo codice e può facilmente modificarlo se necessario è una considerazione importante. Poiché la tua squadra è composta principalmente da non programmatori, questa è una considerazione più ampia, poiché per le tecniche di programmazione probabilmente si avvicinano alla Usa quello che so della scala rispetto a Impara cose nuove ogni giorno fine.

Rompere la logica ripetuta e rimuovere la copia / incolla dovrebbe essere semplice per spiegare i vantaggi di. Tecniche più avanzate come le funzioni anonime o linq sarebbero una vendita più dura dal momento che non offrono miglioramenti importanti e ovvi di funzionalità / manutenzione. Gli ingegneri hardware con cui ho lavorato in passato in genere hanno imparato solo C all'università dal momento che era la lingua di scelta per i microcontrollori nei gadget che stavano costruendo. Con solo una manciata di classi, le loro abilità erano concentrate solo sulla programmazione di base pratica e non su nulla di avanzato.

    
risposta data 10.08.2012 - 22:00
fonte
4

Questa non è una funzione di ordine superiore, quindi dovrebbe essere facilmente comprensibile a qualsiasi programmatore C #.

Sebbene invece di utilizzare un tipo di delegato personalizzato, potresti aver utilizzato Action<string, string, string, CuttingParameters> .

Ma penso che un metodo normale sarebbe andato bene anche qui, ed è probabilmente più idiomatico. Anche se non lo userai da nessun'altra parte.

    
risposta data 10.08.2012 - 22:08
fonte
2

La domanda chiave è se utilizzare una funzione "normale" private o una funzione strettamente locale e la risposta dovrebbe derivare dallo stesso processo decisionale da utilizzare con un campo private rispetto a una variabile locale: Questa cosa è utile ovunque ma questa funzione? In questo caso, non sembrerebbe, quindi il tuo approccio sembra corretto.

è un problema con l'utilizzo di tecniche funzionali avanzate in C #, ma C # si sta evolvendo per avere caratteristiche sempre più funzionali, quindi non dovresti evitare tutte tecniche funzionali < em> solo perché potrebbero non essere ancora conosciuti. Direi che questo sarebbe in realtà il tipo di utilizzo che sarebbe buono in una base di codice in cui le persone erano relativamente poco familiari con la programmazione funzionale, dal momento che è molto semplice sia in termini di utilità che di implementazione.

    
risposta data 10.08.2012 - 22:44
fonte

Leggi altre domande sui tag