C Sharp ExpresionesLambda

download C Sharp ExpresionesLambda

of 9

Transcript of C Sharp ExpresionesLambda

  • 7/25/2019 C Sharp ExpresionesLambda

    1/9

    C# - Apuntes TcticosExpresiones Lambda

    Pgina 1 de 9

    C# - Expresiones Lambda

    Contenido

    1 Expresiones Lambda ........................................................................................................................ 2

    1.1 A modo de introduccin .......................................................................................................... 2

    1.1.1 Sintaxis ............................................................................................................................ 2

    1.1.2 Puntos importantes: ........................................................................................................ 3

    1.1.3 Los delegados genricos: action y func ........................................................................... 3

    1.1.4 Lambdas de expresin ..................................................................................................... 4

    1.1.5 Lambdas de instrucciones ............................................................................................... 4

    1.2 Expresiones Lambda y genricos ............................................................................................ 5

    1.2.1 Un Ejemplo ...................................................................................................................... 6

    1.3 Lambdas de Async ................................................................................................................... 7

    1.4 Lambdas con los operadores de consulta estndar ................................................................ 8

    1.4.1 Ejemplos de Expresiones Lambda en LINQ ..................................................................... 8

    1.5 Deduccin de tipos en las expresiones lambda ...................................................................... 81.6 Referencia Bibliogrfica........................................................................................................... 9

  • 7/25/2019 C Sharp ExpresionesLambda

    2/9

    C# - Apuntes TcticosExpresiones Lambda

    Pgina 2 de 9

    1 Expresiones Lambda1.1 A modo de introduccin

    Una expresin lambda es una expresin que devuelve un mtodo

    Una expresin lambda es una funcin annima que puede contener expresiones e instrucciones y sepuede utilizar para crear delegados o tipos de rboles de expresin.

    Esto resulta bastante extrao porque la mayora de las expresiones devuelven (ms o menos) unvalor

    Un mtodo tpico est formado por cuatro elementos:

    El tipo que devuelve el mtodo, El nombre del mtodo, La lista de parmetros, y El cuerpo del mtodo donde estn las instrucciones que se ejecutan.

    Las expresiones lambda est formada por tres elementos (no define un nombre de mtodo)

    El tipo que devuelve el mtodo, (si es que lo hay) se infiere del contexto en el que se utiliza laexpresin Lambda

    La lista de parmetros, y

    El cuerpo del mtodo donde estn las instrucciones que se ejecutan.1.1.1 Sintaxis( () => {Folder.StopFolding[0];} )

    () => { statusBarItemInformes.Content = texto; }(x) => { return x * x; }(x, y) => { return x + y; }

    (ref x, y) => {x++;

    return x / y;}

    // (Ojo parmetro x pasado por referencia)

    () Una lista de parmetros entre parntesis, si el mtodo que estamos definiendo no aceptaparmetro se ponen los parntesis vacios

    El operador => que indica que es una expresin Lambda. El operador => tiene la mismaprioridad que la asignacin (=) y es asociativo por la derecha.

    A la derecha del operador indicaremos el cdigo de la funcin (la expresin o bloque deinstrucciones). El cuerpo del mtodo, puede contener todas las instrucciones que queramos,o nicamente una expresin, y se pueden identar y/o formatear de la forma que nosparezcan ms legibles, solo tenemos que acordarnos de incluir el carcter punto y coma (;) alfinal de cada alinea igual que en un mtodo ordinario

    Las expresiones lambda no se permiten en el lado izquierdo del operador is o as.

    http://msdn.microsoft.com/es-es/library/scekt9xw.aspxhttp://msdn.microsoft.com/es-es/library/scekt9xw.aspxhttp://msdn.microsoft.com/es-es/library/scekt9xw.aspxhttp://msdn.microsoft.com/es-es/library/cscsdfbt.aspxhttp://msdn.microsoft.com/es-es/library/cscsdfbt.aspxhttp://msdn.microsoft.com/es-es/library/cscsdfbt.aspxhttp://msdn.microsoft.com/es-es/library/cscsdfbt.aspxhttp://msdn.microsoft.com/es-es/library/scekt9xw.aspx
  • 7/25/2019 C Sharp ExpresionesLambda

    3/9

    C# - Apuntes TcticosExpresiones Lambda

    Pgina 3 de 9

    Si una expresin lambda acepta parmetros, los especificaremos entre parntesis a laizquierda del operados =>. Podemos omitir el tipo de los parmetros porque el compiladorlos deducir del contexto de la expresin Lambda.

    Podemos pasar parmetros por referencia mediante la palabra clave [ref] Pueden devolver valores, pero el tipo de retron se infiere del contexto donde se usa.

    1.1.2 Puntos importantes: Las expresiones lambda no utilizan la instruccin return, excepto aquellas que utilicen un

    bloque encerrado entre llaves.

    suma = (a, b) =>

    {

    return a + b;

    };

    No es necesario especificar el tipo de los parmetros, ya que siempre van asociados a undelegado que ya contiene esta informacin.

    delegate string Delegado( int edad);[...]

    Delegado edad = e => string.Format("Tu edad es {0}", e);

    Se pueden usar tanto por delegados creados por nosotros como por aquellos definidos por el

    framework. m.Name) %>

    1.1.3 Los delegados genricos: action y funcPor otro lado, podemos utilizar los siguientes delegados genricos en lugar de delegate. Con ellosconseguimos una sintaxis algo ms refinada y simple.

    Action se utiliza para aquellas expresiones lambda que no retornan ningn valor.

    Action saludo = s => Console.Write("Hola {0}!", s);

    saludo("Amigo");

    Func para aquellas expresiones que retornen un valor.

    Func suma = (a, b) => a + b;int resultado = suma(3, 5);

    En el caso del delegado Func, el ltimo parmetro es un valor de retorno

  • 7/25/2019 C Sharp ExpresionesLambda

    4/9

    C# - Apuntes TcticosExpresiones Lambda

    Pgina 4 de 9

    1.1.4 Lambdas de expresinUna expresin lambda con una expresin en el lado derecho se denomina lambda de expresin. Laslambdas de expresin se utilizan ampliamente en la construccin de rboles de expresin (C# yVisual Basic).Una lambda de expresin devuelve el resultado de la expresin y presenta la siguienteforma bsica:

    (input parameters) => expression

    Los parntesis son opcionales si la expresin lambda tiene un nico parmetro de entrada; de locontrario, son obligatorios. Dos o ms parmetros de entrada se separan por comas y se encierranentre parntesis:

    (x, y) => x == y

    A veces, es difcil o imposible para el compilador deducir los tipos de entrada. Cuando esto ocurre,puede especificar los tipos explcitamente como se muestra en el ejemplo siguiente:

    (int x, string s) => s.Length > x

    Para especificar cero parmetros de entrada, utilice parntesis vacos:

    () => SomeMethod()

    Observe en el ejemplo anterior que el cuerpo de una lambda de expresin puede estar compuestode una llamada a mtodo.

    1.1.5 Lambdas de instruccionesUna lambda de instrucciones es similar a una lambda de expresin, salvo que las instrucciones seencierran entre llaves:

    (input parameters) => {statement;}

    El cuerpo de una lambda de instrucciones puede estar compuesto de cualquier nmero de

    instrucciones; sin embargo, en la prctica, generalmente no hay ms de dos o tres.

    delegate void TestDelegate(string s); TestDelegate myDel = n => { string s = n + " " + "World" ; Console.WriteLine(s); };

    myDel( "Hello" );

    Las lambdas de instrucciones, como los mtodos annimos, no se pueden utilizar para crear rbolesde expresin.

    http://msdn.microsoft.com/es-es/library/bb397951.aspxhttp://msdn.microsoft.com/es-es/library/bb397951.aspxhttp://msdn.microsoft.com/es-es/library/bb397951.aspxhttp://msdn.microsoft.com/es-es/library/bb397951.aspxhttp://msdn.microsoft.com/es-es/library/bb397951.aspxhttp://msdn.microsoft.com/es-es/library/bb397951.aspx
  • 7/25/2019 C Sharp ExpresionesLambda

    5/9

    C# - Apuntes TcticosExpresiones Lambda

    Pgina 5 de 9

    1.2 Expresiones Lambda y genricos

    Un ejemplo: La manera natural de implementar una definicin para la funcin lambda cuadrado enC# sera a travs de un tipo y una instancia de delegados:

    delegate T Mapeado (T x);

    Mapeado cuadrado = delegate(int x) { return x * x; };

    La primera lnea del cdigo anterior define un tipo delegado genrico llamado Mapeado. A partir deeste modelo podremos crear instancias de delegados para funciones que a partir de un valor de untipo T producen otro valor del mismo tipo T (o sea, que mapean recuerde el trmino, quecomenzar a utilizar con frecuencia en un futuro cercano- un valor del tipo T a otro valor del mismotipo).

    En la segunda lnea, por otra parte, se define una instancia del tipo delegado anterior que apunta auna funcin que devuelve el cuadrado de un nmero entero. En esta sintaxis se hace uso de otracaracterstica incorporada a C# en la versin 2.0, los mtodos annimos, que permiten la definicinen lnea del bloque de cdigo que especifica la funcionalidad a la que se desea asociar a la instanciadel delegado. En la versin original de C# habra sido necesario definir explcitamente la funcin (y eldelegado no habra podido ser genrico):

    static int Cuadrado(int x)

    {

    return x * x;

    }

    Mapeado cuadrado2 = Cuadrado;

    Aunque los mtodos annimos ofrecen una notacin ms compacta y directa, su sintaxis es an

    bastante verbosa y de naturaleza imperativa. En particular, al definir un mtodo annimo esnecesario:

    Utilizar explcitamente la palabra reservada delegate. Indicar explcitamente los tipos de los parmetros, sin ninguna posibilidad de que el

    compilador los deduzca a partir del contexto de utilizacin. En el caso bastante frecuente en que el cuerpo de la funcin es una simple sentencia return

    seguida de una expresin que evala el resultado (como en el caso de nuestro cuadrado), sehace an ms evidente el exceso sintctico.

    Las expresiones lambda pueden considerarse como una extensin de los mtodos annimos, queofrecen una sintaxis ms concisa y funcional para expresarlos. La sintaxis de una expresin lambdaconsta de una lista de variables-parmetros, seguida del smbolo de implicacin (aplicacin defuncin) =>, que es seguido a su vez de la expresin o bloque de sentencias que implementa lafuncionalidad deseada. Por ejemplo, nuestra definicin de cuadrado quedara de la siguiente formautilizando una expresin lambda:

    Mapeado cuadrado3 = x => x * x;

    Ms corto imposible, verdad? Se expresa de una manera muy sucinta y natural que cuadrado3 hace

    referencia a una funcin que, a partir de un x, produce x multiplicado por s mismo. En este caso, el

  • 7/25/2019 C Sharp ExpresionesLambda

    6/9

    C# - Apuntes TcticosExpresiones Lambda

    Pgina 6 de 9

    compilador deduce (infiere) automticamente del contexto que el tipo del parmetro y del resultadodeben ser int. Pudimos haberlo indicado explcitamente:

    Mapeado cuadrado4 = (int x) => x * x;

    Si se especifica el tipo del parmetro, o la expresin tiene ms de un parmetro (se indiquenexplcitamente o no sus tipos) los parntesis son obligatorios. Por otra parte, en la parte derecha dela implicacin se puede colocar una expresin, como hemos hecho hasta el momento, o un bloquede sentencias de cualquier complejidad (siempre que por supuesto produzca como resultado unvalor del tipo adecuado):

    Mapeado cuadrado5 = (int x) => { return x * x; };

    Aunque para una mejor comprensin hemos definido nuestro propio tipo delegado genrico

    Mapeado, en la prctica la mayor parte de las veces utilizaremos las distintas sobrecargas del tipogenrico predefinido Func:

    // en System.Query.dll

    // espacio de nombres System.Query

    public delegate T Func ();

    public delegate T Func (A0 a0);

    public delegate T Func (A0 a0, A1 a1);

    public delegate T Func (A0 a0, A1 a1, A2 a2);

    public delegate T Func (A0 a0, A1 a1, A2 a2, A3 a3);

    El tipo Func representa a los delegados a funciones (con 0, 1, 2 3 argumentos, respectivamente)

    que devuelven un valor de tipo T. Utilizando este tipo, podramos definir una nueva versin decuadrado as:

    Func cuadrado6 = x => x * x;

    1.2.1 Un EjemploImaginemos el caso que queremos ordenar una lista, usando el mtodo Sort. El mtodo Sort esperaun delegate de tipo Comparison. Este delegate es un delegate genrico que espera dos argumentosde tipo T, y devuelve un int:

    public delegate int Comparison (T x,T y);Si queremos ordenar una lista, usando un mtodo annimo, haramos algo parecido a esto:

    List lista = new List () { "Perro" , "Gato" , "Zorro" };lista.Sort (delegate (string s1, string s2)

    {return s1.CompareTo(s2);

    } );

    Dentro de la llamada del mtodo Sort, creamos el mtodo annimo (de tipo Comparison).

    Bien, pues bsicamente las expresiones lambda son una sintaxis alternativa (mucho ms compacta),

    para hacer exactamente lo mismo. Fijaros como quedara el cdigo anterior usando expresioneslambda:

    http://msdn.microsoft.com/en-us/library/tfakywbh.aspxhttp://msdn.microsoft.com/en-us/library/tfakywbh.aspxhttp://msdn.microsoft.com/en-us/library/tfakywbh.aspxhttp://msdn.microsoft.com/en-us/library/tfakywbh.aspx
  • 7/25/2019 C Sharp ExpresionesLambda

    7/9

    C# - Apuntes TcticosExpresiones Lambda

    Pgina 7 de 9

    List lista = new List () { "Perro" , "Gato" , "Zorro" };

    lista.Sort ( (x,y) => x.CompareTo(y));

    Es una sintaxis mucho ms compacta que "la clsica" de mtodos annimos. Vamos a comentarlarpidamente...

    El operador => es el operador lambda, y la sintaxis es param-list => valor_retorno

    siendo param-list una lista de parmetros (separados por comas), y valor_retorno una expresin que se evaluar y ser el resultado de la expresin lambda.

    Veamos otro ejemplo de cmo las expresiones lambda sustituyen (sintcticamente) a un mtodoannimo. Imaginemos el delegate:

    public delegate T Updater (T value);

    Un delegate que toma un objeto de tipo T y devuelve otro del mismo tipo.

    En la sintaxis estndard (C# 1.0 sin mtodos annimos) haramos algo como:

    Updater pFoo = new Updater (SumaUno);

    Donde SumaUno, sera un mtodo definido como algo parecido a:

    int SumaUno(int x) { return x + 1; }

    Usando mtodos annimos (C# 2.0) la cosa nos queda como:

    Updater pFooAnonimo = delegate(int x) { return x + 1; };

    Lo cual ya es ms compacto que la sintaxis anterior... y usando las nuevas expresiones lambda, la

    cosa nos queda como:Updater pFooLambda = x => x + 1;

    Bueno... una cosilla debis tener presente con las expresiones lambda... C# es un lenguajefuertemente tipado, y por ello las expresiones lambda tienen tipo... Que nosotros no pongamos tipoen los parmetros de una expresin lambda, no significa que lo tengan, significa que el compiladordebe poder deducirlos por el contexto. En este ejemplo que acabo de poner, el compilador deduceque "x" es de tipo int, porque estamos asignando la expresin lambda a un delegate que espera unparmetro de tipo int ( y una expresin lambda siempre se asigna a un delegate, y es este delegatequien nos define el tipo de los parmetros ). En el otro ejemplo que he expuesto antes (el de lallamada a Sort), el compilador puede deducir que los parmetros x e y son de tipo string, porqueestoy llamando a Sort de una List que por lo tanto me espera un delegate de tipoComparison que define dos parmetros de tipo string.

    1.3 Lambdas de Async

    Ms informacin en - Expresiones lambda (Gua de programacin de C#)http://msdn.microsoft.com/es-es/library/bb397687.aspx

    http://msdn.microsoft.com/es-es/library/bb397687.aspxhttp://msdn.microsoft.com/es-es/library/bb397687.aspxhttp://msdn.microsoft.com/es-es/library/bb397687.aspx
  • 7/25/2019 C Sharp ExpresionesLambda

    8/9

    C# - Apuntes TcticosExpresiones Lambda

    Pgina 8 de 9

    1.4 Lambdas con los operadores de consulta estndar

    Ms informacin en Expresiones lambda (Gua de programacin de C#)

    http://msdn.microsoft.com/es-es/library/bb397687.aspx

    1.4.1 Ejemplos de Expresiones Lambda en LINQEl principal uso de las expresiones lambda est vinculado con las expresiones de consultas LINQ. Asque veamos algunos ejemplos de estas expresiones, estos ejemplos son bien sencillos pero nosvienen bien para comprender el uso de las expresiones lambda.

    int[] nums = { 3, 4, 5, 6, 4, 5, 7 };

    var numMayores = nums.Where(n => n > 5).ToList();

    var numPares = nums.Where(n => n % 2 == 0).ToList();var numImpares = nums.Where(n => n % 2 != 0).ToList();

    El en cdigo de ejemplo anterior tenemos 3 consultas LINQ:

    La primera consulta la usamos para guardar en la variable de tipo annimo (numMayores) losnmeros que sean mayores de 5, y para lograrlo usamos la expresin lambda (n => n > 5). Elresultado sera evidentemente { 6, 7 }.

    En la segunda consulta (numPares) obtendremos los nmeros pares usando la siguienteexpresin lambda (n => n % 2 == 0). El resultado sera evidentemente { 4, 6, 4 }.

    En la tercera consulta (numImpares) obtendremos los nmeros impares usando la siguiente

    expresin lambda (n => n % 2 != 0).

    1.5 Deduccin de tipos en las expresiones lambda

    Al escribir expresiones lambda, no tiene por qu especificar un tipo para los parmetros de entrada,ya que el compilador puede deducir el tipo segn el cuerpo de la lambda, el tipo de delegadosubyacente y otros factores que se describen en la especificacin del lenguaje C#.Para la mayora delos operadores de consulta estndar, la primera entrada es el tipo de los elementos en la secuenciade origen.As, si est realizando una consulta sobre un IEnumerable, se deducir que lavariable de entrada ser un objeto Customer, lo cual significa que se podr tener acceso a susmtodos y propiedades:

    customers.Where(c => c.City == "London");

    Las reglas generales para las expresiones lambda son las siguientes:

    La lambda debe contener el mismo nmero de parmetros que el tipo delegado. Cada parmetro de entrada en la lambda se debe poder convertir implcitamente a su

    parmetro de delegado correspondiente. El valor devuelto de la lambda (si existe) se debe poder convertir implcitamente al tipo devalor devuelto del delegado.

    http://msdn.microsoft.com/es-es/library/bb397687.aspxhttp://msdn.microsoft.com/es-es/library/bb397687.aspxhttp://msdn.microsoft.com/es-es/library/bb397687.aspx
  • 7/25/2019 C Sharp ExpresionesLambda

    9/9

    C# - Apuntes TcticosExpresiones Lambda

    Pgina 9 de 9

    Observe que las expresiones lambda, en s mismas, no tienen tipo, ya que el sistema de tiposcomunes no tiene ningn concepto intrnseco de "expresin lambda". Sin embargo, a veces resultaprctico hablar informalmente del "tipo" de una expresin lambda. En estos casos, el tipo hacereferencia al tipo del delegado o el tipo de Expression en el que se convierte la expresin lambda.

    Ms informacin en - Expresiones lambda (Gua de programacin de C#)http://msdn.microsoft.com/es-es/library/bb397687.aspx

    1.6 Referencia Bibliogrfica

    Expresiones lambda (Gua de programacin de C#)o http://msdn.microsoft.com/es-es/library/bb397687.aspx

    rboles de expresin (C# y Visual Basic)o http://msdn.microsoft.com/es-es/library/bb397951.aspx

    Las expresiones lambda en C# 3.0o http://www.elguille.info/NET/futuro/firmas_octavio_ExpresionesLambda.htm

    Comparison Delegateo http://msdn.microsoft.com/en-us/library/tfakywbh.aspx

    C# es fcil (iv): Expresiones lambdao http://burbujasnet.blogspot.com.es/2008/06/c-es-fcil-iv-expresiones-lambda.html

    Func (Delegado)

    o

    http://msdn.microsoft.com/es-es/library/bb549151.aspx Action (Delegado)o http://msdn.microsoft.com/es-es/library/system.action.aspxo http://msdn.microsoft.com/es-es/library/bb548654.aspx

    Expresiones lambdao http://geeks.ms/blogs/gtorres/archive/2010/02/22/expresiones-lambda.aspx

    Clculo lambda (wikipedia)o http://es.wikipedia.org/wiki/C%C3%A1lculo_lambda

    Informacin sobre el documento

    dc.date.created: 2012-08-28 (Fecha Creacin) dc.date.modified: 2012-09-03 (Fecha Modificacin) dc.date.available: 2012-09-03 (Fecha Impresin) dc.author : Joaquin Medina Serrano [[email protected]]

    http://msdn.microsoft.com/es-es/library/system.linq.expressions.expression.aspxhttp://msdn.microsoft.com/es-es/library/system.linq.expressions.expression.aspxhttp://msdn.microsoft.com/es-es/library/system.linq.expressions.expression.aspxhttp://msdn.microsoft.com/es-es/library/bb397687.aspxhttp://msdn.microsoft.com/es-es/library/bb397687.aspxhttp://msdn.microsoft.com/es-es/library/bb397687.aspxhttp://msdn.microsoft.com/es-es/library/bb397687.aspxhttp://www.elguille.info/NET/futuro/firmas_octavio_ExpresionesLambda.htmhttp://www.elguille.info/NET/futuro/firmas_octavio_ExpresionesLambda.htmhttp://burbujasnet.blogspot.com.es/2008/06/c-es-fcil-iv-expresiones-lambda.htmlhttp://burbujasnet.blogspot.com.es/2008/06/c-es-fcil-iv-expresiones-lambda.htmlhttp://msdn.microsoft.com/es-es/library/bb549151.aspxhttp://msdn.microsoft.com/es-es/library/bb549151.aspxhttp://msdn.microsoft.com/es-es/library/bb549151.aspxhttp://burbujasnet.blogspot.com.es/2008/06/c-es-fcil-iv-expresiones-lambda.htmlhttp://burbujasnet.blogspot.com.es/2008/06/c-es-fcil-iv-expresiones-lambda.htmlhttp://www.elguille.info/NET/futuro/firmas_octavio_ExpresionesLambda.htmhttp://msdn.microsoft.com/es-es/library/bb397687.aspxhttp://msdn.microsoft.com/es-es/library/bb397687.aspxhttp://msdn.microsoft.com/es-es/library/system.linq.expressions.expression.aspx