Funzione che restituisce funzioni non parametriche

4

Ho trovato una funzione in c # come questa:

  private Dictionary<string, Func<string>> ObtenerExtraCfgCampo(MsgDefCamp camp)
    {
        var extra = new Dictionary<string, Func<string>>();
        extra.Add("Oddity", () => camp.Order % 2 == 0 ? "Even" : "Odd");
        extra.Add("Odd", () => camp.Order % 2 == 0 ? "Odd" : string.Empty);
        extra.Add("Even", () => camp.Order % 2 != 0 ? "Even" : string.Empty);
        extra.Add("MsgPath", () => campo.MsgPath);
        return extra;

    }

C'è qualche utilità su questo? non sarebbe meglio così

private Dictionary<string, string> ObtenerExtraCfgCampo(MsgDefCamp camp)
{
    var extra = new Dictionary<string, string>();
    extra.Add("Oddity",  camp.Order % 2 == 0 ? "Even" : "Odd");
    extra.Add("Odd",  camp.Order % 2 == 0 ? "Odd" : string.Empty);
    extra.Add("Even",  camp.Order % 2 != 0 ? "Even" : string.Empty);
    extra.Add("MsgPath",  campo.MsgPath);
    return extra;

}

Ho capito che cambiare campo avrebbe cambiato il comportamento delle funzioni. Ma non è troppo riski e difficile ragionare? Mi chiedo se mi manca il punto di questo

    
posta Adrian Godoy 16.10.2018 - 10:35
fonte

2 risposte

5

Ignorando le leggere differenze di tipo, interagendo con il risultato del primo ti dà una vista sullo stato corrente di camp , ma il secondo dà una vista su qualche precedente stato di camp (IE quando è stato chiamato ObtenerExtraCfgCampo , probabilmente miliardi di nanosecondi fa).

Fanno cose diverse, quindi non sono intercambiabili. Non è più rischioso di qualsiasi altro riferimento allo stato mutevole.

Ho appena passato la maggior parte di un'app modificando un gruppo di Dictionary<Whatever, string> s in Dictionary<Whatever, Func<string>> s in modo da poter cambiare lingua in fase di runtime

    
risposta data 16.10.2018 - 10:54
fonte
3

Per vedere ciò che il punto di esso è, provare a eseguire le due versioni del metodo con il mutare dei dati, es vedi qui per un esempio di ciò che accade .

La prima versione, che utilizza Func , prevede una chiusura sull'istanza MsgDefCamp . In altre parole, quando il dizionario viene interrogato ottiene il valore corrente, quindi nel mio esempio riporta "Even" anche se il valore era disattivato quando è stato chiamato il metodo.

La seconda versione valuta il contenuto dell'istanza MsgDefCamp quando viene chiamato il metodo e memorizza quei risultati nel dizionario. Pertanto, anche se Order cambia, il valore del dizionario non cambia e viene visualizzato "Odd".

Può essere difficile ragionare se non hai familiarità con tale codice . È una funzionalità di linguaggio incredibilmente utile, quindi vale la pena prenderne dimestichezza.

    
risposta data 16.10.2018 - 12:59
fonte

Leggi altre domande sui tag