Expresiones C# Lambda: ¿Por qué debería usarlas?

Resuelto Patrick Desjardins asked hace 16 años • 17 respuestas

Leí rápidamente la documentación de Microsoft Lambda Expression .

Sin embargo, este tipo de ejemplo me ha ayudado a comprender mejor:

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

Aún así, no entiendo por qué es tal innovación. Es sólo un método que muere cuando termina la "variable de método", ¿verdad? ¿Por qué debería utilizar esto en lugar de un método real?

Patrick Desjardins avatar Oct 03 '08 22:10 Patrick Desjardins
Aceptado

Las expresiones Lambda tienen una sintaxis más simple para delegados anónimos y se pueden usar en todos los lugares donde se pueda usar un delegado anónimo. Sin embargo, lo contrario no es cierto; Las expresiones lambda se pueden convertir en árboles de expresión, lo que permite mucha magia como LINQ to SQL.

El siguiente es un ejemplo de una expresión LINQ to Objects que utiliza delegados anónimos y luego expresiones lambda para mostrar cuán agradables a la vista son:

// 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();

Las expresiones Lambda y los delegados anónimos tienen una ventaja sobre escribir una función separada: implementan cierres que pueden permitirle pasar el estado local a la función sin agregar parámetros a la función ni crear objetos de un solo uso.

Los árboles de expresión son una característica nueva muy poderosa de C# 3.0 que permite que una API observe la estructura de una expresión en lugar de simplemente obtener una referencia a un método que se puede ejecutar. Una API solo tiene que convertir un parámetro delegado en un Expression<T>parámetro y el compilador generará un árbol de expresión a partir de una lambda en lugar de un delegado anónimo:

void Example(Predicate<int> aDelegate);

llamado como:

Example(x => x > 5);

se convierte en:

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

A este último se le pasará una representación del árbol de sintaxis abstracta que describe la expresión x > 5. LINQ to SQL se basa en este comportamiento para poder convertir expresiones C# en las expresiones SQL deseadas para filtrar/ordenar/etc. en el lado del servidor.

Neil Williams avatar Oct 03 '2008 15:10 Neil Williams

Las funciones y expresiones anónimas son útiles para métodos únicos que no se benefician del trabajo adicional necesario para crear un método completo.

Considere este ejemplo:

 List<string> people = new List<string> { "name1", "name2", "joe", "another name", "etc" };
 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;
 }

Estos son funcionalmente equivalentes.

Joseph Daigle avatar Oct 03 '2008 15:10 Joseph Daigle

Los encontré útiles en una situación en la que quería declarar un controlador para el evento de algún control, usando otro control. Para hacerlo normalmente tendrías que almacenar las referencias de los controles en campos de la clase para poder usarlos en un método diferente al que fueron creados.

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;
}

gracias a las expresiones lambda puedes usarlo así:

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

Más fácil.

agnieszka avatar Dec 18 '2008 18:12 agnieszka

Lambda limpió la sintaxis delegado anónimo de C# 2.0... por ejemplo

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

Se hizo en C# 2.0 así:

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

Funcionalmente, hacen exactamente lo mismo, sólo que es una sintaxis mucho más concisa.

FlySwat avatar Oct 03 '2008 15:10 FlySwat