Domanda

Ho fretta di leggere le Microsoft Espressione Lambda la documentazione.

Questo tipo di esempio mi ha aiutato a capire meglio, però:

delegate int del(int i);
del myDelegate = x => x * x;
int j = myDelegate(5); //j = 25

Ancora, non capisco perché è un'innovazione.E ' solo un metodo che muore quando il "metodo della variabile" finisce, giusto?Perché dovrei usare questo invece di un vero e proprio metodo?

È stato utile?

Soluzione

Le espressioni Lambda sono una sintassi più semplice per delegati anonimi e può essere utilizzato ovunque un anonimo delegato può essere utilizzato.Tuttavia, non è vero il contrario;le espressioni lambda possono essere convertiti in strutture di espressione che consente per un sacco di magia come LINQ to SQL.

Il seguente è un esempio di un LINQ to Objects espressione utilizzando delegati anonimi quindi le espressioni lambda per mostrare come molto più facile per l'occhio sono:

// anonymous delegate
var evens = Enumerable
                .Range(1, 100)
                .Where(delegate(int x) { return (x % 2) == 0; })
                .ToList();

// lambda expression
var evens = Enumerable
                .Range(1, 100)
                .Where(x => (x % 2) == 0)
                .ToList();

Le espressioni Lambda e delegati anonimi hanno un vantaggio su di scrivere una funzione separata:attuare chiusure che può permettere di passaggio di stato locale alla funzione, senza aggiunta di parametri per la funzione o la creazione di una-volta-utilizzare gli oggetti.

Espressione alberi sono molto nuove e potenti funzionalità di C# 3.0, che le consentono di API a guardare la struttura di un'espressione invece di ottenere un riferimento a un metodo che può essere eseguito.Un'API deve solo fare un delegato parametro in un Expression<T> parametro e il compilatore genererà una struttura ad albero dell'espressione da un lambda invece di un anonimo delegato:

void Example(Predicate<int> aDelegate);

chiamato come:

Example(x => x > 5);

diventa:

void Example(Expression<Predicate<int>> expressionTree);

Quest'ultimo otterrà passato una rappresentazione del albero di sintassi astratta che descrive l'espressione x > 5.LINQ to SQL si basa su questo comportamento per essere in grado di trasformare le espressioni di C# per le espressioni SQL desiderata per il filtro / ordinamento / etc.sul lato server.

Altri suggerimenti

Anonimo funzioni e le espressioni sono utili per metodi che non beneficiano del lavoro aggiuntivo necessario per creare un metodo completo.

Si consideri questo esempio:

 string person = people.Find(person => person.Contains("Joe"));

versus

 public string FindPerson(string nameContains, List<string> persons)
 {
     foreach (string person in persons)
         if (person.Contains(nameContains))
             return person;
     return null;
 }

Questi sono funzionalmente equivalenti.

Li ho trovati utili in una situazione in cui ho voluto dichiarare un gestore per un po ' di controllo dell'evento, utilizzando un altro controllo.Per farlo normalmente si dovrebbe avere per memorizzare i comandi di riferimenti nei campi della classe in modo che si potrebbe utilizzare un diverso metodo di essi sono stati creati.

private ComboBox combo;
private Label label;

public CreateControls()
{
    combo = new ComboBox();
    label = new Label();
    //some initializing code
    combo.SelectedIndexChanged += new EventHandler(combo_SelectedIndexChanged);
}

void combo_SelectedIndexChanged(object sender, EventArgs e)
{
    label.Text = combo.SelectedValue;
}

grazie per le espressioni lambda si può usare come questa:

public CreateControls()
{
    ComboBox combo = new ComboBox();
    Label label = new Label();
    //some initializing code
    combo.SelectedIndexChanged += (s, e) => {label.Text = combo.SelectedValue;};
}

Molto più facile.

Lambda pulito C# 2.0 delegato anonimo sintassi...per esempio

Strings.Find(s => s == "hello");

È stato fatto in C# 2.0 come questo:

Strings.Find(delegate(String s) { return s == "hello"; });

Funzionalmente, fanno esattamente la stessa cosa, solo che è molto più conciso di sintassi.

Questo è solo un modo per usare un'espressione lambda.È possibile utilizzare un'espressione lambda ovunque è possibile utilizzare un delegato.Questo permette di fare cose come questa:

List<string> strings = new List<string>();
strings.Add("Good");
strings.Add("Morning")
strings.Add("Starshine");
strings.Add("The");
strings.Add("Earth");
strings.Add("says");
strings.Add("hello");

strings.Find(s => s == "hello");

Questo codice ricerca elenco la voce che corrisponde alla parola "ciao".L'altro modo per farlo è quello di passare un delegato per il metodo di ricerca, come questo:

List<string> strings = new List<string>();
strings.Add("Good");
strings.Add("Morning")
strings.Add("Starshine");
strings.Add("The");
strings.Add("Earth");
strings.Add("says");
strings.Add("hello");

private static bool FindHello(String s)
{
    return s == "hello";
}

strings.Find(FindHello);

MODIFICA:

In C# 2.0, questo potrebbe essere fatto utilizzando il delegato anonimo sintassi:

  strings.Find(delegate(String s) { return s == "hello"; });

Lambda è molto pulito che di sintassi.

Microsoft ci ha dato un pulitore, più conveniente di creare in modo anonimo delegati chiamati espressioni Lambda.Tuttavia, c'è un sacco di attenzione per il espressioni parte di questa dichiarazione.Microsoft ha rilasciato un intero spazio dei nomi, Sistema.Linq.Espressioni, che contiene le classi per creare strutture di espressione basata su espressioni lambda.Espressione alberi sono fatti di oggetti che rappresentano la logica.Per esempio, x = y + z è un'espressione che potrebbe essere parte di una struttura ad albero dell'espressione in .Net.Si consideri il seguente (semplice) esempio:

using System;
using System.Linq;
using System.Linq.Expressions;


namespace ExpressionTreeThingy
{
    class Program
    {
        static void Main(string[] args)
        {
            Expression<Func<int, int>> expr = (x) => x + 1; //this is not a delegate, but an object
            var del = expr.Compile(); //compiles the object to a CLR delegate, at runtime
            Console.WriteLine(del(5)); //we are just invoking a delegate at this point
            Console.ReadKey();
        }
    }
}

Questo esempio è banale.E sono sicuro che stai pensando "Questo è inutile, come ho potuto, sono creati direttamente il delegato anziché la creazione di un'espressione e la compilazione in fase di esecuzione".E si sarebbe giusto.Ma questo fornisce la base per l'espressione alberi.Ci sono un certo numero di espressioni disponibili nelle Espressioni spazi dei nomi, e si può costruire il proprio.Penso che si può vedere che questo potrebbe essere utile quando non si conosce esattamente quale sia l'algoritmo deve essere in progettazione o in fase di compilazione.Ho visto un esempio da qualche parte per l'utilizzo di questo per scrivere una calcolatrice scientifica.Si potrebbe anche utilizzare per la Bayesiano sistemi, o per programmazione genetica (AI).Poche volte nella mia carriera ho dovuto scrivere Excel-come funzionalità che permetteva agli utenti di immettere espressioni semplici (oltre, subtrations, ecc) per operare sui dati disponibili.In pre-.Net 3.5 ho dovuto ricorrere a qualche linguaggio di scripting esterno di C#, o dovuto usare il codice emissione di funzionalità di riflessione per creare .Net codice al volo.Ora vorrei usare l'espressione di alberi.

Salva la necessità di avere metodi che vengono utilizzati solo una volta, in un luogo specifico da essere definito lontano dal luogo in cui sono utilizzati.Buona usi come comparatori per algoritmi generici come ordinamento, dove è quindi possibile definire una funzione di ordinamento personalizzato in cui si richiama la specie, piuttosto che lontano ti costringe a guardare altrove, di vedere che cosa si sta ordinando.

E non è proprio una novità.Il LISP ha avuto funzioni lambda per circa 30 anni o più.

Un'espressione lambda è come un metodo anonimo scritto in luogo di un'istanza di un delegato.

delegate int MyDelagate (int i);
MyDelagate delSquareFunction = x => x * x;

Considerare l'espressione lambda x => x * x;

Il valore del parametro di input x (sul lato sinistro del =>)

La logica della funzione è x * x (sul lato destro del =>)

Un'espressione lambda codice può essere una dichiarazione di blocco, invece di un'espressione.

x => {return x * x;};

Esempio

Nota: Func è un predefiniti delegato generico.

    Console.WriteLine(MyMethod(x => "Hi " + x));

    public static string MyMethod(Func<string, string> strategy)
    {
        return strategy("Lijo").ToString();
    }

Riferimenti

  1. Come può un delegato & interface essere usati in modo intercambiabile?

Si può trovare anche l'uso di espressioni lambda nella scrittura di codici generici agire sui metodi.

Per esempio:Una generica funzione per calcolare il tempo impiegato da una chiamata al metodo.(cioè Action qui)

public static long Measure(Action action)
{
    Stopwatch sw = new Stopwatch();
    sw.Start();
    action();
    sw.Stop();
    return sw.ElapsedMilliseconds;
}

E si può chiamare il metodo di cui sopra, utilizzando l'espressione lambda come segue,

var timeTaken = Measure(() => yourMethod(param));

Espressione consente di ottenere il valore restituito dal metodo e fuori param così

var timeTaken = Measure(() => returnValue = yourMethod(param, out outParam));

Un sacco di volte, si usa solo la funzionalità in un unico luogo, rendendo così un metodo di rumore della classe.

Espressione Lambda è un modo conciso per rappresentare un metodo anonimo.Entrambi i metodi anonimi e le espressioni Lambda consentono di definire il metodo di attuazione in linea, tuttavia, un metodo anonimo esplicitamente richiede di definire i tipi di parametro e il tipo di ritorno del metodo.Espressione Lambda utilizza la funzionalità inferenza del tipo di C# 3.0 che consente al compilatore di dedurre il tipo della variabile in base al contesto.È molto comodo perché questo ci consente di risparmiare un sacco di battitura!

È un modo di prendere piccole funzionamento e di metterlo molto vicino a dove viene utilizzata (non a differenza di dichiarazione di una variabile, vicino al suo punto d'utilizzo).Questo dovrebbe rendere il codice più leggibile.Dall'anonimato l'espressione, si sta anche rendendo molto più difficile per qualcuno di rompere il codice del client, se la funzione viene utilizzata da qualche altra parte e modificato per "migliorare" di esso.

Allo stesso modo, perché avete bisogno di usare foreach?Si può fare tutto in foreach con un semplice ciclo for o semplicemente utilizzando IEnumerable direttamente.Risposta:non bisogno ma rende il codice più leggibile.

La novità sta nel tipo di sicurezza e trasparenza.Anche se non dichiarare i tipi di espressioni lambda, essi vengono dedotti, e può essere utilizzato da ricerca codice, analisi statica, strumenti di refactoring, tempo di esecuzione e di riflessione.

Per esempio, prima che si potrebbe avere usato SQL e potrebbe avere un attacco di SQL injection, perché un hacker passata una stringa in cui un numero è normalmente previsto.Ora si dovrebbe utilizzare un LINQ espressione lambda, che è protetto da.

La costruzione di una LINQ API pura delegati non è possibile, perché richiede una combinazione di espressione alberi insieme prima della loro valutazione.

Nel 2016 la maggior parte delle lingue popolari sono espressione lambda il supporto, e C# è stato uno dei pionieri in questa evoluzione tra il mainstream linguaggi imperativi.

Questa è forse la migliore delle spiegazioni sul perchè di utilizzare le espressioni lambda -> https://youtu.be/j9nj5dTo54Q

In sintesi, è quello di migliorare la leggibilità del codice, ridurre la probabilità di errori attraverso il riutilizzo piuttosto che la replica di codice, e di sfruttare l'ottimizzazione accadendo dietro le quinte.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top