<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://geeks.ms/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Variable not found en Geeks.ms : linq</title><link>http://geeks.ms/blogs/jmaguilar/archive/tags/linq/default.aspx</link><description>Etiquetas: linq</description><dc:language /><generator>CommunityServer 2008.5 SP1 (Build: 31106.3070)</generator><item><title>¿Esa enumeración está vacía?</title><link>http://geeks.ms/blogs/jmaguilar/archive/2010/05/20/191-esa-enumeraci-243-n-est-225-vac-237-a.aspx</link><pubDate>Thu, 20 May 2010 21:33:00 GMT</pubDate><guid isPermaLink="false">2a2e7ade-7474-448b-9de5-1515d8bb7d1b:176944</guid><dc:creator>José M. Aguilar</dc:creator><slash:comments>6</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/jmaguilar/rsscomments.aspx?PostID=176944</wfw:commentRss><comments>http://geeks.ms/blogs/jmaguilar/archive/2010/05/20/191-esa-enumeraci-243-n-est-225-vac-237-a.aspx#comments</comments><description>Casualmente encuentro en el post de Chris Eargle &amp;ldquo; Any() versus Count() &amp;rdquo; un tema del que pensaba escribir hace tiempo y al final dej&amp;eacute; en el tintero: &amp;iquest;c&amp;oacute;mo podemos determinar si una enumeraci&amp;oacute;n est&amp;aacute; vac&amp;iacute;a? Vale, es bien f&amp;aacute;cil, una enumeraci&amp;oacute;n est&amp;aacute; vac&amp;iacute;a si tiene cero elementos . Si trabajamos con un array, podemos consultar la propiedad Length ; si se trata de una colecci&amp;oacute;n, podemos utilizar la propiedad Count...(&lt;a href="http://geeks.ms/blogs/jmaguilar/archive/2010/05/20/191-esa-enumeraci-243-n-est-225-vac-237-a.aspx"&gt;read more&lt;/a&gt;)&lt;img src="http://geeks.ms/aggbug.aspx?PostID=176944" width="1" height="1"&gt;</description><category domain="http://geeks.ms/blogs/jmaguilar/archive/tags/desarrollo/default.aspx">desarrollo</category><category domain="http://geeks.ms/blogs/jmaguilar/archive/tags/c_2300_/default.aspx">c#</category><category domain="http://geeks.ms/blogs/jmaguilar/archive/tags/trucos/default.aspx">trucos</category><category domain="http://geeks.ms/blogs/jmaguilar/archive/tags/.net/default.aspx">.net</category><category domain="http://geeks.ms/blogs/jmaguilar/archive/tags/buenas+pr_26002300_225_3B00_cticas/default.aspx">buenas pr&amp;#225;cticas</category><category domain="http://geeks.ms/blogs/jmaguilar/archive/tags/vb.net/default.aspx">vb.net</category><category domain="http://geeks.ms/blogs/jmaguilar/archive/tags/linq/default.aspx">linq</category></item><item><title>Linq para NHibernate, versión 1.0</title><link>http://geeks.ms/blogs/jmaguilar/archive/2009/09/16/linq-para-nhibernate-versi-243-n-1-0.aspx</link><pubDate>Wed, 16 Sep 2009 10:59:00 GMT</pubDate><guid isPermaLink="false">2a2e7ade-7474-448b-9de5-1515d8bb7d1b:155797</guid><dc:creator>José M. Aguilar</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/jmaguilar/rsscomments.aspx?PostID=155797</wfw:commentRss><comments>http://geeks.ms/blogs/jmaguilar/archive/2009/09/16/linq-para-nhibernate-versi-243-n-1-0.aspx#comments</comments><description>Hace unas semanas, Oren Eini (o Ayende Raihen, como se le suele conocer) comunicaba la liberaci&amp;oacute;n de la versi&amp;oacute;n 1.0 del proveedor de Linq para NHibernate, una caracter&amp;iacute;stica altamente demandada por los usuarios desde la aparici&amp;oacute;n del lenguaje de consulta integrado en .NET. Aunque ser&amp;aacute; incluido como parte del producto NHibernate en versiones venideras, han decidido liberar la actual release del proveedor como paquete independiente para que pueda comenzar a utilizarse...(&lt;a href="http://geeks.ms/blogs/jmaguilar/archive/2009/09/16/linq-para-nhibernate-versi-243-n-1-0.aspx"&gt;read more&lt;/a&gt;)&lt;img src="http://geeks.ms/aggbug.aspx?PostID=155797" width="1" height="1"&gt;</description><category domain="http://geeks.ms/blogs/jmaguilar/archive/tags/desarrollo/default.aspx">desarrollo</category><category domain="http://geeks.ms/blogs/jmaguilar/archive/tags/.net/default.aspx">.net</category><category domain="http://geeks.ms/blogs/jmaguilar/archive/tags/novedades/default.aspx">novedades</category><category domain="http://geeks.ms/blogs/jmaguilar/archive/tags/bases+de+datos/default.aspx">bases de datos</category><category domain="http://geeks.ms/blogs/jmaguilar/archive/tags/linq/default.aspx">linq</category><category domain="http://geeks.ms/blogs/jmaguilar/archive/tags/orm/default.aspx">orm</category></item><item><title>C#: Desmitificando las expresiones lambda (y III)</title><link>http://geeks.ms/blogs/jmaguilar/archive/2009/04/28/c-desmitificando-las-expresiones-lambda-y-iii.aspx</link><pubDate>Tue, 28 Apr 2009 21:40:00 GMT</pubDate><guid isPermaLink="false">2a2e7ade-7474-448b-9de5-1515d8bb7d1b:147571</guid><dc:creator>José M. Aguilar</dc:creator><slash:comments>2</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/jmaguilar/rsscomments.aspx?PostID=147571</wfw:commentRss><comments>http://geeks.ms/blogs/jmaguilar/archive/2009/04/28/c-desmitificando-las-expresiones-lambda-y-iii.aspx#comments</comments><description>&lt;div class="post-header-line-1"&gt;&lt;/div&gt;
&lt;div class="post-body entry-content"&gt;
&lt;p&gt;&lt;img src="http://3.bp.blogspot.com/_O9D62hXq-ng/SQtrgaCIm9I/AAAAAAAAA6k/XuuGqsiLjkw/s200/lambdas.jpg" alt="Lambda" border="0" id="BLOGGER_PHOTO_ID_5263418794000817106" style="margin:0px 0px 10px 10px;float:right;" /&gt;En el &lt;a href="http://www.variablenotfound.com/2009/03/c-desmitificando-las-expresiones-lambda.html"&gt;&lt;span style="color:#35537a;"&gt;primer post&lt;/span&gt;&lt;/a&gt; intentamos describir qu&amp;eacute; eran las expresiones lambda, resumiendo muy brevemente su utilidad, as&amp;iacute; como los aspectos sint&amp;aacute;cticos de este tipo de construcciones del lenguaje. &lt;a href="http://www.variablenotfound.com/2009/03/c-desmitificando-las-expresiones-lambda_29.html"&gt;&lt;span style="color:#35537a;"&gt;El segundo&lt;/span&gt;&lt;/a&gt; lo enfocamos a explicar el papel de las lambda como funciones an&amp;oacute;nimas, su estrecha relaci&amp;oacute;n con los delegados, y su forma de utilizaci&amp;oacute;n.&lt;br /&gt;&lt;br /&gt;En esta tercera y &amp;uacute;ltima entrega de la serie, vamos a centrarnos en otra de las grandes utilidades de las expresiones lambda en .NET framework: la definici&amp;oacute;n de &amp;aacute;rboles de expresi&amp;oacute;n.&lt;/p&gt;
&lt;h3 id="arboles"&gt;Las lambda como &amp;aacute;rboles de expresi&amp;oacute;n&lt;/h3&gt;
&lt;img src="http://3.bp.blogspot.com/_O9D62hXq-ng/SPD32TjLheI/AAAAAAAAA5w/9wlOhabJCs8/s400/ExpressionTree.jpg" alt="&amp;Aacute;rbol de expresi&amp;oacute;n" border="0" id="BLOGGER_PHOTO_ID_5255973277474194914" style="margin:0px 0px 10px 10px;float:right;" /&gt;Los compiladores de C# y VB.NET pueden, bajo determinadas circunstancias, utilizar las lambdas para crear un &amp;aacute;rbol de expresi&amp;oacute;n, una estructura en memoria que representa en forma de &amp;aacute;rbol las operaciones a realizar, y en el orden que hay que hacerlo, para lograr un objetivo. Si lo quer&amp;eacute;is ver m&amp;aacute;s claro, observad el diagrama adjunto, en el que se muestra el &amp;aacute;rbol de expresi&amp;oacute;n correspondiente a una funci&amp;oacute;n lambda que obtiene la media de dos n&amp;uacute;meros.&lt;br /&gt;&lt;br /&gt;Esto es muy diferente al caso anterior, donde habl&amp;aacute;bamos de las lambda como funciones ejecutables que pod&amp;iacute;an ser referenciadas por delegados e invocadas de forma directa. Entonces las expresiones lambda eran transformadas en tiempo de compilaci&amp;oacute;n en c&amp;oacute;digo ejecutable (de hecho, en m&amp;eacute;todos est&amp;aacute;ticos que pueden ser consultados usando &lt;a hreflang="en" href="http://www.red-gate.com/products/reflector/index.htm" title=".NET Reflector"&gt;Reflector&lt;/a&gt; u otros desensambladores), y por ello pod&amp;iacute;amos utilizarlas de forma directa.&lt;br /&gt;&lt;br /&gt;En el caso de los &amp;aacute;rboles de expresi&amp;oacute;n, la compilaci&amp;oacute;n no genera c&amp;oacute;digo ejecutable correspondiente a las instrucciones definidas en la lambda, sino el c&amp;oacute;digo para crear y llenar el &amp;aacute;rbol con dicha expresi&amp;oacute;n. Despu&amp;eacute;s, en tiempo de ejecuci&amp;oacute;n, ser&amp;aacute; posible recorrer dicho &amp;aacute;rbol, analizarlo, seriarlo para almacenarlo o moverlo a otras capas, e incluso compilarlo para poder lanzar su ejecuci&amp;oacute;n.&lt;br /&gt;&lt;br /&gt;Pero paremos aqu&amp;iacute; un momento... seg&amp;uacute;n lo dicho, cuando el compilador se encuentra con una expresi&amp;oacute;n lambda, por ejemplo &lt;code&gt;x =&amp;gt; x * 2&lt;/code&gt;, puede optar por generar una funci&amp;oacute;n an&amp;oacute;nima o por generar el c&amp;oacute;digo de llenado del &amp;aacute;rbol, &amp;iquest;c&amp;oacute;mo sabe lo que debe hacer?&lt;br /&gt;&lt;br /&gt;Pues bien, el compilador elegir&amp;aacute; la opci&amp;oacute;n adecuada dependiendo del tipo de la referencia a la expresi&amp;oacute;n lambda. Si se trata de un tipo de delegado como &lt;code&gt;Func&lt;/code&gt; o &lt;code&gt;Action&lt;/code&gt;, generar&amp;aacute; c&amp;oacute;digo ejecutable y las referencias a la funci&amp;oacute;n ser&amp;aacute;n tratados como delegados; si se usa el tipo &lt;code&gt;Expression&lt;/code&gt;, que veremos m&amp;aacute;s adelante, se generar&amp;aacute; el &amp;aacute;rbol de expresi&amp;oacute;n y las referencias no se considerar&amp;aacute;n delegados, sino objetos de este tipo. Por este motivo no podemos utilizar para declarar lambdas &lt;a href="http://www.variablenotfound.com/2007/12/variables-locales-implictamente-tipadas.html" title="Variables locales impl&amp;iacute;citamente tipadas en C#"&gt;&lt;span style="color:#35537a;"&gt;variables locales de tipo impl&amp;iacute;cito&lt;/span&gt;&lt;/a&gt;: el compilador no sabr&amp;iacute;a qu&amp;eacute; hacer.
&lt;pre&gt;&lt;code&gt;&lt;br /&gt;  &lt;span style="color:red;font-weight:bold;"&gt;var dobla = a =&amp;gt; a * 2;&lt;/span&gt;&lt;span style="color:green;"&gt; // Error: no se puede asignar&lt;br /&gt;                          // una expresi&amp;oacute;n lambda a una variable&lt;br /&gt;                          // local de tipo impl&amp;iacute;cito.&lt;/span&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;
&amp;nbsp;&lt;br /&gt;
&lt;h3 id="definicionarboles"&gt;Definici&amp;oacute;n de &amp;aacute;rboles con expresiones lambda&lt;/h3&gt;
Para definir un &amp;aacute;rbol de expresi&amp;oacute;n a partir de una lambda debemos utilizar el tipo gen&amp;eacute;rico &lt;code&gt;Expression&amp;lt;TipoDelegado&amp;gt;&lt;/code&gt;, siendo &lt;code&gt;TipoDelegado&lt;/code&gt; un delegado como &lt;code&gt;Action&lt;/code&gt; o &lt;code&gt;Func&lt;/code&gt; de los descritos en el post anterior. &amp;iquest;Que esto os parece confuso? Pues esperad a ver el ejemplo... ;-)
&lt;pre&gt;&lt;code&gt;  Expression&amp;lt;&lt;span style="background-color:#ffffc0;"&gt;Func&amp;lt;int, int, int&amp;gt;&lt;/span&gt;&amp;gt; media = (a, b) =&amp;gt; (a + b) / 2;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;
&amp;nbsp;&lt;br /&gt;En realidad, aparte de lo dif&amp;iacute;cil de leer que es una declaraci&amp;oacute;n de este tipo, la idea es bastante sencilla. Lo que estamos indicando al compilador es que queremos montar un &amp;aacute;rbol de una expresi&amp;oacute;n de la que conocemos el tipo de los par&amp;aacute;metros de entrada y del valor de retorno, datos que indicamos mediante el delegado que utilizamos como argumento gen&amp;eacute;rico de la clase &lt;code&gt;Expression&lt;/code&gt;, la porci&amp;oacute;n que he marcado de amarillo en el ejemplo anterior. Adem&amp;aacute;s, este delegado lo utilizaremos cuando queramos convertir el &amp;aacute;rbol de expresi&amp;oacute;n en c&amp;oacute;digo ejecutable, m&amp;aacute;s adelante veremos c&amp;oacute;mo.&lt;br /&gt;&lt;br /&gt;Para que quede claro, ah&amp;iacute; van algunos ejemplos m&amp;aacute;s:
&lt;pre&gt;&lt;code&gt;  &lt;span style="color:green;"&gt;// &amp;Aacute;rbol de expresi&amp;oacute;n de una funci&amp;oacute;n que determina&lt;br /&gt;  // si el par&amp;aacute;metro que le llega es par&lt;/span&gt;&lt;br /&gt;  Expression&amp;lt;&lt;span style="background-color:#ffffc0;"&gt;Func&amp;lt;int, bool&amp;gt;&lt;/span&gt;&amp;gt; esPar = a =&amp;gt; a%2==0;&lt;br /&gt;&lt;br /&gt;  &lt;span style="color:green;"&gt;// &amp;Aacute;rbol de expresi&amp;oacute;n de una funci&amp;oacute;n &lt;br /&gt;  // que retorna el m&amp;aacute;ximo de dos n&amp;uacute;meros.&lt;/span&gt;&lt;br /&gt;  Expression&amp;lt;&lt;span style="background-color:#ffffc0;"&gt;Func&amp;lt;int, int, int&amp;gt;&lt;/span&gt;&amp;gt; maximo =&lt;br /&gt;              (a, b) =&amp;gt; a &amp;gt; b ? a:b;&lt;br /&gt;&lt;br /&gt;  &lt;span style="color:green;"&gt;// &amp;Aacute;rbol de expresi&amp;oacute;n de una funci&amp;oacute;n que&lt;br /&gt;  // retorna un string transformado&lt;/span&gt;&lt;br /&gt;  Expression&amp;lt;&lt;span style="background-color:#ffffc0;"&gt;Func&amp;lt;string, string&amp;gt;&lt;/span&gt;&amp;gt; TrimMays = &lt;br /&gt;              a =&amp;gt; a.Trim().ToUpper();&lt;br /&gt;&lt;br /&gt;  &lt;span style="color:green;"&gt;// &amp;Aacute;rbol de expresi&amp;oacute;n de una acci&amp;oacute;n &lt;br /&gt;  // sin par&amp;aacute;metros que escribe por consola la fecha y hora.&lt;/span&gt;&lt;br /&gt;  Expression&amp;lt;&lt;span style="background-color:#ffffc0;"&gt;Action&lt;/span&gt;&amp;gt; accion =&lt;br /&gt;              () =&amp;gt; Console.WriteLine(DateTime.Now); &lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;
&amp;nbsp;&lt;br /&gt;Fijaos que el tipo de delegado &lt;code&gt;Action&lt;/code&gt; o &lt;code&gt;Func&lt;/code&gt;, que son los par&amp;aacute;metros gen&amp;eacute;ricos de la expresi&amp;oacute;n, son los que definen los tipos de par&amp;aacute;metros y retornos de la lambda. En el primer caso, el &lt;code&gt;Func&amp;lt;int, bool&amp;gt;&lt;/code&gt; define que la funci&amp;oacute;n recibe un entero y retorna un booleano; en el &amp;uacute;ltimo caso, ni se env&amp;iacute;a ni se recibe nada, de ah&amp;iacute; que utilicemos un delegado &lt;code&gt;Action&lt;/code&gt;.&lt;br /&gt;&lt;br /&gt;Un detalle importante, antes de que se me olvide comentarlo. Los &amp;aacute;rboles de expresi&amp;oacute;n sirven, como su nombre indica, para almacenar expresiones. Esto limita el tipo de construcciones de c&amp;oacute;digo que podemos usar en las lambdas que los definen: no est&amp;aacute; permitido utilizar asignaciones, bloques con llaves { }, ni bucles... debe tratarse de una expresi&amp;oacute;n que pueda representarse en una jerarqu&amp;iacute;a de &amp;aacute;rbol. Si intentamos saltarnos estas restricciones, el compilador generar&amp;aacute; un error, aunque el tipo de delegado sea correcto y la funci&amp;oacute;n lambda tambi&amp;eacute;n, como en el siguiente ejemplo:&lt;br /&gt;
&lt;pre&gt;&lt;code&gt;  &lt;span style="color:green;"&gt;// Suma los n primeros naturales&lt;/span&gt;&lt;br /&gt;  Expression&amp;lt;&lt;span style="background-color:#ffffc0;"&gt;Func&amp;lt;int, int&amp;gt;&lt;/span&gt;&amp;gt; expr =&lt;br /&gt;&lt;span style="color:red;"&gt;    n =&amp;gt; {&lt;br /&gt;           int t = 0;&lt;br /&gt;           for (int i = 1; i &amp;lt;= n; t += i++) ;&lt;br /&gt;           return t;&lt;br /&gt;         };&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;  &lt;span style="color:green;"&gt;// Error CS0834: Una expresi&amp;oacute;n lambda con cuerpo no puede ser &lt;br /&gt;  // convertida a &amp;aacute;rbol de expresi&amp;oacute;n&lt;/span&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;
&amp;nbsp;&lt;br /&gt;&lt;img src="http://2.bp.blogspot.com/_O9D62hXq-ng/SQ2ntSUN7eI/AAAAAAAAA7M/ZZ60FYYNyR8/s400/expression-tree-2.jpg" alt="&amp;Aacute;rbol de expresi&amp;oacute;n" border="0" id="BLOGGER_PHOTO_ID_5264047935918566882" style="margin:0px 0px 10px 10px;float:right;" /&gt;Volvemos un poco atr&amp;aacute;s ahora para recordar cuando comentaba que la compilaci&amp;oacute;n de una lambda no genera c&amp;oacute;digo ejecutable correspondiente a las instrucciones definidas en la expresi&amp;oacute;n, sino el c&amp;oacute;digo para llenar el &amp;aacute;rbol de expresi&amp;oacute;n que la representa. &lt;br /&gt;&lt;br /&gt;&amp;iquest;Y c&amp;oacute;mo hace eso? Muy sencillo. El compilador analiza la expresi&amp;oacute;n, genera la secuencia de instrucciones que compone el &amp;aacute;rbol, las compila, e introduce el resultado en el ensamblado. El siguiente ejemplo muestra c&amp;oacute;mo crear un &amp;aacute;rbol de expresi&amp;oacute;n usando una lambda, y una aproximaci&amp;oacute;n al c&amp;oacute;digo equivalente que genera el compilador, para que nos podamos hacer una idea del trabajo que nos ahorra esta caracter&amp;iacute;stica del lenguaje:&lt;br /&gt;
&lt;pre style="clear:both;"&gt;&lt;code&gt;&lt;br /&gt;  &lt;span style="color:green;"&gt;// &amp;Aacute;rbol definido con una lambda:&lt;/span&gt;&lt;br /&gt;  Expression&amp;lt;Func&amp;lt;int, bool&amp;gt;&amp;gt; esPar = a =&amp;gt; a % 2 == 0;&lt;br /&gt;&lt;br /&gt;  &lt;span style="color:green;"&gt;// Y el mismo &amp;aacute;rbol definido a mano, &lt;/span&gt;&lt;br /&gt;  &lt;span style="color:green;"&gt;// lo que genera el compilador autom&amp;aacute;ticamente:&lt;/span&gt;&lt;br /&gt;  ParameterExpression param = Expression.Parameter(typeof(int), &amp;quot;a&amp;quot;);&lt;br /&gt;  ConstantExpression dos = Expression.Constant(2, typeof(int));&lt;br /&gt;  ConstantExpression cero = Expression.Constant(0, typeof(int));&lt;br /&gt;  BinaryExpression modulo = Expression.Modulo(param, dos);&lt;br /&gt;  BinaryExpression comparacion = Expression.Equal(modulo, cero);&lt;br /&gt;  Expression&amp;lt;Func&amp;lt;int, bool&amp;gt;&amp;gt; esPar2 =&lt;br /&gt;       Expression.Lambda&amp;lt;Func&amp;lt;int, bool&amp;gt;&amp;gt;(comparacion, param);&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;
&amp;nbsp;&lt;br /&gt;
&lt;h3 id="usoarboles"&gt;Uso de los &amp;aacute;rboles de expresi&amp;oacute;n&lt;/h3&gt;
Ya sabemos qu&amp;eacute; son los &amp;aacute;rboles de expresi&amp;oacute;n y c&amp;oacute;mo podemos definirlos, pero a&amp;uacute;n no le hemos visto sentido a su existencia. Pero lo tiene, vaya si lo tiene ;-)&lt;br /&gt;&lt;br /&gt;En primer lugar, el hecho de poder definir el &amp;aacute;rbol partiendo de una expresi&amp;oacute;n lambda, adem&amp;aacute;s de comodidad a la hora de codificar, nos permite aprovechar el tipado fuerte y la potencia del intellisense para evitar errores. En el ejemplo anterior, las probabilidades de que nos equivoquemos creando el &amp;aacute;rbol de forma manual son muy superiores a que ocurra si utilizamos la sintaxis lambda.&lt;br /&gt;&lt;br /&gt;Segundo, fijaos que en ning&amp;uacute;n momento se est&amp;aacute; generando c&amp;oacute;digo IL o compilando la expresi&amp;oacute;n representada por la lambda. Estamos creando una estructura en memoria. Esto quiere decir que despu&amp;eacute;s podemos procesar esta informaci&amp;oacute;n como estimemos conveniente; podemos, por ejemplo, analizar su contenido, recorrerlo, seriarlo, o transformarlo, en funci&amp;oacute;n de nuestras necesidades. Es ideal, por tanto, cuando tengamos inter&amp;eacute;s en interpretar una expresi&amp;oacute;n para realizar alguna acci&amp;oacute;n con ella.&lt;br /&gt;&lt;br /&gt;Vamos a ver ahora varios ejemplos para ilustrar el uso de las lambdas y &amp;aacute;rboles de expresi&amp;oacute;n en el mundo real.&lt;br /&gt;
&lt;h4&gt;Linq&lt;/h4&gt;
En el caso de &lt;acronym title="Language INtegrated Query"&gt;Linq&lt;/acronym&gt; aplicado a un proveedor externo de datos relacional (por ejemplo, las tecnolog&amp;iacute;as Linq to SQL, o Entity Framework), no tiene inter&amp;eacute;s alguno el c&amp;oacute;digo ejecutable asociado a una expresi&amp;oacute;n, sino su estructura, pues al final va a ser traducida al lenguaje o tecnolog&amp;iacute;a del almac&amp;eacute;n de informaci&amp;oacute;n. Supongamos la siguiente consulta para obtener los productos que comienzan por &amp;quot;S&amp;quot;:
&lt;pre&gt;&lt;code&gt;  &lt;span style="color:green;"&gt;// Usando una consulta Linq:&lt;/span&gt;&lt;br /&gt;  var datos = from p in productos &lt;br /&gt;                 where p.Nombre.StartsWith(&amp;quot;S&amp;quot;)&lt;br /&gt;                 select p;&lt;br /&gt;&lt;br /&gt;  &lt;span style="color:green;"&gt;// O su equivalente usando &lt;br /&gt;  // &lt;a href="http://www.variablenotfound.com/2008/04/chuleta-de-operadores-estndar-de.html" title="Operadores de consulta"&gt;&lt;span style="color:#35537a;"&gt;operadores de consulta&lt;/span&gt;&lt;/a&gt;:&lt;/span&gt;&lt;br /&gt;  var datos = productos.Where(&lt;span style="background-color:#ffffc0;"&gt;p=&amp;gt;p.Nombre.StartsWith(&amp;quot;S&amp;quot;)&lt;/span&gt;);&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;
&amp;nbsp;&lt;br /&gt;La lambda resaltada servir&amp;aacute; para crear un &amp;aacute;rbol de expresi&amp;oacute;n con las condiciones indicadas, pues el &lt;a href="http://www.variablenotfound.com/2008/02/mtodos-de-extensin-en-c.html" title="&amp;iquest;Qu&amp;eacute; son los m&amp;eacute;todos de extensi&amp;oacute;n?"&gt;&lt;span style="color:#35537a;"&gt;m&amp;eacute;todo de extensi&amp;oacute;n&lt;/span&gt;&lt;/a&gt; &lt;code&gt;Where&lt;/code&gt; aplicado acepta un predicado de tipo &lt;code&gt;Expression&lt;/code&gt;. No se genera ning&amp;uacute;n m&amp;eacute;todo an&amp;oacute;nimo para la expresi&amp;oacute;n lambda, ni se traduce a IL su contenido: s&amp;oacute;lo interesa para definir la expresi&amp;oacute;n que ser&amp;aacute; introducida en el &amp;aacute;rbol. M&amp;aacute;s adelante, en el momento de extraer realmente la informaci&amp;oacute;n desde el almac&amp;eacute;n correspondiente, el componente proveedor de datos recorrer&amp;aacute; y analizar&amp;aacute; la estructura en memoria, generando su equivalente en SQL, que es lo que lanzar&amp;aacute; al &lt;acronym title="Sistema Gestor de Bases de Datos"&gt;SGBD&lt;/acronym&gt; para obtener los datos.&lt;br /&gt;&lt;br /&gt;Por cierto, existen en la actualidad una gran cantidad de &lt;a hreflang="en" href="http://blogs.msdn.com/charlie/archive/2008/02/28/link-to-everything-a-list-of-linq-providers.aspx" title="Lista de proveedores Linq"&gt;proveedores de Linq&lt;/a&gt;, capaces de transformar los &amp;aacute;rboles de expresi&amp;oacute;n en consultas a casi cualquier tipo de almac&amp;eacute;n. Fijaos que la posibilidad de separar la codificaci&amp;oacute;n lambda de la interpretaci&amp;oacute;n de la expresi&amp;oacute;n hace posible su utilizaci&amp;oacute;n en una gran variedad de &amp;aacute;mbitos.&lt;br /&gt;&lt;br /&gt;
&lt;h4&gt;C&amp;aacute;lculo simb&amp;oacute;lico&lt;/h4&gt;
Otro ejemplo que ilustra muy bien las posibilidades de los &amp;aacute;rboles de expresi&amp;oacute;n, de mano del maestro &lt;a href="http://geeks.ms/blogs/ohernandez" title="Octavio Hern&amp;aacute;ndez, en Geeks.ms"&gt;&lt;span style="color:#35537a;"&gt;Octavio Hern&amp;aacute;ndez&lt;/span&gt;&lt;/a&gt;. Se trata del art&amp;iacute;culo &lt;a href="http://www.elguille.info/NET/futuro/firmas_octavio_calculo_simbolico.htm" title="C&amp;aacute;lculo simb&amp;oacute;lico en C# 3.0"&gt;&lt;span style="color:#35537a;"&gt;C&amp;aacute;lculo simb&amp;oacute;lico en C# 3.0&lt;/span&gt;&lt;/a&gt;, publicado en la web de &lt;a href="http://www.elguille.info/" title="El Guille"&gt;&lt;span style="color:#35537a;"&gt;El Guille&lt;/span&gt;&lt;/a&gt; a principios de 2007.&lt;br /&gt;&lt;br /&gt;A lo largo del art&amp;iacute;culo se realiza la implementaci&amp;oacute;n b&amp;aacute;sica de un sistema de c&amp;aacute;lculo de derivadas de funciones matem&amp;aacute;ticas partiendo de un &amp;aacute;rbol de expresiones. El proceso, que el autor va explicando paso a paso, consiste en analizar el &amp;aacute;rbol, e ir generando otro &amp;aacute;rbol con el resultado de la derivaci&amp;oacute;n de cada expresi&amp;oacute;n encontrada. A continuaci&amp;oacute;n se muestra la porci&amp;oacute;n de c&amp;oacute;digo donde se realiza la derivaci&amp;oacute;n de una operaci&amp;oacute;n de suma, utilizando recursividad para derivar adem&amp;aacute;s cada uno de los sumandos:
&lt;pre&gt;&lt;code&gt;  private static Expression Derive(this Expression e, string paramName)&lt;br /&gt;  {&lt;br /&gt;      switch (e.NodeType)&lt;br /&gt;      {&lt;br /&gt;          [...]&lt;br /&gt;          &lt;span style="color:green;"&gt;// sum rule&lt;/span&gt;&lt;br /&gt;          case ExpressionType.Add:&lt;br /&gt;              {&lt;br /&gt;                  Expression dleft = &lt;br /&gt;                     ((BinaryExpression) e).Left.Derive(paramName);&lt;br /&gt;                  Expression dright = &lt;br /&gt;                     ((BinaryExpression) e).Right.Derive(paramName);&lt;br /&gt;                  return Expression.Add(dleft, dright);&lt;br /&gt;              }&lt;br /&gt;          [...]&lt;br /&gt;      }&lt;br /&gt;  }&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;
&amp;nbsp;&lt;br /&gt;Al final, fijaos que de nuevo no nos interesa en absoluto la lambda como funci&amp;oacute;n an&amp;oacute;nima ni delegado, sino la estructura de la propia expresi&amp;oacute;n, de forma que podamos recorrerla y transformarla en otra expresi&amp;oacute;n, en este caso la funci&amp;oacute;n derivada de la original. El siguiente ejemplo muestra el uso de esta clase:
&lt;pre&gt;&lt;code&gt;   Expression&amp;lt;Func&amp;lt;double, double&amp;gt;&amp;gt; &lt;br /&gt;                funcion = x =&amp;gt; x*x;          &lt;span style="color:green;"&gt;// f(x)=x^2&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;  Expression&amp;lt;Func&amp;lt;double, double&amp;gt;&amp;gt; &lt;br /&gt;                derivada = funcion.Derive(); &lt;span style="color:green;"&gt;// f&amp;#39;(x)=2*x&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;  Console.WriteLine(derivada); &lt;span style="color:green;"&gt;// Muestra la funci&amp;oacute;n derivada:&lt;br /&gt;                               //    x =&amp;gt; ((x * 1) + (1 * x))&lt;/span&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;
&amp;nbsp;&lt;br /&gt;Creedme, vale la pena &lt;a href="http://www.elguille.info/NET/futuro/firmas_octavio_calculo_simbolico.htm" title="C&amp;aacute;lculo simb&amp;oacute;lico en C# 3.0"&gt;&lt;span style="color:#35537a;"&gt;echarle un vistazo&lt;/span&gt;&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;
&lt;h4&gt;ASP.NET MVC&lt;/h4&gt;
Un &amp;uacute;ltimo ejemplo, que demuestra la versatilidad del uso de lambdas y &amp;aacute;rboles de expresi&amp;oacute;n en multitud de escenarios. En el &lt;a href="http://www.asp.net/mvc" title="Sitio oficial de ASP.NET MVC"&gt;&lt;span style="color:#35537a;"&gt;framework ASP.NET MVC&lt;/span&gt;&lt;/a&gt;, es posible crear enlaces hacia acciones desde dentro de las vistas (p&amp;aacute;ginas .ASPX), que no son sino m&amp;eacute;todos dentro de unas clases concretas llamadas &amp;quot;controladores&amp;quot;. El caso es que para hacer referencia a un m&amp;eacute;todo del controlador, pueden utilizarse estas dos v&amp;iacute;as, de resultado id&amp;eacute;ntico:
&lt;pre&gt;&lt;code&gt;  &lt;span style="color:green;"&gt;// Obtiene un enlace al m&amp;eacute;todo &amp;quot;ChangePassword&amp;quot;&lt;br /&gt;  // de la clase &amp;quot;AccountController&amp;quot;:&lt;/span&gt;&lt;br /&gt;  Html.ActionLink(&amp;quot;Cambiar clave&amp;quot;, &amp;quot;ChangePassword&amp;quot;, &amp;quot;Account&amp;quot;)&lt;br /&gt;&lt;br /&gt;  &lt;span style="color:green;"&gt;// Lo mismo, pero usando un &amp;aacute;rbol de expresi&amp;oacute;n:&lt;/span&gt;&lt;br /&gt;  Html.ActionLink&amp;lt;AccountController&amp;gt;&lt;br /&gt;              (acc=&amp;gt;acc.ChangePassword(), &amp;quot;Cambiar clave&amp;quot;)&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;
&amp;nbsp;&lt;br /&gt;Aunque el resultado es el mismo, la segunda usa un &amp;aacute;rbol de expresi&amp;oacute;n para realizar la referencia al m&amp;eacute;todo &lt;code&gt;ChangePassword&lt;/code&gt; de la clase &lt;code&gt;AccountController&lt;/code&gt;. La implementaci&amp;oacute;n del m&amp;eacute;todo &lt;code&gt;ActionLink&lt;/code&gt; recorre el &amp;aacute;rbol generado desde la expresi&amp;oacute;n lambda para obtener el nombre del controlador y del m&amp;eacute;todo, por lo que es equivalente a primera f&amp;oacute;rmula, pero benefici&amp;aacute;ndose de las ventajas del tipado fuerte y del &lt;em&gt;intellisense&lt;/em&gt; en la edici&amp;oacute;n.&lt;br /&gt;
&lt;h3&gt;Los &amp;aacute;rboles de expresi&amp;oacute;n como c&amp;oacute;digo ejecutable&lt;/h3&gt;
Hasta ahora siempre me he referido a los &amp;aacute;rboles de expresi&amp;oacute;n como entidades de almacenamiento. De alguna u otra forma, estaba equiparando su utilidad a la cualquier estructura de datos que permitiera guardar y procesar informaci&amp;oacute;n, lo cual es cierto pero s&amp;oacute;lo parcialmente.&lt;br /&gt;&lt;br /&gt;Los &amp;aacute;rboles de expresi&amp;oacute;n aportan una caracter&amp;iacute;stica adicional: se pueden convertir en c&amp;oacute;digo ejecutable. Es decir, &lt;strong&gt;es posible compilar un &amp;aacute;rbol de expresi&amp;oacute;n&lt;/strong&gt; en tiempo de ejecuci&amp;oacute;n, dando lugar a una funci&amp;oacute;n an&amp;oacute;nima a la que podemos tener acceso, es decir, invocarla, a trav&amp;eacute;s de sus delegados.&lt;br /&gt;&lt;br /&gt;Ve&amp;aacute;moslo con un caso concreto. Retomando el ejemplo de obtenci&amp;oacute;n de derivadas, ser&amp;iacute;a perfectamente posible obtener el valor de la funci&amp;oacute;n derivada en un punto ampliando ligeramente el c&amp;oacute;digo visto anteriormente:
&lt;pre&gt;&lt;code&gt;  Expression&amp;lt;Func&amp;lt;double, double&amp;gt;&amp;gt; &lt;br /&gt;                funcion = x =&amp;gt; x*x;          &lt;span style="color:green;"&gt;// f(x)=x^2&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;  Expression&amp;lt;Func&amp;lt;double, double&amp;gt;&amp;gt; &lt;br /&gt;                derivada = funcion.Derive(); &lt;span style="color:green;"&gt;// f&amp;#39;(x)=2*x&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;  &lt;span style="color:green;"&gt;// Compilamos la funci&amp;oacute;n derivada&lt;br /&gt;  // y obtenemos un delegado a la misma:&lt;/span&gt;&lt;br /&gt;  Func&amp;lt;double, double&amp;gt; funcDerivada = derivada.Compile();&lt;br /&gt;&lt;br /&gt;  double result = funcDerivada(6); &lt;span style="color:green;"&gt;// Obtenemos el valor de la funci&amp;oacute;n &lt;br /&gt;                                   // invocando al delegado con x=6&lt;/span&gt;&lt;br /&gt;  Console.WriteLine(result);       &lt;span style="color:green;"&gt;// Muestra &amp;quot;12&amp;quot;&lt;/span&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;
&amp;nbsp;&lt;br /&gt;Como se puede observar en el c&amp;oacute;digo, la llamada al m&amp;eacute;todo &lt;code&gt;Compile()&lt;/code&gt; devuelve un delegado del tipo &lt;code&gt;Func&lt;/code&gt; indicado en el par&amp;aacute;metro gen&amp;eacute;rico de la expresi&amp;oacute;n, que apunta hacia la funci&amp;oacute;n an&amp;oacute;nima creada &amp;quot;al vuelo&amp;quot; a partir de las expresiones contenidas en el &amp;aacute;rbol. Es decir, desde la definici&amp;oacute;n simb&amp;oacute;lica contenida en el &amp;aacute;rbol &amp;iexcl;obtenemos c&amp;oacute;digo ejecutable!&lt;br /&gt;&lt;br /&gt;Aunque espectacular, en realidad no hay nada m&amp;aacute;gico en esta caracter&amp;iacute;stica: se trata de ir recorriendo el &amp;aacute;rbol y emitiendo el c&amp;oacute;digo IL correspondiente a cada expresi&amp;oacute;n, que est&amp;aacute; perfectamente tipificada y definida. En el namespace &lt;code&gt;System.Linq.Expressions&lt;/code&gt; existe una bonita clase interna llamada &lt;code&gt;ExpressionCompiler&lt;/code&gt; que se dedica exclusivamente a ello, utilizando herramientas suministradas por &lt;code&gt;System.Reflection.Emit&lt;/code&gt;, como los generadores de lenguaje intermedio &lt;code&gt;ILGenerator&lt;/code&gt;.&lt;br /&gt;
&lt;h3&gt;&amp;iexcl;Y hasta aqu&amp;iacute; hemos llegado!&lt;/h3&gt;
A lo largo de estos tres posts hemos recorrido las principales caracter&amp;iacute;sticas y utilidades de las expresiones lambda. Obviamente, han quedado cosas por detr&amp;aacute;s; no era objetivo de esta serie profundizar demasiado, sino ofrecer una visi&amp;oacute;n suficiente para animar a los desarrolladores a utilizar esta potente caracter&amp;iacute;stica que nos ofrece C# (y VB.NET).&lt;br /&gt;&lt;br /&gt;Espero que os haya sido una lectura &amp;uacute;til, al menos tanto como me ha resultado a m&amp;iacute; su escritura. Ah, y para consultas, sugerencias o puntualizaciones, por aqu&amp;iacute; me ten&amp;eacute;is.&lt;br /&gt;&lt;br /&gt;Publicado en: &lt;a href="http://www.variablenotfound.com"&gt;&lt;span style="color:#35537a;"&gt;www.variablenotfound.com&lt;/span&gt;&lt;/a&gt;. &lt;/div&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=147571" width="1" height="1"&gt;</description><category domain="http://geeks.ms/blogs/jmaguilar/archive/tags/c_2300_/default.aspx">c#</category><category domain="http://geeks.ms/blogs/jmaguilar/archive/tags/vs2008/default.aspx">vs2008</category><category domain="http://geeks.ms/blogs/jmaguilar/archive/tags/linq/default.aspx">linq</category><category domain="http://geeks.ms/blogs/jmaguilar/archive/tags/_26002300_225_3B00_rboles+de+expresi_26002300_243_3B00_n/default.aspx">&amp;#225;rboles de expresi&amp;#243;n</category><category domain="http://geeks.ms/blogs/jmaguilar/archive/tags/lambdas/default.aspx">lambdas</category></item><item><title>C#: Desmitificando las expresiones lambda (II)</title><link>http://geeks.ms/blogs/jmaguilar/archive/2009/04/21/c-desmitificando-las-expresiones-lambda-ii.aspx</link><pubDate>Tue, 21 Apr 2009 21:54:00 GMT</pubDate><guid isPermaLink="false">2a2e7ade-7474-448b-9de5-1515d8bb7d1b:147071</guid><dc:creator>José M. Aguilar</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/jmaguilar/rsscomments.aspx?PostID=147071</wfw:commentRss><comments>http://geeks.ms/blogs/jmaguilar/archive/2009/04/21/c-desmitificando-las-expresiones-lambda-ii.aspx#comments</comments><description>&lt;div class="post-body entry-content"&gt;&lt;span&gt;
&lt;div class="post-header-line-1"&gt;&lt;/div&gt;
&lt;div class="post-body entry-content"&gt;
&lt;p&gt;&lt;img src="http://3.bp.blogspot.com/_O9D62hXq-ng/SQtrgaCIm9I/AAAAAAAAA6k/XuuGqsiLjkw/s200/lambdas.jpg" alt="Lambda" border="0" id="BLOGGER_PHOTO_ID_5263418794000817106" style="margin:0px 0px 10px 10px;float:right;" /&gt;En el &lt;a href="http://www.variablenotfound.com/2009/03/c-desmitificando-las-expresiones-lambda.html"&gt;&lt;span style="color:#35537a;"&gt;post anterior&lt;/span&gt;&lt;/a&gt; intentamos realizar una primera aproximaci&amp;oacute;n a las expresiones lambda, centr&amp;aacute;ndonos en obtener una definici&amp;oacute;n lo suficientemente cercana, que nos permitiera conocer a grandes rasgos qu&amp;eacute; son, as&amp;iacute; como en describir su forma general y sus particularidades sint&amp;aacute;cticas.&lt;br /&gt;&lt;br /&gt;En esta segunda entrega vamos a profundizar un poco en el papel de las expresiones lambda como v&amp;iacute;a para definir muy r&amp;aacute;pidamente funciones an&amp;oacute;nimas y los tipos de delegados con los que podemos referenciarlas, y por tanto, invocarlas.&lt;br /&gt;&lt;br /&gt;Ya en el tercer post describiremos el papel de las &lt;a href="http://www.variablenotfound.com/2009/03/c-desmitificando-las-expresiones-lambda_2829.html"&gt;&lt;span style="color:#35537a;"&gt;expresiones lambda como herramienta de generaci&amp;oacute;n de &amp;aacute;rboles de expresi&amp;oacute;n&lt;/span&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id="funciones"&gt;Las lambdas como funciones an&amp;oacute;nimas&lt;/h3&gt;
Como hab&amp;iacute;amos insinuado anteriormente, uno de los usos de las expresiones lambda es permitir la definici&amp;oacute;n &amp;quot;en l&amp;iacute;nea&amp;quot; de funciones an&amp;oacute;nimas. De hecho, en tiempo de compilaci&amp;oacute;n las expresiones lambda son convertidas en m&amp;eacute;todos a los que el compilador establece un nombre &amp;uacute;nico autogenerado, como los ejemplos mostrados a continuaci&amp;oacute;n:&lt;br /&gt;&lt;br /&gt;&lt;img src="http://1.bp.blogspot.com/_O9D62hXq-ng/SQww-8_vZJI/AAAAAAAAA68/qPY91CUBI8s/s400/lambda-anonimas.jpg" alt="Transformaci&amp;oacute;n de lamdas en m&amp;eacute;todos" border="0" id="BLOGGER_PHOTO_ID_5263635922572764306" style="text-align:center;margin:0px auto 10px;display:block;" /&gt;&lt;br /&gt;Las referencias a estas funciones an&amp;oacute;nimas son transformadas en delegados (punteros) a las mismas, lo que nos permitir&amp;aacute;, por ejemplo, invocarlas desde el c&amp;oacute;digo. En la pr&amp;aacute;ctica esto quiere decir que podemos asignar una lambda a una variable y ejecutarla como muestra el siguiente pseudoc&amp;oacute;digo:
&lt;pre&gt;&lt;code&gt;&lt;br /&gt;  delegado &lt;strong&gt;duplica&lt;/strong&gt; = &lt;span style="background-color:#ffffc0;"&gt;x =&amp;gt; x * 2&lt;/span&gt;; &lt;br /&gt;  escribe &lt;strong&gt;duplica(2)&lt;/strong&gt;; &lt;span style="color:green;"&gt;// Escribe un 4&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&amp;nbsp;&lt;br /&gt;En este primer acercamiento, fijaos que &lt;code&gt;duplica&lt;/code&gt; es el nombre del delegado, la funci&amp;oacute;n definida en forma de expresi&amp;oacute;n lambda no tiene nombre, ser&amp;aacute; el compilador el que se asigne uno. &lt;br /&gt;&lt;br /&gt;Veamos c&amp;oacute;mo se concreta esta idea en C#. En el siguiente c&amp;oacute;digo, la variable &lt;code&gt;duplica&lt;/code&gt; &lt;em&gt;apunta&lt;/em&gt; hacia una funci&amp;oacute;n an&amp;oacute;nima definida a trav&amp;eacute;s de la expresi&amp;oacute;n lambda en cuya implementaci&amp;oacute;n lo &amp;uacute;nico que se hace es retornar el doble del valor que le llega como par&amp;aacute;metro. Vemos tambi&amp;eacute;n c&amp;oacute;mo podemos utilizarla de forma directa:
&lt;pre&gt;&lt;code&gt;  Func&amp;lt;int, int&amp;gt; &lt;strong&gt;duplica &lt;/strong&gt;= &lt;span style="background-color:#ffffc0;"&gt;x =&amp;gt; x * 2&lt;/span&gt;;&lt;br /&gt;  int result = &lt;strong&gt;duplica&lt;/strong&gt;(7); &lt;span style="color:green;"&gt;// result vale 14&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&amp;nbsp;&lt;br /&gt;S&amp;oacute;lo con objeto de que pod&amp;aacute;is entender el c&amp;oacute;digo anterior, os adelantar&amp;eacute; que la porci&amp;oacute;n &lt;code&gt;Func&amp;lt;int, int&amp;gt;&lt;/code&gt; es una forma r&amp;aacute;pida de tipificar el delegado, indicando que &lt;code&gt;duplica&lt;/code&gt; apunta a una funci&amp;oacute;n que espera un entero como par&amp;aacute;metro de entrada, y que su valor de retorno ser&amp;aacute; otro entero. Esto lo veremos dentro de un momento.&lt;br /&gt;&lt;br /&gt;De la misma forma que asignamos la expresi&amp;oacute;n lambda a una variable, podemos hacerlo tambi&amp;eacute;n para indicar el valor de un par&amp;aacute;metro a un m&amp;eacute;todo que acepte un delegado concreto. Por ejemplo, el siguiente c&amp;oacute;digo muestra un m&amp;eacute;todo llamado &lt;code&gt;calcula&lt;/code&gt; que recibe un valor entero y una referencia a una funci&amp;oacute;n, retornando el resultado de efectuar dicha operaci&amp;oacute;n sobre el entero proporcionado:
&lt;pre&gt;&lt;code&gt;  &lt;span style="color:green;"&gt;// Es m&amp;eacute;todo ejecuta la funci&amp;oacute;n indicada por&lt;br /&gt;  // el par&amp;aacute;metro &lt;em&gt;operacion&lt;/em&gt;, envi&amp;aacute;ndole el &lt;em&gt;valor&lt;/em&gt; especificado, &lt;br /&gt;  // y retorna el resultado obtenido de la misma.&lt;/span&gt;&lt;br /&gt;  public int calcula(int valor, Func&amp;lt;int, int&amp;gt; operacion)&lt;br /&gt;  {&lt;br /&gt;    return operacion(valor); &lt;span style="color:green;"&gt;// retorna el resultado de aplicar la &lt;br /&gt;                             // expresi&amp;oacute;n indicada al valor.&lt;/span&gt;&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  &lt;span style="color:green;"&gt;// Usos posibles:&lt;/span&gt;&lt;br /&gt;  int i = calcula(4, &lt;span style="background-color:#ffffc0;"&gt;x =&amp;gt; x / 2&lt;/span&gt;); &lt;span style="color:green;"&gt;// Le pasamos una referencia a la &lt;br /&gt;                                  // funci&amp;oacute;n que estamos definiendo sobre&lt;br /&gt;                                  // la marcha. El resultado es que i=2.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;  int j = calcula(4, &lt;strong&gt;duplica&lt;/strong&gt;);    &lt;span style="color:green;"&gt;// Le pasamos la variable &amp;quot;duplica&amp;quot;, &lt;br /&gt;                                  // que es una referencia a la lambda&lt;br /&gt;                                  // definida anteriormente. J valdr&amp;aacute; 8.&lt;/span&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;
&amp;nbsp;&lt;br /&gt;
&lt;div style="background-color:#fffff0;margin-left:4em;border:#c0c0c0 1px dotted;padding:5px;"&gt;&amp;lt;HistoriaDelAbuelete&amp;gt;&lt;br /&gt;Seguro que a los m&amp;aacute;s viejos del lugar esto le recuerda a los &lt;a hreflang="en" href="http://www.leylan.com/app.asp?pg=blocks" title="They&amp;#39;re Mysterious... They&amp;#39;re Code Blocks"&gt;Codeblocks&lt;/a&gt; que utiliz&amp;aacute;bamos en &lt;a href="http://es.wikipedia.org/wiki/Clipper_(lenguaje_de_programaci%C3%B3n)" title="El Lenguaje Clipper"&gt;&lt;span style="color:#35537a;"&gt;Clipper&lt;/span&gt;&lt;/a&gt; a principios de los 90 (uuf, c&amp;oacute;mo pasa el tiempo...). &amp;iquest;Todav&amp;iacute;a reconoc&amp;eacute;is el siguiente c&amp;oacute;digo?
&lt;pre&gt;&lt;code&gt;  bDuplica := { |n| n*2 }&lt;br /&gt;  ? EVAL(bDuplica, 7)     // Muestra un 14&lt;/code&gt;&lt;/pre&gt;
&amp;nbsp;&amp;lt;/HistoriaDelAbuelete&amp;gt;&lt;/div&gt;
&lt;br /&gt;Una consecuencia directa de que las expresiones lambdas sean referenciadas a trav&amp;eacute;s de delegados es que &lt;strong&gt;podemos utilizarlas en cualquier sitio donde se acepte un delegado&lt;/strong&gt;, con la &amp;uacute;nica precauci&amp;oacute;n de escribirla teniendo en cuenta el tipo de su retorno y los par&amp;aacute;metros que recibe. Un ejemplo claro lo tenemos en la suscripci&amp;oacute;n a eventos, donde la t&amp;eacute;cnica habitual consiste en utilizar un delegado a un m&amp;eacute;todo en el que se implementa la l&amp;oacute;gica del tratamiento de los mismos, algo como:&lt;br /&gt;
&lt;pre&gt;&lt;code&gt;  &lt;span style="color:green;"&gt;// Nos suscribimos al evento MouseMove:&lt;/span&gt;&lt;br /&gt;  this.MouseMove += &lt;span style="background-color:#ffffc0;"&gt;new MouseEventHandler(this.Form1_MouseMove);&lt;/span&gt;&lt;br /&gt;  [...]&lt;br /&gt;&lt;br /&gt;  &lt;span style="color:green;"&gt;// Tratamiento del evento MouseMove:&lt;/span&gt;&lt;br /&gt;  private void Form1_MouseMove(object sender, MouseEventArgs e)&lt;br /&gt;  {&lt;br /&gt;    this.Text = e.X + &amp;quot;,&amp;quot; + e.Y;&lt;br /&gt;  }&lt;/code&gt;&lt;/pre&gt;
&amp;nbsp;&lt;br /&gt;Como sabemos, podemos suscribirnos al evento &lt;code&gt;MouseMove&lt;/code&gt; a&amp;ntilde;adi&amp;eacute;ndole delegados del tipo &lt;code&gt;MouseEventHandler&lt;/code&gt;, definido en &lt;code&gt;System.Windows.Forms&lt;/code&gt;, cuya firma indica que recibe un par&amp;aacute;metro de tipo &lt;code&gt;object&lt;/code&gt;, otro de tipo &lt;code&gt;MouseEventArgs&lt;/code&gt; y no retorna ning&amp;uacute;n valor, exactamente igual que ser&amp;iacute;a un delegado an&amp;oacute;nimo (C# 2.0) escrito as&amp;iacute;:&lt;br /&gt;
&lt;pre&gt;&lt;code&gt;  this.MouseMove += delegate(object sender, MouseEventArgs args)&lt;br /&gt;  {&lt;br /&gt;    this.Text = args.X + &amp;quot;,&amp;quot; + args.Y;&lt;br /&gt;  };&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;
&amp;nbsp;&lt;br /&gt;Y dado que las lambdas pueden sustituir de forma directa a cualquier delegado, podemos utilizarlas para conseguir un c&amp;oacute;digo m&amp;aacute;s compacto:&lt;br /&gt;
&lt;pre&gt;&lt;code&gt;  this.MouseMove += &lt;span style="background-color:#ffffc0;"&gt;(sender, args) =&amp;gt; {&lt;/span&gt;&lt;br /&gt;                    &lt;span style="background-color:#ffffc0;"&gt;   this.Text = args.X + &amp;quot;,&amp;quot; + args.Y;&lt;/span&gt;&lt;br /&gt;                    &lt;span style="background-color:#ffffc0;"&gt;};&lt;/span&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;
&amp;nbsp;&lt;br /&gt;Llegados a este punto es conveniente aclarar que las expresiones lambda son caracter&amp;iacute;sticas introducidas en los lenguajes, y por tanto en sus compiladores, pero no en la plataforma de ejecuci&amp;oacute;n (CLR) en s&amp;iacute;. Por tanto, todo lo descrito hasta el momento era posible realizarlo antes que las lambda aparecieran por el horizonte, aunque de forma un poco m&amp;aacute;s tediosa, utilizando mecanismos que la versi&amp;oacute;n 2.0 del framework pon&amp;iacute;a a nuestra disposici&amp;oacute;n, como los delegados y m&amp;eacute;todos an&amp;oacute;nimos. En este sentido, el uso de expresiones lambda aportan mucha simplicidad, elegancia y legibilidad al c&amp;oacute;digo.&lt;br /&gt;&lt;br /&gt;Esto explica, adem&amp;aacute;s, que Visual Studio 2008 sea capaz de generar c&amp;oacute;digo para .NET 2.0 a partir de c&amp;oacute;digo fuente C# 3.0.&lt;br /&gt;&lt;br /&gt;
&lt;h3 id="tiposdelegados"&gt;Tipos de delegados de expresiones lambda&lt;/h3&gt;
Antes ya hab&amp;iacute;a adelantado que la definici&amp;oacute;n &lt;code&gt;Func&amp;lt;int, int&amp;gt;&lt;/code&gt; era simplemente una forma de indicar el tipo del par&amp;aacute;metro que recib&amp;iacute;a la funci&amp;oacute;n lambda, as&amp;iacute; como el tipo del valor de retorno. En realidad, lo &amp;uacute;nico que est&amp;aacute;bamos haciendo era definir, de forma muy sencilla y r&amp;aacute;pida, el delegado hacia la funci&amp;oacute;n. &lt;br /&gt;&lt;br /&gt;Vamos a concretar esto un poco m&amp;aacute;s, pero antes de continuar, una cosa: si para t&amp;iacute; un gen&amp;eacute;rico es un &lt;a href="http://es.wikipedia.org/wiki/Medicamento_gen%C3%A9rico" title="Medicamentos gen&amp;eacute;ricos en la Wikipedia"&gt;&lt;span style="color:#35537a;"&gt;tipo de medicamento&lt;/span&gt;&lt;/a&gt;, mejor que leas algo sobre el tema antes de continuar, pues en caso contrario es posible que te pierdas un poco ;-). Pues probar leyendo una &lt;a href="http://www.variablenotfound.com/2007/03/generics-en-c.html" title="Introducci&amp;oacute;n a los generics"&gt;&lt;span style="color:#35537a;"&gt;introducci&amp;oacute;n a los generics en c#&lt;/span&gt;&lt;/a&gt;, o la &lt;a href="http://msdn.microsoft.com/es-es/library/512aeb7t(VS.80).aspx" title="Tipos gen&amp;eacute;ricos"&gt;&lt;span style="color:#35537a;"&gt;Gu&amp;iacute;a de programaci&amp;oacute;n de C#&lt;/span&gt;&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;.NET Framework ofrece en el espacio de nombres &lt;code&gt;System&lt;/code&gt; un conjunto de definiciones de gen&amp;eacute;ricas de delegados para que podamos utilizarlos para &amp;quot;apuntar&amp;quot; hacia las funciones definidas mediante expresiones lambda, llamados &lt;code&gt;Action&lt;/code&gt; y &lt;code&gt;Func&lt;/code&gt;.&lt;br /&gt;&lt;br /&gt;Utilizaremos los tipos &lt;code&gt;Func&lt;/code&gt; para definir referencias a expresiones lambda que retornen un valor, o sea, funciones. De ah&amp;iacute; su nombre. Los tipos &lt;code&gt;Action&lt;/code&gt;, en cambio, est&amp;aacute;n destinados a referenciar a lambdas que realicen acciones y que no retornen ning&amp;uacute;n valor. De ah&amp;iacute; su nombre tambi&amp;eacute;n. ;-)&lt;br /&gt;&lt;br /&gt;Una de estas definiciones es la que hab&amp;iacute;amos usado en un ejemplo anterior:
&lt;pre&gt;&lt;code&gt;  &lt;span style="background-color:#ffffc0;"&gt;&lt;strong&gt;Func&amp;lt;int, int&amp;gt;&lt;/strong&gt;&lt;/span&gt; duplica = x =&amp;gt; x * 2;&lt;/code&gt;&lt;/pre&gt;
&amp;nbsp;&lt;br /&gt;Como se puede observar, al tratarse de una referencia a una funci&amp;oacute;n que retorna un valor, hemos utilizado un tipo &lt;code&gt;Func&lt;/code&gt; con dos par&amp;aacute;metros gen&amp;eacute;ricos, que corresponde con la siguiente declaraci&amp;oacute;n existente en el espacio de nombres &lt;code&gt;System&lt;/code&gt;:&lt;br /&gt;
&lt;pre&gt;&lt;code&gt;  public delegate TResult Func&amp;lt;T, TResult&amp;gt;(T arg);&lt;/code&gt;&lt;/pre&gt;
&amp;nbsp;&lt;br /&gt;Por ello, cuando declar&amp;aacute;bamos que la variable &lt;code&gt;duplica&lt;/code&gt; era del tipo &lt;code&gt;Func&amp;lt;int, int&amp;gt;&lt;/code&gt;, lo que indic&amp;aacute;bamos era, en primer lugar que el par&amp;aacute;metro que necesitaba la lambda era un &lt;code&gt;int&lt;/code&gt;, y que &amp;eacute;sta nos devolver&amp;iacute;a tambi&amp;eacute;n un &lt;code&gt;int&lt;/code&gt;, es decir, lo mismo que si hubi&amp;eacute;ramos definido &lt;code&gt;duplica&lt;/code&gt; as&amp;iacute;, utilizando m&amp;eacute;todos an&amp;oacute;nimos de C# 2.0:&lt;br /&gt;
&lt;pre&gt;&lt;code&gt;  &lt;span style="color:green;"&gt;// En el &amp;aacute;rea de declaraciones:&lt;/span&gt;&lt;br /&gt;  public delegate int Duplicador(int arg);&lt;br /&gt;  &lt;span style="color:blue;"&gt;...&lt;/span&gt;&lt;br /&gt;  &lt;span style="color:green;"&gt;// En el c&amp;oacute;digo:&lt;/span&gt;&lt;br /&gt;  Duplicador duplica = delegate(int k) { return k*2 };&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;
&amp;nbsp;&lt;br /&gt;Obviamente, la sintaxis lambda es mucho m&amp;aacute;s compacta y expresiva.&lt;br /&gt;&lt;br /&gt;En la pr&amp;aacute;ctica, lo &amp;uacute;nico que tenemos que tener claro a la hora de referenciar una funci&amp;oacute;n lambda es el tipo de cada uno de los par&amp;aacute;metros que usa, y el tipo de retorno. Estos se introducen, en ese orden, en los par&amp;aacute;metros gen&amp;eacute;ricos de la clase &lt;code&gt;Func&lt;/code&gt; y listo. Como esto debe quedar claro, ah&amp;iacute; van unos ejemplos de definici&amp;oacute;n y uso:
&lt;pre&gt;&lt;code&gt;  &lt;span style="color:green;"&gt;// Recibe un entero y retorna un booleano:&lt;/span&gt;&lt;br /&gt;  Func&amp;lt;int, bool&amp;gt; esPar = x =&amp;gt; x%2==0;     &lt;br /&gt;  Console.WriteLine(esPar(2)); &lt;span style="color:green;"&gt;// Muestra &amp;quot;True&amp;quot;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;  &lt;span style="color:green;"&gt;// Recibe dos enteros, retorna otro entero:&lt;/span&gt;&lt;br /&gt;  Func&amp;lt;int, int, int&amp;gt; suma = (a,b) =&amp;gt; a+b;&lt;br /&gt;  Console.WriteLine(suma(2,3)); &lt;span style="color:green;"&gt;// Muestra &amp;quot;5&amp;quot;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;  &lt;span style="color:green;"&gt;// No recibe nada, retorna un texto:&lt;/span&gt;&lt;br /&gt;  Func&amp;lt;string&amp;gt; hora = () =&amp;gt; &amp;quot;Son las &amp;quot;&lt;br /&gt;                             + DateTime.Now.ToShortTimeString();&lt;br /&gt;  Console.WriteLine(hora()); &lt;span style="color:green;"&gt;// Muestra &amp;quot;Son las 14:21:10&amp;quot;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;
&amp;nbsp;&lt;br /&gt;Es importante saber que en el framework est&amp;aacute;n definidos los delegados &lt;code&gt;Func&amp;lt;tipo1, tipo2..., tipoResult&amp;gt;&lt;/code&gt; para funciones de hasta cuatro par&amp;aacute;metros. Si necesitamos m&amp;aacute;s deberemos definir los delegados a mano, aunque esto es realmente sencillo utilizando una de las declaraciones existentes y a&amp;ntilde;adi&amp;eacute;ndole el n&amp;uacute;mero de par&amp;aacute;metros que deseemos. Por ejemplo, para seis par&amp;aacute;metros la definici&amp;oacute;n del gen&amp;eacute;rico ser&amp;iacute;a algo as&amp;iacute; como:
&lt;pre&gt;&lt;code&gt;  public delegate &lt;br /&gt;         TResult Func&amp;lt;T1, T2, T3, T4, T5, T6, TResult&amp;gt;&lt;br /&gt;                 (T1 p1, T2 p2, T3 p3, T4 p4, T5 p5, T6 p6);&lt;/code&gt;&lt;/pre&gt;
&amp;nbsp;&lt;br /&gt;Pero ahora aparece un peque&amp;ntilde;o problema: las funciones sin retorno no pueden referenciarse con delegados de tipo &lt;code&gt;Func&lt;/code&gt;, puesto que el framework .NET no soporta la instanciaci&amp;oacute;n de tipos gen&amp;eacute;ricos utilizando par&amp;aacute;metros &lt;code&gt;void&lt;/code&gt; (&lt;a hreflang="en" href="http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-335.pdf" title="Common Language Infrastructure (CLI)"&gt;ECMA 335&lt;/a&gt;, secci&amp;oacute;n 9.4, p&amp;aacute;g. 153). Por tanto, no podr&amp;iacute;amos declarar un delegado como &lt;code&gt;Func&amp;lt;int, void&amp;gt;&lt;/code&gt; para apuntar hacia una funci&amp;oacute;n que recibe un entero y no devuelve nada. Si lo pens&amp;aacute;is un poco, este es el motivo de que no exista ninguna sobrecarga de la clase &lt;code&gt;Func&lt;/code&gt; sin par&amp;aacute;metros gen&amp;eacute;ricos, pues como m&amp;iacute;nimo debemos indicar el tipo del valor de retorno.&lt;br /&gt;&lt;br /&gt;La clave para cubrir estos casos se encuentra en el tipo &lt;code&gt;Action&lt;/code&gt;. Como comentaba unas l&amp;iacute;neas m&amp;aacute;s arriba, el objeto de estos tipos de delegados es apuntar a expresiones lambda que realicen acciones y que no retornen ning&amp;uacute;n valor, por lo que sus par&amp;aacute;metros gen&amp;eacute;ricos describir&amp;aacute;n exclusivamente los tipos de los par&amp;aacute;metros de la funci&amp;oacute;n. En este caso, como es obvio, s&amp;iacute; existe una clase no parametrizada &lt;code&gt;Action&lt;/code&gt; para apuntar a funciones sin par&amp;aacute;metros, adem&amp;aacute;s de disponer de gen&amp;eacute;ricos que cubren las acciones de hasta cuatro par&amp;aacute;metros. Veamos unos ejemplos:&lt;br /&gt;
&lt;pre&gt;&lt;code&gt;  &lt;span style="color:green;"&gt;// Acci&amp;oacute;n sin par&amp;aacute;metros (no gen&amp;eacute;rica):&lt;/span&gt;&lt;br /&gt;  Action saluda = () =&amp;gt; Console.WriteLine(&amp;quot;hola&amp;quot;);&lt;br /&gt;  saluda();  &lt;span style="color:green;"&gt;// Muestra &amp;quot;hola&amp;quot;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;  &lt;span style="color:green;"&gt;// Acci&amp;oacute;n que recibe un string&lt;/span&gt;&lt;br /&gt;  Action&amp;lt;string&amp;gt; apaga = motivo =&amp;gt; { &lt;br /&gt;                                      log(motivo);&lt;br /&gt;                                      shutdown();&lt;br /&gt;                                   };&lt;br /&gt;  apaga(&amp;quot;mantenimiento&amp;quot;); &lt;span style="color:green;"&gt;// Apaga el sistema&lt;/span&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;
&amp;nbsp;&lt;br /&gt;Por &amp;uacute;ltimo, me parece interesante recordar algo que hab&amp;iacute;a comentado en el post anterior, que en las expresiones lambda no era necesario indicar el tipo de los par&amp;aacute;metros ni del retorno porque el compilador los infer&amp;iacute;a del contexto. Como podemos ver, lo tiene bastante f&amp;aacute;cil, puesto que simplemente debe tomar la definici&amp;oacute;n del delegado para conocerlos; por eso no es necesario introducir redundancias como las siguientes:
&lt;pre&gt;&lt;code&gt;  Func&amp;lt;&lt;span style="background-color:#ffc0ff;"&gt;int&lt;/span&gt;, &lt;span style="background-color:#ffffc0;"&gt;int&lt;/span&gt;&amp;gt; duplica = (&lt;span style="background-color:#ffc0ff;"&gt;int&lt;/span&gt; a) =&amp;gt; (&lt;span style="background-color:#ffffc0;"&gt;int&lt;/span&gt;)(a * 2); &lt;span style="color:green;"&gt;// &amp;iexcl;Redundante!&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;  &lt;span style="color:green;"&gt;// Forma m&amp;aacute;s c&amp;oacute;moda:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;  Func&amp;lt;&lt;span style="background-color:#ffc0ff;"&gt;int&lt;/span&gt;, &lt;span style="background-color:#ffffc0;"&gt;int&lt;/span&gt;&amp;gt; duplica =  a =&amp;gt; a * 2; &lt;span style="color:green;"&gt;// Ok!&lt;/span&gt;&lt;/code&gt;&lt;span&gt;&amp;nbsp;&lt;br /&gt;&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;En cualquier caso, si por alg&amp;uacute;n motivo es necesario utilizar la forma expl&amp;iacute;cita, sabed que no se permite hacerlo de forma parcial, es decir, o le pon&amp;eacute;is los tipos a todo, o no se los pon&amp;eacute;is a nada.&lt;br /&gt;&lt;br /&gt;Y hasta aqu&amp;iacute; esta segunda entrega. En el siguiente post, el &amp;uacute;ltimo de la serie, estudiaremos el uso de las &lt;/p&gt;
&lt;/div&gt;
&lt;/span&gt;&lt;a href="http://www.variablenotfound.com/2009/03/c-desmitificando-las-expresiones-lambda_2829.html"&gt;&lt;span style="color:#35537a;"&gt;lambda como herramientas de definici&amp;oacute;n de &amp;aacute;rboles de expresi&amp;oacute;n&lt;/span&gt;&lt;/a&gt;&lt;span&gt;.&lt;br /&gt;&lt;br /&gt;Por supuesto, para cualquier duda o sugerencia, ya sab&amp;eacute;is d&amp;oacute;nde encontrarme. :-)&lt;br /&gt;&lt;br /&gt;Publicado en: &lt;/span&gt;&lt;a href="http://www.variablenotfound.com"&gt;&lt;span style="color:#35537a;"&gt;www.variablenotfound.com&lt;/span&gt;&lt;/a&gt;&lt;span&gt;.&lt;/span&gt;&lt;/div&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=147071" width="1" height="1"&gt;</description><category domain="http://geeks.ms/blogs/jmaguilar/archive/tags/c_2300_/default.aspx">c#</category><category domain="http://geeks.ms/blogs/jmaguilar/archive/tags/vs2008/default.aspx">vs2008</category><category domain="http://geeks.ms/blogs/jmaguilar/archive/tags/linq/default.aspx">linq</category><category domain="http://geeks.ms/blogs/jmaguilar/archive/tags/lambdas/default.aspx">lambdas</category><category domain="http://geeks.ms/blogs/jmaguilar/archive/tags/delegados/default.aspx">delegados</category><category domain="http://geeks.ms/blogs/jmaguilar/archive/tags/m_26002300_233_3B00_todos+an_26002300_243_3B00_nimos/default.aspx">m&amp;#233;todos an&amp;#243;nimos</category></item><item><title>C#: Desmitificando las expresiones lambda (I)</title><link>http://geeks.ms/blogs/jmaguilar/archive/2009/04/12/c-desmitificando-las-expresiones-lambda-i.aspx</link><pubDate>Sun, 12 Apr 2009 21:59:00 GMT</pubDate><guid isPermaLink="false">2a2e7ade-7474-448b-9de5-1515d8bb7d1b:146631</guid><dc:creator>José M. Aguilar</dc:creator><slash:comments>6</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/jmaguilar/rsscomments.aspx?PostID=146631</wfw:commentRss><comments>http://geeks.ms/blogs/jmaguilar/archive/2009/04/12/c-desmitificando-las-expresiones-lambda-i.aspx#comments</comments><description>&lt;div class="post-header-line-1"&gt;&lt;/div&gt;
&lt;p class="post-body entry-content"&gt;&lt;img src="http://3.bp.blogspot.com/_O9D62hXq-ng/SQtrgaCIm9I/AAAAAAAAA6k/XuuGqsiLjkw/s200/lambdas.jpg" alt="Lambda" border="0" id="BLOGGER_PHOTO_ID_5263418794000817106" style="float:right;margin:0px 0px 10px 10px;" /&gt;Entre las m&amp;uacute;ltiples novedades aparecidas con C# 3.0 y VB.NET 9.0, las &lt;em&gt;expresiones lambda&lt;/em&gt; son sin duda una de las que en principio pueden parecer m&amp;aacute;s complejas, probablemente por su relaci&amp;oacute;n con conceptos no demasiado asimilables como los delegados, inferencia de tipado, m&amp;eacute;todos an&amp;oacute;nimos, o tipos gen&amp;eacute;ricos, entre otros.&lt;br /&gt;&lt;br /&gt;Sin embargo, esa aparente dificultad desaparece en cuanto se les presta un poco de atenci&amp;oacute;n, y una vez comprendidas aportan a los desarrolladores una potencia y agilidad dif&amp;iacute;ciles de lograr con las herramientas disponibles hasta el momento. S&amp;oacute;lo hay que ver su amplia utilizaci&amp;oacute;n dentro del propio .NET framework, LINQ, y nuevas plataformas como ASP.NET MVC, para darse cuenta de su importancia. Y por si fuera poco, seg&amp;uacute;n cuentan los expertos, &lt;a hreflang="en" href="http://blog.wekeroad.com/blog/my-personal-lambda-crusade/" title="Rob Conery, My Personal Lambda Crusade"&gt;su uso &amp;quot;engancha&amp;quot;&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;A lo largo de esta serie de tres posts intentar&amp;eacute; describir las expresiones lambda desde un punto de vista pr&amp;aacute;ctico, con la &amp;uacute;nica pretensi&amp;oacute;n de aportar algo de luz a los que todav&amp;iacute;a no han sucumbido a su poder. ;-)&lt;br /&gt;&lt;br /&gt;El objetivo de este primer post es puramente introductorio, y tratar&amp;eacute; conceptos y nociones b&amp;aacute;sicas para poder abordar los siguientes. En el segundo post de la serie trataremos las expresiones lambda como funciones an&amp;oacute;nimas, dejando para el tercero los &lt;em&gt;misteriosos&lt;/em&gt; &amp;aacute;rboles de expresi&amp;oacute;n.&lt;/p&gt;
&lt;h3 class="post-body entry-content" id="intro"&gt;Introducci&amp;oacute;n a las lambda&lt;/h3&gt;
&lt;div class="post-body entry-content"&gt;Seg&amp;uacute;n la definici&amp;oacute;n en la &lt;a href="http://msdn.microsoft.com/es-es/library/bb397687.aspx" title="Expresiones lambda, Referencia del lenguaje C#"&gt;&lt;span style="color:#35537a;"&gt;Referencia del lenguaje C# de MSDN&lt;/span&gt;&lt;/a&gt;:&lt;br /&gt;&lt;/div&gt;
&lt;blockquote class="post-body entry-content"&gt;&amp;quot;Una expresi&amp;oacute;n lambda es una funci&amp;oacute;n an&amp;oacute;nima que puede contener expresiones e instrucciones y se puede utilizar para crear delegados o tipos de &amp;aacute;rboles de expresi&amp;oacute;n&amp;quot;&lt;/blockquote&gt;
&lt;div class="post-body entry-content"&gt;En la &lt;a href="http://msdn.microsoft.com/es-es/library/bb531253.aspx" title="Expresiones lambda, en la Gu&amp;iacute;a de Programaci&amp;oacute;n de Visual Basic"&gt;&lt;span style="color:#35537a;"&gt;Gu&amp;iacute;a de programaci&amp;oacute;n de Visual Basic 9&lt;/span&gt;&lt;/a&gt; encontramos otra definici&amp;oacute;n, muy simple y pragm&amp;aacute;tica: &lt;/div&gt;
&lt;blockquote class="post-body entry-content"&gt;&amp;quot;Una expresi&amp;oacute;n lambda es una funci&amp;oacute;n sin nombre que calcula y devuelve un solo valor. Se pueden utilizar las expresiones lambda dondequiera que un tipo de delegado sea v&amp;aacute;lido&amp;quot;&lt;/blockquote&gt;
&lt;div class="post-body entry-content"&gt;&lt;a hreflang="en" href="http://weblogs.asp.net/scottgu/archive/2007/04/08/new-orcas-language-feature-lambda-expressions.aspx" title="New &amp;#39;Orcas&amp;#39; Language Feature: Lambda Expressions"&gt;ScottGu&lt;/a&gt; tambi&amp;eacute;n aport&amp;oacute; su granito de arena para hacer el concepto m&amp;aacute;s cercano a los desarrolladores; como siempre, al grano: &lt;/div&gt;
&lt;blockquote class="post-body entry-content"&gt;&amp;quot;Las Expresiones Lambda aportan una sintaxis m&amp;aacute;s concisa y funcional para escribir m&amp;eacute;todos an&amp;oacute;nimos.&amp;quot;&lt;br /&gt;[...]&lt;br /&gt;&amp;quot;La forma m&amp;aacute;s sencilla para conceptualizar las expresiones lambda es pensar en ellas como formas de escribir m&amp;eacute;todos breves en una l&amp;iacute;nea.&amp;quot;&lt;/blockquote&gt;
&lt;div class="post-body entry-content"&gt;Partiendo de estas definiciones, y de otras muchas aportadas por Google ;-), est&amp;aacute; claro que las lambda son funciones, es decir, un conjunto de intrucciones capaces de retornar un valor partiendo de los par&amp;aacute;metros que se les suministra, aunque en determinados casos es posible que no reciba ning&amp;uacute;n par&amp;aacute;metro, o que realicen una acci&amp;oacute;n sin retornar nada. Igual que una funci&amp;oacute;n tradicional, vaya. Y de hecho, en el cuerpo de una expresi&amp;oacute;n lambda puede haber &lt;em&gt;casi&lt;/em&gt; de todo: llamadas a otras funciones, expresiones, bucles, declaraciones de variables...&lt;br /&gt;&lt;br /&gt;Sin embargo, a diferencia de los m&amp;eacute;todos o funciones habituales, las lambdas no necesitan de un identificador, puesto que se declaran in situ, justo en el momento en que van a asignarse a una variable o a utilizarse como par&amp;aacute;metro de una funci&amp;oacute;n, pasando el destinatario de esta asignaci&amp;oacute;n a actuar como delegado, o puntero, hacia la misma, o a ser el contenedor del &amp;aacute;rbol de expresi&amp;oacute;n que la representa. Ein? Chino, eh? No pasa nada, dentro de poco estudiaremos estos dos usos en profundidad, pero antes vamos a ver c&amp;oacute;mo se definen las expresiones lambda a nivel de c&amp;oacute;digo.&lt;br /&gt;&lt;/div&gt;
&lt;h3 class="post-body entry-content" id="forma"&gt;Forma de las expresiones lambda&lt;/h3&gt;
&lt;div class="post-body entry-content"&gt;Las expresiones lambda en C# se escriben seg&amp;uacute;n el patr&amp;oacute;n descrito a continuaci&amp;oacute;n, al que le siguen algunos ejemplos que lo ilustran e introducen algunas particularidades. &lt;/div&gt;
&lt;div class="post-body entry-content"&gt;
&lt;pre&gt;&lt;code&gt;&lt;div style="background-color:#ffffc0;border:#c0c0c0 1px dotted;padding:3px;"&gt;Forma general: &lt;strong&gt;par&amp;aacute;metros =&amp;gt; expresi&amp;oacute;n&lt;/strong&gt;, donde:&lt;br /&gt;- &lt;strong&gt;par&amp;aacute;metros&lt;/strong&gt;: lista de par&amp;aacute;metros separados por comas&lt;br /&gt;- &lt;strong&gt;&amp;quot;=&amp;gt;&amp;quot;&lt;/strong&gt; : separador.&lt;br /&gt;- &lt;strong&gt;expresi&amp;oacute;n&lt;/strong&gt;: implementaci&amp;oacute;n de las operaciones a realizar&lt;/div&gt;&lt;br /&gt;num =&amp;gt; num * 2     &lt;span style="color:green;"&gt;// Lambda con un par&amp;aacute;metro que retorna&lt;br /&gt;                   // el doble del valor que se le pasa.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;(a, b) =&amp;gt; a + b    &lt;span style="color:green;"&gt;// Lambda con dos par&amp;aacute;metros que retorna&lt;br /&gt;                   // la suma de ambos.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;num =&amp;gt; {                        &lt;span style="color:green;"&gt;// Lambda con cuerpo que recibe un &lt;/span&gt;&lt;br /&gt;   int x = new Random().Next(); &lt;span style="color:green;"&gt;// entero, y retorna la suma de &amp;eacute;ste&lt;/span&gt;&lt;br /&gt;   return num+x;                &lt;span style="color:green;"&gt;// con un n&amp;uacute;mero aleatorio.&lt;/span&gt;&lt;br /&gt;}  &lt;br /&gt;&lt;br /&gt;() =&amp;gt; DateTime.Now &lt;span style="color:green;"&gt;// Lambda que no recibe par&amp;aacute;metros&lt;br /&gt;                   // y retorna la fecha y hora del sistema.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;msg =&amp;gt; Console.WriteLine(msg); &lt;span style="color:green;"&gt;// Recibe un par&amp;aacute;metro, realiza una&lt;br /&gt;                               // acci&amp;oacute;n y no retorna nada.&lt;/span&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;div class="post-body entry-content"&gt;&amp;nbsp;&lt;br /&gt;Como se puede observar, cuando s&amp;oacute;lo existe un par&amp;aacute;metro no es necesario utilizar par&amp;eacute;ntesis en el lado izquierdo de la expresi&amp;oacute;n, mientras que hay que hacerlo en todos los dem&amp;aacute;s casos. Tambi&amp;eacute;n es interesante destacar que las lambda con cuerpo deben utilizar &lt;code&gt;return&lt;/code&gt; para retornar el valor deseado, cuando esto sea necesario.&lt;br /&gt;&lt;br /&gt;Y un &amp;uacute;ltimo dato: fijaos que ni los par&amp;aacute;metros ni el retorno de la funci&amp;oacute;n tienen indicado un tipo. Aunque puede hacerse, normalmente no ser&amp;aacute; necesario puesto que el compilador podr&amp;aacute; inferir (deducir) el tipo a partir de su contexto, m&amp;aacute;s adelante veremos c&amp;oacute;mo es esto posible. Por tanto, &lt;strong&gt;no&lt;/strong&gt; es necesario escribir c&amp;oacute;digo tan extenso como: &lt;/div&gt;
&lt;div class="post-body entry-content"&gt;
&lt;pre&gt;&lt;code&gt;  (int a, int b) =&amp;gt; (int)(a+b)&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;div class="post-body entry-content"&gt;&amp;nbsp;&lt;br /&gt;Y hasta aqu&amp;iacute; este primer post introductorio. En el siguiente trataremos de explicar el papel de &lt;a href="http://www.variablenotfound.com/2009/03/c-desmitificando-las-expresiones-lambda_29.html"&gt;&lt;span style="color:#35537a;"&gt;las expresiones lambda como funciones an&amp;oacute;nimas y facilitadoras del trabajo con delegados&lt;/span&gt;&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Continuar leyendo la siguiente entrega: &lt;a href="http://www.variablenotfound.com/2009/03/c-desmitificando-las-expresiones-lambda_29.html" title="Desmitificando las expresiones lambda, toma 2."&gt;C#: Desmitificando las expresiones lambda (II)&lt;/a&gt;&lt;/div&gt;
&lt;div class="post-body entry-content"&gt;&lt;/div&gt;
&lt;div class="post-body entry-content"&gt;Publicado en: &lt;a href="http://www.variablenotfound.com/"&gt;&lt;span style="color:#35537a;"&gt;www.variablenotfound.com&lt;/span&gt;&lt;/a&gt;. &lt;/div&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=146631" width="1" height="1"&gt;</description><category domain="http://geeks.ms/blogs/jmaguilar/archive/tags/c_2300_/default.aspx">c#</category><category domain="http://geeks.ms/blogs/jmaguilar/archive/tags/vs2008/default.aspx">vs2008</category><category domain="http://geeks.ms/blogs/jmaguilar/archive/tags/linq/default.aspx">linq</category><category domain="http://geeks.ms/blogs/jmaguilar/archive/tags/_26002300_225_3B00_rboles+de+expresi_26002300_243_3B00_n/default.aspx">&amp;#225;rboles de expresi&amp;#243;n</category><category domain="http://geeks.ms/blogs/jmaguilar/archive/tags/lambdas/default.aspx">lambdas</category><category domain="http://geeks.ms/blogs/jmaguilar/archive/tags/delegados/default.aspx">delegados</category></item><item><title>Chuleta de operadores estándar de consulta LINQ</title><link>http://geeks.ms/blogs/jmaguilar/archive/2008/04/24/chuleta-de-operadores-est-225-ndar-de-consulta-linq.aspx</link><pubDate>Thu, 24 Apr 2008 19:32:00 GMT</pubDate><guid isPermaLink="false">2a2e7ade-7474-448b-9de5-1515d8bb7d1b:84191</guid><dc:creator>José M. Aguilar</dc:creator><slash:comments>1</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/jmaguilar/rsscomments.aspx?PostID=84191</wfw:commentRss><comments>http://geeks.ms/blogs/jmaguilar/archive/2008/04/24/chuleta-de-operadores-est-225-ndar-de-consulta-linq.aspx#comments</comments><description>&lt;p&gt;Buscando información sobre los operadores estándar de consulta de Linq, me he topado en &lt;a href="http://www.aspnetresources.com/blog/linq_sqo__cheat_sheet.aspx"&gt;&lt;font color="#35537a"&gt;ASP.NET Resources&lt;/font&gt;&lt;/a&gt; con una chuleta (cheat sheet) que nos puede valer para tener siempre a mano una referencia rápida de los mismos, y de paso, adornar alguna pared que tengamos vacía ;-).&lt;br /&gt;&lt;br /&gt;Puedes descargarla pulsando sobre la imagen:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://aspnetresources.com/downloads/linq_standard_query_operators.pdf"&gt;&lt;img id="BLOGGER_PHOTO_ID_5190887880070670562" style="DISPLAY:block;MARGIN:0px auto 10px;CURSOR:hand;TEXT-ALIGN:center;" alt="Descargar archivo PDF" src="http://bp3.blogger.com/_O9D62hXq-ng/SAm9BkB-KOI/AAAAAAAAAVg/seVtif928Os/s400/linq_cheat_sheet.png" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Si quieres leer más sobre estos operadores, puedes probar también en la referencia oficial, &lt;a href="http://download.microsoft.com/download/5/8/6/5868081c-68aa-40de-9a45-a3803d8134b8/Standard_Query_Operators.doc"&gt;&lt;font color="#35537a"&gt;The .Net Standard Query Operators&lt;/font&gt;&lt;/a&gt; &lt;span style="FONT-SIZE:78%;"&gt;&lt;font size="2"&gt;[ING]&lt;/font&gt;&lt;/span&gt;, a leer &lt;a title="Operadores de consulta estándar" href="http://www.microsoft.com/spanish/msdn/articulos/archivo/041206/voices/StandardQuery.mspx"&gt;&lt;font color="#35537a"&gt;este artículo&lt;/font&gt;&lt;/a&gt; traducido por el maestro &lt;a href="http://geeks.ms/blogs/ohernandez/"&gt;&lt;font color="#35537a"&gt;Octavio Hernández&lt;/font&gt;&lt;/a&gt;, profundizar en &lt;a href="http://msdn2.microsoft.com/es-es/library/bb397896.aspx"&gt;&lt;font color="#35537a"&gt;MSDN&lt;/font&gt;&lt;/a&gt;, o en otros de los muchos sitios con información relacionada, como la referencia de &lt;a href="http://www.hookedonlinq.com/StandardQueryOperators.ashx"&gt;&lt;font color="#35537a"&gt;Hooked On Linq&lt;/font&gt;&lt;/a&gt;&lt;span style="FONT-SIZE:78%;"&gt;&lt;font size="2"&gt; [ING]&lt;/font&gt;&lt;/span&gt;. &lt;br /&gt;&lt;br /&gt;Publicado en: &lt;a href="http://www.variablenotfound.com/"&gt;&lt;font color="#35537a"&gt;http://www.variablenotfound.com/&lt;/font&gt;&lt;/a&gt;. &lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=84191" width="1" height="1"&gt;</description><category domain="http://geeks.ms/blogs/jmaguilar/archive/tags/desarrollo/default.aspx">desarrollo</category><category domain="http://geeks.ms/blogs/jmaguilar/archive/tags/programaci_26002300_243_3B00_n/default.aspx">programaci&amp;#243;n</category><category domain="http://geeks.ms/blogs/jmaguilar/archive/tags/chuletas/default.aspx">chuletas</category><category domain="http://geeks.ms/blogs/jmaguilar/archive/tags/linq/default.aspx">linq</category></item></channel></rss>