<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss 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/" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0"><channel><title>Jad Engine Blog</title><link>http://kartones.net/blogs/jadengine/default.aspx</link><description>Blog about Jad Engine, a game engine written using the .NET Framework.</description><dc:language>en</dc:language><generator>CommunityServer 2007 SP2 (Build: 20611.960)</generator><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" href="http://feeds.feedburner.com/JadEngineBlog" type="application/rss+xml" /><feedburner:emailServiceId>JadEngineBlog</feedburner:emailServiceId><feedburner:feedburnerHostname>http://feedburner.google.com</feedburner:feedburnerHostname><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com" /><item><title>MVP otro año más</title><link>http://feedproxy.google.com/~r/JadEngineBlog/~3/-_LZnpE91f0/mvp-otro-a-241-o-m-225-s.aspx</link><pubDate>Mon, 06 Jul 2009 14:30:34 GMT</pubDate><guid isPermaLink="false">b86c0850-82e5-42ed-a9d8-bde9e8f94ec1:50180</guid><dc:creator>Vicente</dc:creator><slash:comments>1</slash:comments><wfw:commentRss>http://kartones.net/blogs/jadengine/rsscomments.aspx?PostID=50180</wfw:commentRss><comments>http://kartones.net/blogs/jadengine/archive/2009/07/06/mvp-otro-a-241-o-m-225-s.aspx#comments</comments><description>&lt;p&gt;Hace unos días recibí una noticia que la verdad me hacía mucha ilusión recibir: he sido renovado como MVP de DirectX/XNA :) Este es mi segundo año como MVP y estoy encantado de poder seguir participando en esta tecnología que personalmente creo que tiene mucho futuro (aunque los principios siempre sean difíciles).&lt;/p&gt;  &lt;p&gt;Además este año (que yo sepa) se nos unen como MVPs de DirectX/XNA dos personas que admiro muchísimo: &lt;a href="https://mvp.support.microsoft.com/profile/Ayucar"&gt;Iñaki Ayucar&lt;/a&gt; (¡otro español!) y &lt;a href="https://mvp.support.microsoft.com/profile=08938215-662E-45FA-B327-4E8755E07B6A"&gt;Promit Roy&lt;/a&gt;. ¡Enhorabuena a ambos!&lt;/p&gt;  &lt;p&gt;&lt;img style="border-bottom:0px;border-left:0px;display:inline;border-top:0px;border-right:0px;" title="mvplogo[1]" border="0" alt="mvplogo[1]" src="http://kartones.net/blogs/jadengine/mvplogo1_thumb_0E5E33BD.jpg" width="112" height="172" /&gt;&lt;/p&gt;&lt;img src="http://kartones.net/aggbug.aspx?PostID=50180" width="1" height="1"&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/7zhG3J0TqoHPEMCCVWfH37pQIhQ/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/7zhG3J0TqoHPEMCCVWfH37pQIhQ/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/7zhG3J0TqoHPEMCCVWfH37pQIhQ/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/7zhG3J0TqoHPEMCCVWfH37pQIhQ/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/JadEngineBlog/~4/-_LZnpE91f0" height="1" width="1"/&gt;</description><feedburner:origLink>http://kartones.net/blogs/jadengine/archive/2009/07/06/mvp-otro-a-241-o-m-225-s.aspx</feedburner:origLink></item><item><title>El patrón Singleton en C#</title><link>http://feedproxy.google.com/~r/JadEngineBlog/~3/KOyWmLZC-Wc/el-patr-243-n-singleton-en-c.aspx</link><pubDate>Wed, 20 May 2009 15:21:00 GMT</pubDate><guid isPermaLink="false">b86c0850-82e5-42ed-a9d8-bde9e8f94ec1:50052</guid><dc:creator>Vicente</dc:creator><slash:comments>5</slash:comments><wfw:commentRss>http://kartones.net/blogs/jadengine/rsscomments.aspx?PostID=50052</wfw:commentRss><comments>http://kartones.net/blogs/jadengine/archive/2009/05/20/el-patr-243-n-singleton-en-c.aspx#comments</comments><description>&lt;p&gt;Una de las cosas que creo es importante cuando usas un lenguaje es entender como funciona por dentro. Por ejemplo es cierto que C# se parece mucho a Java pero a bajo nivel presentan muchas diferencias de filosofía y diseño que creo son importantes de entender para hacer un uso eficaz del mismo. Algo similar ocurre cuando alguien que está acostumbrado a C++ se pasa a C#, muchas veces piensa que es un C++ “fácil” (sin punteros, sin gestión de memoria) y luego se queja de que su rendimiento es mucho peor, que va lento,… cuando a veces todo esto es porque está usando C# como si fuera C++ y las cosas no funcionan así.&lt;/p&gt;
&lt;p&gt;Un ejemplo de libro de esta situación es la implementación del &lt;a href="http://en.wikipedia.org/wiki/Singleton_pattern"&gt;patrón Singleton&lt;/a&gt; en C#. Si buscáis un poco, en muchas páginas webs para implementar un Singleton lazy y thread-safe en Java/C++ se recomienda la siguiente implementación:&lt;/p&gt;
&lt;div style="FONT-FAMILY:consolas;BACKGROUND:white;COLOR:black;FONT-SIZE:10pt;"&gt;
&lt;p style="MARGIN:0px;"&gt;&lt;span style="COLOR:blue;"&gt;public&lt;/span&gt; &lt;span style="COLOR:blue;"&gt;sealed&lt;/span&gt; &lt;span style="COLOR:blue;"&gt;class&lt;/span&gt; &lt;span style="COLOR:#2b91af;"&gt;Singleton&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;{&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR:blue;"&gt;static&lt;/span&gt; &lt;span style="COLOR:#2b91af;"&gt;Singleton&lt;/span&gt; instance = &lt;span style="COLOR:blue;"&gt;null&lt;/span&gt;;&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR:blue;"&gt;static&lt;/span&gt; &lt;span style="COLOR:blue;"&gt;readonly&lt;/span&gt; &lt;span style="COLOR:blue;"&gt;object&lt;/span&gt; padlock = &lt;span style="COLOR:blue;"&gt;new&lt;/span&gt; &lt;span style="COLOR:blue;"&gt;object&lt;/span&gt;();&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Singleton()&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR:blue;"&gt;public&lt;/span&gt; &lt;span style="COLOR:blue;"&gt;static&lt;/span&gt; &lt;span style="COLOR:#2b91af;"&gt;Singleton&lt;/span&gt; Instance&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR:blue;"&gt;get&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR:blue;"&gt;if&lt;/span&gt; (instance == &lt;span style="COLOR:blue;"&gt;null&lt;/span&gt;)&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR:blue;"&gt;lock&lt;/span&gt; (padlock)&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR:blue;"&gt;if&lt;/span&gt; (instance == &lt;span style="COLOR:blue;"&gt;null&lt;/span&gt;)&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; instance = &lt;span style="COLOR:blue;"&gt;new&lt;/span&gt; &lt;span style="COLOR:#2b91af;"&gt;Singleton&lt;/span&gt;();&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR:blue;"&gt;return&lt;/span&gt; instance;&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;}&lt;/p&gt;&lt;/div&gt;
&lt;p&gt;La sintaxis es de C#, pero lo importante es la idea del if/lock/if. A esto se le llama &lt;a href="http://en.wikipedia.org/wiki/Double-checked_locking"&gt;double-checked-locking&lt;/a&gt; y por motivos bastante sutiles esa implementación no es totalmente thread-safe (más detalles &lt;a href="http://www.cs.umd.edu/~pugh/java/memoryModel/DoubleCheckedLocking.html"&gt;en este paper&lt;/a&gt;). El problema de thread-safe se puede solucionar haciendo la variable instance &lt;a href="http://en.wikipedia.org/wiki/Volatile_variable"&gt;volatile&lt;/a&gt; (a partir de la JDK 5.0 y Visual C++ 2005, ni idea en otros compiladores de C++).&lt;/p&gt;
&lt;p&gt;El problema es que como mucha gente de Java/C++ se ha acostumbrado a implementar el Singleton de esa manera, cuando llegan a C# hacen lo mismo. Pero resulta que en C# la implementación correcta es la siguiente:&lt;/p&gt;
&lt;div style="FONT-FAMILY:consolas;BACKGROUND:white;COLOR:black;FONT-SIZE:10pt;"&gt;
&lt;p style="MARGIN:0px;"&gt;&lt;span style="COLOR:blue;"&gt;public&lt;/span&gt; &lt;span style="COLOR:blue;"&gt;sealed&lt;/span&gt; &lt;span style="COLOR:blue;"&gt;class&lt;/span&gt; &lt;span style="COLOR:#2b91af;"&gt;Singleton&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;{&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR:blue;"&gt;static&lt;/span&gt; &lt;span style="COLOR:blue;"&gt;readonly&lt;/span&gt; &lt;span style="COLOR:#2b91af;"&gt;Singleton&lt;/span&gt; instance = &lt;span style="COLOR:blue;"&gt;new&lt;/span&gt; &lt;span style="COLOR:#2b91af;"&gt;Singleton&lt;/span&gt;();&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR:blue;"&gt;static&lt;/span&gt; Singleton()&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Singleton()&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR:blue;"&gt;public&lt;/span&gt; &lt;span style="COLOR:blue;"&gt;static&lt;/span&gt; &lt;span style="COLOR:#2b91af;"&gt;Singleton&lt;/span&gt; Instance&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR:blue;"&gt;get&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR:blue;"&gt;return&lt;/span&gt; instance;&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;}&lt;/p&gt;&lt;/div&gt;
&lt;p&gt;Visto así por encima, esa implementación no parece ni lazy, ni thread-safe, ni nada de nada. Pero si nos cogemos el gran &lt;a href="http://www.amazon.com/CLR-via-Second-Pro-Developer/dp/0735621632"&gt;CLR via C#&lt;/a&gt; (libro totalmente recomendado) podemos entender como es que tan poco código hace tantas cosas. Toda la implementación gira en torno a los constructores estáticos y como funcionan dentro de .NET. Lo primero es entender que esto:&lt;/p&gt;
&lt;div style="FONT-FAMILY:consolas;BACKGROUND:white;COLOR:black;FONT-SIZE:10pt;"&gt;
&lt;p style="MARGIN:0px;"&gt;&lt;span style="COLOR:blue;"&gt;public&lt;/span&gt; &lt;span style="COLOR:blue;"&gt;sealed&lt;/span&gt; &lt;span style="COLOR:blue;"&gt;class&lt;/span&gt; &lt;span style="COLOR:#2b91af;"&gt;Singleton&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;{&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR:blue;"&gt;static&lt;/span&gt; &lt;span style="COLOR:blue;"&gt;int&lt;/span&gt; a = 5;&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;}&lt;/p&gt;&lt;/div&gt;
&lt;p&gt;En IL se traduce a esto:&lt;/p&gt;
&lt;div style="FONT-FAMILY:consolas;BACKGROUND:white;COLOR:black;FONT-SIZE:10pt;"&gt;
&lt;p style="MARGIN:0px;"&gt;&lt;span style="COLOR:blue;"&gt;public&lt;/span&gt; &lt;span style="COLOR:blue;"&gt;sealed&lt;/span&gt; &lt;span style="COLOR:blue;"&gt;class&lt;/span&gt; &lt;span style="COLOR:#2b91af;"&gt;Singleton&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;{&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR:blue;"&gt;static&lt;/span&gt; &lt;span style="COLOR:blue;"&gt;int&lt;/span&gt; a;&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR:blue;"&gt;static&lt;/span&gt; Singleton()&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; a = 5;&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;}&lt;/p&gt;&lt;/div&gt;
&lt;p&gt;Y que por ejemplo esto otro:&lt;/p&gt;
&lt;div style="FONT-FAMILY:consolas;BACKGROUND:white;COLOR:black;FONT-SIZE:10pt;"&gt;
&lt;p style="MARGIN:0px;"&gt;&lt;span style="COLOR:blue;"&gt;public&lt;/span&gt; &lt;span style="COLOR:blue;"&gt;sealed&lt;/span&gt; &lt;span style="COLOR:blue;"&gt;class&lt;/span&gt; &lt;span style="COLOR:#2b91af;"&gt;Singleton&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;{ &lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR:blue;"&gt;static&lt;/span&gt; &lt;span style="COLOR:blue;"&gt;int&lt;/span&gt; a = 5;&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR:blue;"&gt;static&lt;/span&gt; &lt;span style="COLOR:blue;"&gt;int&lt;/span&gt; b;&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR:blue;"&gt;static&lt;/span&gt; Singleton() &lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; b = 10; &lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; } &lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;}&lt;/p&gt;&lt;/div&gt;
&lt;p&gt;En IL queda así:&lt;/p&gt;
&lt;div style="FONT-FAMILY:consolas;BACKGROUND:white;COLOR:black;FONT-SIZE:10pt;"&gt;
&lt;p style="MARGIN:0px;"&gt;&lt;span style="COLOR:blue;"&gt;public&lt;/span&gt; &lt;span style="COLOR:blue;"&gt;sealed&lt;/span&gt; &lt;span style="COLOR:blue;"&gt;class&lt;/span&gt; &lt;span style="COLOR:#2b91af;"&gt;Singleton&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;{ &lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR:blue;"&gt;static&lt;/span&gt; &lt;span style="COLOR:blue;"&gt;int&lt;/span&gt; a;&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR:blue;"&gt;static&lt;/span&gt; &lt;span style="COLOR:blue;"&gt;int&lt;/span&gt; b;&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR:blue;"&gt;static&lt;/span&gt; Singleton() &lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; a = 5;&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; b = 10; &lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; } &lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;}&lt;/p&gt;&lt;/div&gt;
&lt;p&gt;Vamos, que las inicializaciones de variables estáticas una vez compilada la clase se incluyen dentro de un constructor estático (si el constructor existe se añaden al principio en el orden que son declaradas, si no existe se genera un constructor y se añaden).&lt;/p&gt;
&lt;p&gt;En C#, cuando el compilador JIT (el que pasa de IL a código máquina) encuentra un constructor estático, mira si ese constructor ya se ha ejecutado o no:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Si no se ha ejecutado, emite un lock, el código de ejecución y un unlock. &lt;/li&gt;
&lt;li&gt;Si se ha ejecutado, no emite nada. &lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;Es decir, el JIT se asegura que el constructor estático solo se ejecute una vez aunque haya varios hilos, por eso en C# no hace falta poner el lock, ya que la línea &lt;em&gt;new Singleton()&lt;/em&gt; se ejecuta dentro del constructor estático y el propio JIT ya se ha encargado que ese constructor solo sea llamado una vez. Con esto ya tenemos cubierto el tema de thread-safe, pero ¿y lo de que sea lazy?&lt;/p&gt;
&lt;p&gt;Primero, tengo que reconocer que os he mentido un poco antes. Esta clase:&lt;/p&gt;
&lt;div style="FONT-FAMILY:consolas;BACKGROUND:white;COLOR:black;FONT-SIZE:10pt;"&gt;
&lt;p style="MARGIN:0px;"&gt;&lt;span style="COLOR:blue;"&gt;public&lt;/span&gt; &lt;span style="COLOR:blue;"&gt;sealed&lt;/span&gt; &lt;span style="COLOR:blue;"&gt;class&lt;/span&gt; &lt;span style="COLOR:#2b91af;"&gt;Singleton&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;{ &lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR:blue;"&gt;static&lt;/span&gt; &lt;span style="COLOR:blue;"&gt;int&lt;/span&gt; a = 5;&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;}&lt;/p&gt;&lt;/div&gt;
&lt;p&gt;Y esta otra clase:&lt;/p&gt;
&lt;p&gt;&lt;span style="COLOR:blue;"&gt;public&lt;/span&gt; &lt;span style="COLOR:blue;"&gt;sealed&lt;/span&gt; &lt;span style="COLOR:blue;"&gt;class&lt;/span&gt; &lt;span style="COLOR:#2b91af;"&gt;Singleton&lt;/span&gt;&lt;/p&gt;
&lt;div style="FONT-FAMILY:consolas;BACKGROUND:white;COLOR:black;FONT-SIZE:10pt;"&gt;
&lt;p style="MARGIN:0px;"&gt;{ &lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR:blue;"&gt;static&lt;/span&gt; &lt;span style="COLOR:blue;"&gt;int&lt;/span&gt; a;&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR:blue;"&gt;static&lt;/span&gt; Singleton() &lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; a = 5;&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; } &lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;}&lt;/p&gt;&lt;/div&gt;
&lt;p&gt;No generan exactamente el mismo IL: la primera está marcada con un atributo que se llama &lt;strong&gt;BeforeFieldInit&lt;/strong&gt; y la segunda no. Cuando una clase está marcada como &lt;strong&gt;BeforeFieldInit&lt;/strong&gt; el runtime del framework puede decidir ejecutar su inicializador de tipo (constructor estático) cuando se haga la primera referencia a ese tipo o antes, según le parezca. Pero si no está marcada con &lt;strong&gt;BeforeFieldInit&lt;/strong&gt; (porque hemos puesto un constructor estático explícito) entonces el inicializador del tipo solo puede ejecutarse en el momento que se haga uso de ese tipo.&lt;/p&gt;
&lt;p&gt;Es decir, como mi implementación del Singleton tiene un constructor estático, esta clase no está marcada como &lt;strong&gt;BeforeFieldInit&lt;/strong&gt; y lo que haya dentro del constructor estático (&lt;em&gt;new Singleton()&lt;/em&gt;) se ejecutará justo cuando haga &lt;em&gt;Singleton.Instance&lt;/em&gt;. Pero si no tuviera un constructor estático la línea &lt;em&gt;new Singleton()&lt;/em&gt; se podría ejecutar una hora antes de llamar a &lt;em&gt;Singleton.Instance&lt;/em&gt; (por ejemplo), según decida el runtime. Y esto puede ser un problema porque no tenemos ni idea de cuando se va a ejecutar ese constructor y si tiene código muy pesado puede ralentizar el resto del programa en algún punto que no sea adecuado, o incluso ejecutarse y que luego resulte que nunca se utiliza en el programa.&lt;/p&gt;
&lt;p&gt;Podéis encontrar una discusión mucho más en profundidad del tema en &lt;a href="http://www.yoda.arachsys.com/csharp/singleton.html"&gt;este&lt;/a&gt; artículo y &lt;a href="http://www.yoda.arachsys.com/csharp/beforefieldinit.html"&gt;este&lt;/a&gt; otro (cuentan lo mismo pero de forma mucho más técnica).&lt;/p&gt;
&lt;p&gt;Actualización: Reed Copsey ha publicado un artículo sobre este mismo tema llamado &lt;a href="http://reedcopsey.com/?p=39&amp;amp;cpage=1#comment-18"&gt;&amp;quot;Just keep repeating: C# is not Java. C# is not C++&amp;quot;&lt;/a&gt; que contiene más ejemplos y resulta bastante interesante.&lt;/p&gt;&lt;img src="http://kartones.net/aggbug.aspx?PostID=50052" width="1" height="1"&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/U2kRqvAiK4CRVU1z5C3crWR0gcI/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/U2kRqvAiK4CRVU1z5C3crWR0gcI/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/U2kRqvAiK4CRVU1z5C3crWR0gcI/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/U2kRqvAiK4CRVU1z5C3crWR0gcI/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/JadEngineBlog/~4/KOyWmLZC-Wc" height="1" width="1"/&gt;</description><category domain="http://kartones.net/blogs/jadengine/archive/tags/C_2300_/default.aspx">C#</category><feedburner:origLink>http://kartones.net/blogs/jadengine/archive/2009/05/20/el-patr-243-n-singleton-en-c.aspx</feedburner:origLink></item><item><title>Emprendedores</title><link>http://feedproxy.google.com/~r/JadEngineBlog/~3/I4XpRD8gUSE/emprendedores.aspx</link><pubDate>Wed, 08 Apr 2009 05:21:00 GMT</pubDate><guid isPermaLink="false">b86c0850-82e5-42ed-a9d8-bde9e8f94ec1:39208</guid><dc:creator>Vicente</dc:creator><slash:comments>7</slash:comments><wfw:commentRss>http://kartones.net/blogs/jadengine/rsscomments.aspx?PostID=39208</wfw:commentRss><comments>http://kartones.net/blogs/jadengine/archive/2009/04/08/emprendedores.aspx#comments</comments><description>&lt;p&gt;Hay un tipo de personas a las que &lt;strike&gt;envidio&lt;/strike&gt; admiro de sobremanera: los emprendedores. Yo siempre he tenido ideas que he pensado que podrían ser un buen producto, o al menos suficentemente decente para funcionar. Cuando empecé con esto de los videojuegos tenía la idea del juego definitivo, normalmente un refrito de los tres o cuatro juegos de moda del momento, y junto con algunos amigos y algún colaborador nos lanzábamos a lo loco a intentar realizarlos - seguro que al igual que muchos de los que leéis estas líneas.&lt;/p&gt;  &lt;p&gt;Todo empezaba genial, con la gente muy animada dedicando buena parte de su tiempo libre y de repente, un día:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Pepito ha ligado el finde anterior y ya no tiene tiempo para seguir en el proyecto.&lt;/li&gt;    &lt;li&gt;Juanito lleva 5 días sin dormir enganchado al Call of Duty 6. Pero es para intentar conseguir nuevas ideas, ya sabéis, hay que jugar a todas las obras maestras - aunque tu juego sea un clon del pong.&lt;/li&gt;    &lt;li&gt;Luisito está más pelao que las ratas y se ha buscado un trabajo, así que cuando termina su jornada solo le apetece tumbarse en el sofá y ver la tele.&lt;/li&gt;    &lt;li&gt;Jaimito viendo que los demás no hacen ni el huevo, obviamente se contagia del espíritu reinante y tampoco hace nada.&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Total, que al cabo de dos meses el resultado es un proyecto cancelado y lo mismo hasta alguna bronca o discusión entre los integrantes del equipo. Después de un tiempo, y ya siendo más “maduros”, este proceso se vuelve a repetir con idénticos resultados y así N veces hasta que uno tras otro nos vamos dando cuenta que mejor dedicarnos a otra cosa.&lt;/p&gt;  &lt;p&gt;Pero hay gente que es capaz de salir de este círculo y llevar sus ideas adelante. Cuando te pones a analizarlo el resultado es sorprendente:&lt;/p&gt;  &lt;p align="center"&gt;¡han convertido su proyecto en su &lt;i&gt;trabajo&lt;/i&gt;!&lt;/p&gt;  &lt;p&gt;Traduciendo: de lunes a viernes dedican entre las 9 y las 19 a su idea (cuando las cosas van bien, cuando hay que apretar parecen un 7 Eleven). Y eso que también tienen novias y les encanta viciarse al Call of Duty 6. Además, ¡la de riesgos a los que se exponen frente a un trabajo tradicional! Que si no encuentras clientes, los proveedores te la lían, no consigues financiación,…&lt;/p&gt;  &lt;p&gt;Y esa es la forma de pensar que hace que uno no emprenda. O al menos es la que hace que yo no me atreva a emprender y admire a la gente que tiene los cojones de arriesgarse, y más en este país donde el fracaso está tan mal considerado – demasiado en mi opinión.&lt;/p&gt;  &lt;p&gt;Así que este post va dedicado a toda esa gente que da ese salto, que pone todo su esfuerzo en perseguir sus ideas, en confiar en ellas, y en no dejarse achantar por todos los posibles problemas que puedan cruzarse en su camino.&lt;/p&gt;  &lt;p&gt;Por suerte para mi, porque considero una fortuna poder hablar con este tipo de personas, conozco a bastante gente que ha emprendido y me gustaría dedicarles unas líneas:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;A &lt;a href="http://graphicdna.blogspot.com/"&gt;Iñaki Ayucar&lt;/a&gt; que posiblemente sea el tío que más sabe de gráficos y código manejado de España, y que lleva años apostando por su empresa &lt;a href="http://www.simaxvirt.com/"&gt;Simax&lt;/a&gt;, un simulador de conducción que es sencillamente impresionante.&lt;/li&gt;    &lt;li&gt;A mis compañeros de facultad que fundaron &lt;a href="http://vaelsys.com/"&gt;Vaelsys&lt;/a&gt;, una empresa especializada en visión artificial. Nunca se me olvidarán momentos como cuando Jorge hizo su parte de una práctica de Criptografía en Latín, o cuando Edu se vino a mi casa con su compañera a hacer prácticas de POO y el cabrón terminó comiendo palomitas mientras yo hacía el trabajo. Y encima al cabo de unas semanas vino quejándose de que solo había sacado un notable. Está claro que se le da bien ser jefe (y que yo soy un pringao).&lt;/li&gt;    &lt;li&gt;A la gente de &lt;a href="http://www.signumsoftware.com/"&gt;Signum Software&lt;/a&gt; y en particular a Olmo del Corral, que se han lanzado a la aventura de lanzar un &lt;a href="http://www.signumframework.com/"&gt;ORM&lt;/a&gt; open source en .NET con ideas bastante novedosas en algunos aspectos.&lt;/li&gt;    &lt;li&gt;A &lt;a href="http://www.cokidoo.com/"&gt;Cokidoo&lt;/a&gt;, empresa fundada por yens y Loover (entre otros), dos conocidos de &lt;a href="http://www.stratos-ad.com/"&gt;Stratos-AD&lt;/a&gt;. Están poniendo toda la carne en el asador con una &lt;a href="http://www.erasmusu.com/"&gt;red social&lt;/a&gt; enfocada a estudiantes de movilidad (erasmus,…) que tiene un acabado impecable. Ahora mismo están participando en el concurso BBVA Open Talent así que pasaros por &lt;a href="http://www.bbvaopentalent.com/erasmusu/"&gt;aquí&lt;/a&gt; y votadles.&lt;/li&gt;    &lt;li&gt;A &lt;a href="http://blep.blogspot.com/"&gt;ethernet&lt;/a&gt;, otro Stratero al que tuve la oportunidad de conocer en el Congreso de Desrrolladores de Videojuegos 08. Javi ha creado un producto llamado &lt;a href="http://www.agroguia.es/"&gt;Agroguía&lt;/a&gt; que es un sistema de guiado GPS para tractores. Un curioso nicho de mercado, todo sea dicho :p&lt;/li&gt;    &lt;li&gt;A SiPoX, un habitual de las Kdds madrileñas de Stratos-AD que ha fundado &lt;a href="http://www.undeadcode.com/"&gt;Undead Code&lt;/a&gt;, otra empresa orientada hacia el tema de aplicaciones web y web 2.0. También participan en el BBVA Open Talent con &lt;a href="http://www.somflee.com/"&gt;Somflee&lt;/a&gt;, una mezcla entre red social y herramienta de gestión de contenidos digitales. Podéis votarles &lt;a href="http://www.bbvaopentalent.com/somflee/"&gt;aquí&lt;/a&gt;.&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Para todos ellos, lo mejor. A ver si un día de tanto hablar con vosotros se me contagia algo y me lanzo yo también a la aventura :) (¡acordaos de mi cuando seáis ricos!) &lt;/p&gt;&lt;img src="http://kartones.net/aggbug.aspx?PostID=39208" width="1" height="1"&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/mh-ySBDPF8SBoN-GaU2RJDc5HYU/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/mh-ySBDPF8SBoN-GaU2RJDc5HYU/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/mh-ySBDPF8SBoN-GaU2RJDc5HYU/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/mh-ySBDPF8SBoN-GaU2RJDc5HYU/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/JadEngineBlog/~4/I4XpRD8gUSE" height="1" width="1"/&gt;</description><category domain="http://kartones.net/blogs/jadengine/archive/tags/Off+Topic/default.aspx">Off Topic</category><feedburner:origLink>http://kartones.net/blogs/jadengine/archive/2009/04/08/emprendedores.aspx</feedburner:origLink></item><item><title>Árboles de Expresiones</title><link>http://feedproxy.google.com/~r/JadEngineBlog/~3/Q3qKZ9xTzrE/193-rboles-de-expresiones.aspx</link><pubDate>Tue, 31 Mar 2009 19:00:00 GMT</pubDate><guid isPermaLink="false">b86c0850-82e5-42ed-a9d8-bde9e8f94ec1:38764</guid><dc:creator>Vicente</dc:creator><slash:comments>0</slash:comments><wfw:commentRss>http://kartones.net/blogs/jadengine/rsscomments.aspx?PostID=38764</wfw:commentRss><comments>http://kartones.net/blogs/jadengine/archive/2009/03/31/193-rboles-de-expresiones.aspx#comments</comments><description>&lt;p&gt;Ahora que ya hemos visto que es una &lt;a href="http://kartones.net/blogs/jadengine/archive/2009/03/15/caracter-237-sticas-de-c-3-0-expresiones-lambda.aspx"&gt;expresión lambda&lt;/a&gt; podemos ver otra nueva característica mucho más “rara” de C# 3.0: los árboles de expresiones. En algunos lenguajes, como &lt;a href="http://en.wikipedia.org/wiki/Lisp_programming_language"&gt;Lisp&lt;/a&gt;, se permite manejar el código como si fueran datos y los datos como si fueran código (hace un par de días leyendo el blog del gran &lt;a href="http://blogs.msdn.com/ericlippert/"&gt;Eric Lippert&lt;/a&gt; descubrí que a esto se le llama &lt;i&gt;&lt;a href="http://blogs.msdn.com/ericlippert/archive/2009/03/23/five-dollar-words-for-programmers-part-three-homoiconic.aspx"&gt;homoiconic&lt;/a&gt;&lt;/i&gt;). Los árboles de expresión son la forma que tiene C# de implementar esta funcionalidad (de forma algo limitada).&lt;/p&gt;  &lt;p&gt;Por ejemplo, en el artículo anterior teníamos la expresión lambda:&lt;/p&gt;  &lt;div style="background:white none repeat scroll 0% 0%;font-family:consolas;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;color:black;font-size:10pt;"&gt;   &lt;p style="margin:0px;"&gt;num =&amp;gt; num &amp;lt; 5&lt;/p&gt; &lt;/div&gt;  &lt;p&gt;Que devolvía si un número era menor que cinco o no. Expresado en forma de un delegado del tipo Func, el código sería:&lt;/p&gt;  &lt;div style="background:white none repeat scroll 0% 0%;font-family:consolas;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;color:black;font-size:10pt;"&gt;   &lt;p style="margin:0px;"&gt;&lt;span&gt;Func&lt;/span&gt;&amp;lt;&lt;span style="color:blue;"&gt;int&lt;/span&gt;, &lt;span style="color:blue;"&gt;bool&lt;/span&gt;&amp;gt; f = num =&amp;gt; num &amp;lt; 5;&lt;/p&gt; &lt;/div&gt;  &lt;p&gt;Y la forma de poner lo mismo usando un árbol de expresiones es:&lt;/p&gt;  &lt;div style="background:white none repeat scroll 0% 0%;font-family:consolas;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;color:black;font-size:10pt;"&gt;   &lt;p style="margin:0px;"&gt;System.Linq.Expressions.&lt;span&gt;Expression&lt;/span&gt;&amp;lt;&lt;span&gt;Func&lt;/span&gt;&amp;lt;&lt;span style="color:blue;"&gt;int&lt;/span&gt;, &lt;span style="color:blue;"&gt;bool&lt;/span&gt;&amp;gt;&amp;gt; e = num =&amp;gt; num &amp;lt; 5;&lt;/p&gt; &lt;/div&gt;  &lt;p&gt;La diferencia entre Func y Expression es que &lt;i&gt;&lt;b&gt;f&lt;/b&gt;&lt;/i&gt; es una función que se puede ejecutar:&lt;/p&gt;  &lt;div style="background:white none repeat scroll 0% 0%;font-family:consolas;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;color:black;font-size:10pt;"&gt;   &lt;p style="margin:0px;"&gt;&lt;span style="color:blue;"&gt;bool&lt;/span&gt; result = f(10);&lt;/p&gt; &lt;/div&gt;  &lt;p&gt;Pero para ejecutar &lt;i&gt;&lt;b&gt;e&lt;/b&gt; &lt;/i&gt;tenemos que hacer lo siguiente:&lt;/p&gt;  &lt;div style="background:white none repeat scroll 0% 0%;font-family:consolas;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;color:black;font-size:10pt;"&gt;   &lt;p style="margin:0px;"&gt;&lt;span style="color:blue;"&gt;bool&lt;/span&gt; result = e.Compile()(10);&lt;/p&gt; &lt;/div&gt;  &lt;p&gt;Es decir: para ejecutar un árbol de expresiones primero tenemos que compilarlo (porque son datos que representan código, no código en sí) y una vez compilado ya podemos utilizar el resultado como si fuera un método normal.&lt;/p&gt;  &lt;p&gt;De forma gráfica, &lt;i&gt;&lt;b&gt;e&lt;/b&gt;&lt;/i&gt; internamente está representado por el siguiente árbol:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://kartones.net/blogs/jadengine/tree_0FED6B83.png"&gt;&lt;img src="http://kartones.net/blogs/jadengine/tree_thumb_48981590.png" style="border-width:0px;display:block;float:none;margin-left:auto;margin-right:auto;" title="tree" alt="tree" width="345" border="0" height="245" /&gt;&lt;/a&gt;Pero lo interesante de los árboles de expresiones es que en vez de dejar que el compilador los genere automáticamente, podemos construirlos nosotros a mano. Una vez tenemos una idea de como se representan internamente generarlos por código es bastante fácil (aunque algo tedioso):&lt;/p&gt;  &lt;div style="background:white none repeat scroll 0% 0%;font-family:consolas;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;color:black;font-size:10pt;"&gt;   &lt;pre style="margin:0px;"&gt;&lt;span&gt;ParameterExpression&lt;/span&gt; param = &lt;span&gt;Expression&lt;/span&gt;.Parameter(&lt;span style="color:blue;"&gt;typeof&lt;/span&gt;(&lt;span style="color:blue;"&gt;int&lt;/span&gt;), &lt;span&gt;&amp;quot;num&amp;quot;&lt;/span&gt;);&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span&gt;ConstantExpression&lt;/span&gt; five = &lt;span&gt;Expression&lt;/span&gt;.Constant(5, &lt;span style="color:blue;"&gt;typeof&lt;/span&gt;(&lt;span style="color:blue;"&gt;int&lt;/span&gt;));&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span&gt;BinaryExpression&lt;/span&gt; lessThan = &lt;span&gt;Expression&lt;/span&gt;.LessThan(param, five);&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span&gt;Expression&lt;/span&gt;&amp;lt;&lt;span&gt;Func&lt;/span&gt;&amp;lt;&lt;span style="color:blue;"&gt;int&lt;/span&gt;, &lt;span style="color:blue;"&gt;bool&lt;/span&gt;&amp;gt;&amp;gt; e = &lt;span&gt;Expression&lt;/span&gt;.Lambda&amp;lt;&lt;span&gt;Func&lt;/span&gt;&amp;lt;&lt;span style="color:blue;"&gt;int&lt;/span&gt;, &lt;span style="color:blue;"&gt;bool&lt;/span&gt;&amp;gt;&amp;gt; (lessThan, &lt;span style="color:blue;"&gt;new&lt;/span&gt; &lt;span&gt;ParameterExpression&lt;/span&gt;[] { param });&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Si hacemos un poco de memoria, en el mini motor de RPGs una parte bastante importante del código se encargaba de trabajar con las expresiones matemáticas que definen los valores de las variables de los objetos (los puntos de vida, el bonificador de ataque,…). Lo que hacíamos era definir el modificador en algún sitio (un fichero, una BD, …) como una expresión infijo, es decir, como esto:&lt;/p&gt;

&lt;div style="background:white none repeat scroll 0% 0%;font-family:consolas;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;color:black;font-size:10pt;" align="left"&gt;
  &lt;pre style="margin:0px;"&gt;(a) Attack = 3 * Level + 4 / 7 ^ 34 - 345&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Se aplicaba el algoritmo de &lt;a href="http://en.wikipedia.org/wiki/Shunting_yard_algorithm"&gt;Shunting-Yard&lt;/a&gt; para transformarla en una expresión postfijo:&lt;/p&gt;

&lt;div style="background:white none repeat scroll 0% 0%;font-family:consolas;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;color:black;font-size:10pt;" align="left"&gt;
  &lt;pre style="margin:0px;"&gt;(b) Attack = 3 Level * 4 7 34 ^ / + 345 -&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Y una vez teníamos (b) en forma postfijo se utilizaba un algoritmo para evaluar la expresión que lo que hace es construir un árbol con la siguiente pinta:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://kartones.net/blogs/jadengine/postfixeval_1CE74B94.png"&gt;&lt;img src="http://kartones.net/blogs/jadengine/postfixeval_thumb_27386FF4.png" style="border-width:0px;display:block;float:none;margin-left:auto;margin-right:auto;" title="postfixeval" alt="postfixeval" width="388" border="0" height="268" /&gt;&lt;/a&gt;Y sinceramente, este árbol se parece un montón al árbol del ejemplo anterior :) Así que el cambio realizado en la librería de RPGs va a utilizar árboles de expresiones para permitirnos pasar de esto:&lt;/p&gt;

&lt;div style="background:white none repeat scroll 0% 0%;font-family:consolas;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;color:black;font-size:10pt;" align="left"&gt;
  &lt;pre style="margin:0px;"&gt;&lt;span style="color:blue;"&gt;string&lt;/span&gt; strExp = &lt;span&gt;&amp;quot;3 * Level + 4 / 7 ^ 34 - 345&amp;quot;&lt;/span&gt;;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;A esto:&lt;/p&gt;

&lt;div style="background:white none repeat scroll 0% 0%;font-family:consolas;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;color:black;font-size:10pt;"&gt;
  &lt;pre style="margin:0px;"&gt;&lt;span&gt;Func&lt;/span&gt;&amp;lt;&lt;span&gt;Evaluator&lt;/span&gt;, &lt;span style="color:blue;"&gt;double&lt;/span&gt;&amp;gt; func = (evaluator) =&amp;gt; 3 * evaluator.Chain(Level) + 4 / 7 ^ 34 - 345;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;¡Hemos transformado una cadena de texto en una función en C#! Esta función recibe un objeto del tipo Evaluator (que se utiliza para calcular el valor de las variables como Level, Dexterity,… de forma recursiva) y devuelve un double (el valor de la fórmula).&lt;/p&gt;

&lt;p&gt;El código que realiza esto es bastante sencillo (es una modificación del algoritmo de evaluación):&lt;/p&gt;

&lt;div style="background:white none repeat scroll 0% 0%;font-family:consolas;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;color:black;font-size:10pt;"&gt;
  &lt;pre style="margin:0px;"&gt;&lt;span style="color:blue;"&gt;using&lt;/span&gt; System;&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:blue;"&gt;using&lt;/span&gt; System.Collections.Generic;&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:blue;"&gt;using&lt;/span&gt; System.Linq;&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:blue;"&gt;using&lt;/span&gt; System.Text;&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:blue;"&gt;using&lt;/span&gt; SLE = System.Linq.Expressions;&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&amp;nbsp;&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:blue;"&gt;namespace&lt;/span&gt; GravityAge.Rpg&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;{&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue;"&gt;public&lt;/span&gt; &lt;span style="color:blue;"&gt;static&lt;/span&gt; &lt;span style="color:blue;"&gt;class&lt;/span&gt; &lt;span&gt;Experiments&lt;/span&gt;&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:blue;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; #region&lt;/span&gt; Methods&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&amp;nbsp;&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue;"&gt;public&lt;/span&gt; &lt;span style="color:blue;"&gt;static&lt;/span&gt; SLE.&lt;span&gt;Expression&lt;/span&gt;&amp;lt;&lt;span&gt;Func&lt;/span&gt;&amp;lt;&lt;span&gt;Evaluator&lt;/span&gt;, &lt;span style="color:blue;"&gt;double&lt;/span&gt;&amp;gt;&amp;gt; ToExpressionTree(&lt;span style="color:blue;"&gt;this&lt;/span&gt; &lt;span&gt;Expression&lt;/span&gt; expression)&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span&gt;Stack&lt;/span&gt;&amp;lt;SLE.&lt;span&gt;Expression&lt;/span&gt;&amp;gt; operands;&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; SLE.&lt;span&gt;Expression&lt;/span&gt; op1, op2;&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&amp;nbsp;&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; SLE.&lt;span&gt;ParameterExpression&lt;/span&gt; parameter = SLE.&lt;span&gt;Expression&lt;/span&gt;.Parameter(&lt;span style="color:blue;"&gt;typeof&lt;/span&gt;(&lt;span&gt;Evaluator&lt;/span&gt;), &lt;span&gt;&amp;quot;evaluator&amp;quot;&lt;/span&gt;);&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&amp;nbsp;&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; operands = &lt;span style="color:blue;"&gt;new&lt;/span&gt; &lt;span&gt;Stack&lt;/span&gt;&amp;lt;SLE.&lt;span&gt;Expression&lt;/span&gt;&amp;gt;();&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&amp;nbsp;&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue;"&gt;for&lt;/span&gt; (&lt;span style="color:blue;"&gt;int&lt;/span&gt; i = 0; i &amp;lt; expression.Terms.Count; i++)&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue;"&gt;switch&lt;/span&gt; (expression.Terms[i].TermType)&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue;"&gt;case&lt;/span&gt; &lt;span&gt;TermType&lt;/span&gt;.Number:&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; operands.Push(SLE.&lt;span&gt;Expression&lt;/span&gt;.Constant(expression.Terms[i].Value, &lt;span style="color:blue;"&gt;typeof&lt;/span&gt;(&lt;span style="color:blue;"&gt;double&lt;/span&gt;)));&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue;"&gt;break&lt;/span&gt;;&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&amp;nbsp;&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue;"&gt;case&lt;/span&gt; &lt;span&gt;TermType&lt;/span&gt;.Variable:&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; operands.Push(SLE.&lt;span&gt;Expression&lt;/span&gt;.Call(parameter, &lt;span&gt;&amp;quot;Chain&amp;quot;&lt;/span&gt;, &lt;span style="color:blue;"&gt;new&lt;/span&gt; &lt;span&gt;Type&lt;/span&gt;[] { }, SLE.&lt;span&gt;Expression&lt;/span&gt;.Constant(expression.Terms[i].Text)));&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue;"&gt;break&lt;/span&gt;;&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&amp;nbsp;&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue;"&gt;case&lt;/span&gt; &lt;span&gt;TermType&lt;/span&gt;.Operator:&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; op2 = operands.Pop();&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; op1 = operands.Pop();&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&amp;nbsp;&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue;"&gt;switch&lt;/span&gt; (expression.Terms[i].TermOperator)&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue;"&gt;case&lt;/span&gt; &lt;span&gt;TermOperator&lt;/span&gt;.Add:&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; operands.Push(SLE.&lt;span&gt;Expression&lt;/span&gt;.Add(op1, op2));&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue;"&gt;break&lt;/span&gt;;&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&amp;nbsp;&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue;"&gt;case&lt;/span&gt; &lt;span&gt;TermOperator&lt;/span&gt;.Subtract:&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; operands.Push(SLE.&lt;span&gt;Expression&lt;/span&gt;.Subtract(op1, op2));&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue;"&gt;break&lt;/span&gt;;&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&amp;nbsp;&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue;"&gt;case&lt;/span&gt; &lt;span&gt;TermOperator&lt;/span&gt;.Multiply:&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; operands.Push(SLE.&lt;span&gt;Expression&lt;/span&gt;.Multiply(op1, op2));&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue;"&gt;break&lt;/span&gt;;&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&amp;nbsp;&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue;"&gt;case&lt;/span&gt; &lt;span&gt;TermOperator&lt;/span&gt;.Divide:&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; operands.Push(SLE.&lt;span&gt;Expression&lt;/span&gt;.Divide(op1, op2));&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue;"&gt;break&lt;/span&gt;;&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&amp;nbsp;&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue;"&gt;case&lt;/span&gt; &lt;span&gt;TermOperator&lt;/span&gt;.Power:&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; operands.Push(SLE.&lt;span&gt;Expression&lt;/span&gt;.Power(op1, op2));&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue;"&gt;break&lt;/span&gt;;&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&amp;nbsp;&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue;"&gt;break&lt;/span&gt;;&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&amp;nbsp;&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue;"&gt;default&lt;/span&gt;:&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue;"&gt;throw&lt;/span&gt; &lt;span style="color:blue;"&gt;new&lt;/span&gt; &lt;span&gt;ArgumentException&lt;/span&gt;(&lt;span&gt;&amp;quot;An undefined token (&amp;quot;&lt;/span&gt; + expression.Terms[i].Text + &lt;span&gt;&amp;quot;) appeared while calculating an expression.&amp;quot;&lt;/span&gt;);&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&amp;nbsp;&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue;"&gt;if&lt;/span&gt; (operands.Count == 1)&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue;"&gt;return&lt;/span&gt; SLE.&lt;span&gt;Expression&lt;/span&gt;.Lambda&amp;lt;&lt;span&gt;Func&lt;/span&gt;&amp;lt;&lt;span&gt;Evaluator&lt;/span&gt;, &lt;span style="color:blue;"&gt;double&lt;/span&gt;&amp;gt;&amp;gt;(operands.Pop(), parameter);&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue;"&gt;else&lt;/span&gt;&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue;"&gt;return&lt;/span&gt; &lt;span style="color:blue;"&gt;null&lt;/span&gt;;&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&amp;nbsp;&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&lt;span style="color:blue;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; #endregion&lt;/span&gt;&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/pre&gt;

  &lt;pre style="margin:0px;"&gt;}&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Como podréis ver el código se encuentra dentro de una clase llamada Experiments, ya que no tenía muy claro si iba a ser capaz de hacer esto o no cuando empecé :p Así que estos días me dedicaré a refactorizar y pulir algunas cosas y en breve subiré una nueva versión de la librería a Kartones por si a alguien le interesa.&lt;/p&gt;&lt;img src="http://kartones.net/aggbug.aspx?PostID=38764" width="1" height="1"&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/FpDgk0iEHwpR0mWyCrIiaIdypu8/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/FpDgk0iEHwpR0mWyCrIiaIdypu8/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/FpDgk0iEHwpR0mWyCrIiaIdypu8/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/FpDgk0iEHwpR0mWyCrIiaIdypu8/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/JadEngineBlog/~4/Q3qKZ9xTzrE" height="1" width="1"/&gt;</description><category domain="http://kartones.net/blogs/jadengine/archive/tags/Statecraft/default.aspx">Statecraft</category><category domain="http://kartones.net/blogs/jadengine/archive/tags/RPG/default.aspx">RPG</category><category domain="http://kartones.net/blogs/jadengine/archive/tags/C_2300_/default.aspx">C#</category><feedburner:origLink>http://kartones.net/blogs/jadengine/archive/2009/03/31/193-rboles-de-expresiones.aspx</feedburner:origLink></item><item><title>Características de C# 3.0 – Expresiones Lambda</title><link>http://feedproxy.google.com/~r/JadEngineBlog/~3/J6S6DGP-V90/caracter-237-sticas-de-c-3-0-expresiones-lambda.aspx</link><pubDate>Sun, 15 Mar 2009 01:06:00 GMT</pubDate><guid isPermaLink="false">b86c0850-82e5-42ed-a9d8-bde9e8f94ec1:38027</guid><dc:creator>Vicente</dc:creator><slash:comments>3</slash:comments><wfw:commentRss>http://kartones.net/blogs/jadengine/rsscomments.aspx?PostID=38027</wfw:commentRss><comments>http://kartones.net/blogs/jadengine/archive/2009/03/15/caracter-237-sticas-de-c-3-0-expresiones-lambda.aspx#comments</comments><description>&lt;p&gt;En el artículo &lt;a href="http://kartones.net/blogs/jadengine/archive/2009/02/09/implementando-el-reglamendo-de-un-rpg.aspx"&gt;anterior&lt;/a&gt; comenté el diseño de una pequeña librería para implementar las reglas de un RPG. Desde ese día he realizado pequeños cambios en el código con el objetivo de simplificarlo y aumentar el rendimiento. En este artículo (y el próximo) voy a hablar de algunas características nuevas de C# 3.0 que permiten que nuestra librería sea mucho más flexible.&lt;/p&gt;  &lt;p&gt;En C# 3.0 la gente de Microsoft añadió muchas mejoras en el lenguaje, la mayoría inspirada en los lenguajes funcionales como &lt;a href="http://en.wikipedia.org/wiki/Lisp_programming_language"&gt;Lisp&lt;/a&gt;, &lt;a href="http://en.wikipedia.org/wiki/Ocaml"&gt;OCaml&lt;/a&gt;,… En particular hay dos que van de la mano: las &lt;a href="http://msdn.microsoft.com/en-us/library/bb397687.aspx"&gt;expresiones lambda&lt;/a&gt; y los &lt;a href="http://msdn.microsoft.com/en-us/library/bb397951.aspx"&gt;árboles de expresiones&lt;/a&gt;. Este primer artículo va a tratar de las expresiones lambda, así que recordemos que era un delegado y poco a poco veremos el porqué se añadieron todas estas nuevas características a C#.&lt;/p&gt;  &lt;p&gt;Por ejemplo, queremos filtrar una lista de elementos T en base a un criterio pero queremos que el criterio sea modificable. Este “criterio” es una función que recibirá un T y devolverá un booleano indicando si el elemento cumple el criterio o no. En código tradicional de C# esto sería un delegado y sería algo como lo que sigue:&lt;/p&gt;  &lt;div style="background:white none repeat scroll 0% 0%;font-family:consolas;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;color:black;font-size:10pt;"&gt;   &lt;p style="margin:0px;"&gt;&lt;span style="color:blue;"&gt;delegate&lt;/span&gt; &lt;span style="color:blue;"&gt;bool&lt;/span&gt; &lt;span&gt;Criteria&lt;/span&gt;&amp;lt;T&amp;gt;(T element);&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;nbsp;&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&lt;span style="color:blue;"&gt;class&lt;/span&gt; &lt;span&gt;Program&lt;/span&gt;&lt;/p&gt;    &lt;p style="margin:0px;"&gt;{&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue;"&gt;static&lt;/span&gt; &lt;span&gt;List&lt;/span&gt;&amp;lt;T&amp;gt; FilterList&amp;lt;T&amp;gt;(&lt;span&gt;List&lt;/span&gt;&amp;lt;T&amp;gt; list, &lt;span&gt;Criteria&lt;/span&gt;&amp;lt;T&amp;gt; criteria)&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span&gt;List&lt;/span&gt;&amp;lt;T&amp;gt; newList = &lt;span style="color:blue;"&gt;new&lt;/span&gt; &lt;span&gt;List&lt;/span&gt;&amp;lt;T&amp;gt;();&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue;"&gt;foreach&lt;/span&gt; (T element &lt;span style="color:blue;"&gt;in&lt;/span&gt; list)&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue;"&gt;if&lt;/span&gt; (criteria(element))&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; newList.Add(element);&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;nbsp;&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue;"&gt;return&lt;/span&gt; newList;&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;nbsp;&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue;"&gt;static&lt;/span&gt; &lt;span style="color:blue;"&gt;bool&lt;/span&gt; CriteriaLessThan5(&lt;span style="color:blue;"&gt;int&lt;/span&gt; intValue)&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue;"&gt;return&lt;/span&gt; intValue &amp;lt; 5;&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;nbsp;&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue;"&gt;static&lt;/span&gt; &lt;span style="color:blue;"&gt;bool&lt;/span&gt; CriteriaBiggerThan5(&lt;span style="color:blue;"&gt;int&lt;/span&gt; intValue)&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue;"&gt;return&lt;/span&gt; intValue &amp;gt; 5;&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;nbsp;&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue;"&gt;static&lt;/span&gt; &lt;span style="color:blue;"&gt;void&lt;/span&gt; Main(&lt;span style="color:blue;"&gt;string&lt;/span&gt;[] args)&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span&gt;List&lt;/span&gt;&amp;lt;&lt;span style="color:blue;"&gt;int&lt;/span&gt;&amp;gt; numbers = &lt;span style="color:blue;"&gt;new&lt;/span&gt; &lt;span&gt;List&lt;/span&gt;&amp;lt;&lt;span style="color:blue;"&gt;int&lt;/span&gt;&amp;gt;() { 1, 2, 3, 4, 5, 6, 7, 8, 9 };&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span&gt;List&lt;/span&gt;&amp;lt;&lt;span style="color:blue;"&gt;int&lt;/span&gt;&amp;gt; numbers2;&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;nbsp;&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; numbers2 = FilterList(numbers, CriteriaLessThan5);&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue;"&gt;foreach&lt;/span&gt; (&lt;span style="color:blue;"&gt;int&lt;/span&gt; number &lt;span style="color:blue;"&gt;in&lt;/span&gt; numbers2)&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span&gt;Console&lt;/span&gt;.WriteLine(number);&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;nbsp;&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; numbers2 = FilterList(numbers, CriteriaBiggerThan5);&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue;"&gt;foreach&lt;/span&gt; (&lt;span style="color:blue;"&gt;int&lt;/span&gt; number &lt;span style="color:blue;"&gt;in&lt;/span&gt; numbers2)&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span&gt;Console&lt;/span&gt;.WriteLine(number);&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;nbsp;&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span&gt;Console&lt;/span&gt;.ReadKey();&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;    &lt;p style="margin:0px;"&gt;}&lt;/p&gt; &lt;/div&gt;  &lt;p&gt;Si os fijáis he declarado un delegado (Criteria) que recibe un elemento T y devuelve bool. Luego he añadido una función FilterList que recibe una lista y un criterio y devuelve la lista filtrada y por último en el main he usado dos funciones diferentes para filtrar una misma lista de números.&lt;/p&gt;  &lt;p&gt;A partir de C# 2.0 se añadió al lenguaje la capacidad de declarar delegados anónimos (al vuelo). Usando delegados anónimos el código anterior tendría la siguiente pinta:&lt;/p&gt;  &lt;div style="background:white none repeat scroll 0% 0%;font-family:consolas;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;color:black;font-size:10pt;"&gt;   &lt;p style="margin:0px;"&gt;&lt;span style="color:blue;"&gt;delegate&lt;/span&gt; &lt;span style="color:blue;"&gt;bool&lt;/span&gt; &lt;span&gt;Criteria&lt;/span&gt;&amp;lt;T&amp;gt;(T element);&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;nbsp;&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&lt;span style="color:blue;"&gt;class&lt;/span&gt; &lt;span&gt;Program2&lt;/span&gt;&lt;/p&gt;    &lt;p style="margin:0px;"&gt;{&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue;"&gt;static&lt;/span&gt; &lt;span&gt;List&lt;/span&gt;&amp;lt;T&amp;gt; FilterList&amp;lt;T&amp;gt;(&lt;span&gt;List&lt;/span&gt;&amp;lt;T&amp;gt; list, &lt;span&gt;Criteria&lt;/span&gt;&amp;lt;T&amp;gt; criteria)&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span&gt;List&lt;/span&gt;&amp;lt;T&amp;gt; newList = &lt;span style="color:blue;"&gt;new&lt;/span&gt; &lt;span&gt;List&lt;/span&gt;&amp;lt;T&amp;gt;();&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue;"&gt;foreach&lt;/span&gt; (T element &lt;span style="color:blue;"&gt;in&lt;/span&gt; list)&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue;"&gt;if&lt;/span&gt; (criteria(element))&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; newList.Add(element);&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;nbsp;&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue;"&gt;return&lt;/span&gt; newList;&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;nbsp;&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue;"&gt;static&lt;/span&gt; &lt;span style="color:blue;"&gt;void&lt;/span&gt; Main(&lt;span style="color:blue;"&gt;string&lt;/span&gt;[] args)&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span&gt;List&lt;/span&gt;&amp;lt;&lt;span style="color:blue;"&gt;int&lt;/span&gt;&amp;gt; numbers = &lt;span style="color:blue;"&gt;new&lt;/span&gt; &lt;span&gt;List&lt;/span&gt;&amp;lt;&lt;span style="color:blue;"&gt;int&lt;/span&gt;&amp;gt;() { 1, 2, 3, 4, 5, 6, 7, 8, 9 };&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span&gt;List&lt;/span&gt;&amp;lt;&lt;span style="color:blue;"&gt;int&lt;/span&gt;&amp;gt; numbers2;&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;nbsp;&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; numbers2 = FilterList(numbers, &lt;span style="color:blue;"&gt;delegate&lt;/span&gt;(&lt;span style="color:blue;"&gt;int&lt;/span&gt; e) { &lt;span style="color:blue;"&gt;return&lt;/span&gt; e &amp;lt; 5; });&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue;"&gt;foreach&lt;/span&gt; (&lt;span style="color:blue;"&gt;int&lt;/span&gt; number &lt;span style="color:blue;"&gt;in&lt;/span&gt; numbers2)&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span&gt;Console&lt;/span&gt;.WriteLine(number);&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;nbsp;&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; numbers2 = FilterList(numbers, &lt;span style="color:blue;"&gt;delegate&lt;/span&gt;(&lt;span style="color:blue;"&gt;int&lt;/span&gt; e) { &lt;span style="color:blue;"&gt;return&lt;/span&gt; e &amp;gt; 5; });&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue;"&gt;foreach&lt;/span&gt; (&lt;span style="color:blue;"&gt;int&lt;/span&gt; number &lt;span style="color:blue;"&gt;in&lt;/span&gt; numbers2)&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span&gt;Console&lt;/span&gt;.WriteLine(number);&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;nbsp;&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span&gt;Console&lt;/span&gt;.ReadKey();&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;    &lt;p style="margin:0px;"&gt;}&lt;/p&gt; &lt;/div&gt;  &lt;p&gt;Ahora los delegados están metidos directamente en la llamada al método FilterList. En C# 3.0 se añaden las expresiones lambda que es una forma más “bonita” de escribir lo mismo. Además se añaden los delegados genéricos &lt;a href="http://msdn.microsoft.com/en-us/library/018hxwa8.aspx"&gt;Action&lt;/a&gt; y &lt;a href="http://msdn.microsoft.com/en-us/library/bb534960.aspx"&gt;Func&lt;/a&gt; que nos ahorran tener que declarar delegados propios. Con lo que en C# 3.0 nuestro código quedaría así:&lt;/p&gt;  &lt;div style="background:white none repeat scroll 0% 0%;font-family:consolas;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;color:black;font-size:10pt;"&gt;   &lt;p style="margin:0px;"&gt;&lt;span style="color:blue;"&gt;class&lt;/span&gt; &lt;span&gt;Program3&lt;/span&gt;&lt;/p&gt;    &lt;p style="margin:0px;"&gt;{&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue;"&gt;static&lt;/span&gt; &lt;span&gt;List&lt;/span&gt;&amp;lt;T&amp;gt; FilterList&amp;lt;T&amp;gt;(&lt;span&gt;List&lt;/span&gt;&amp;lt;T&amp;gt; list, &lt;span&gt;Func&lt;/span&gt;&amp;lt;T, &lt;span style="color:blue;"&gt;bool&lt;/span&gt;&amp;gt; criteria)&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span&gt;List&lt;/span&gt;&amp;lt;T&amp;gt; newList = &lt;span style="color:blue;"&gt;new&lt;/span&gt; &lt;span&gt;List&lt;/span&gt;&amp;lt;T&amp;gt;();&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue;"&gt;foreach&lt;/span&gt; (T element &lt;span style="color:blue;"&gt;in&lt;/span&gt; list)&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue;"&gt;if&lt;/span&gt; (criteria(element))&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; newList.Add(element);&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;nbsp;&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue;"&gt;return&lt;/span&gt; newList;&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;nbsp;&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue;"&gt;static&lt;/span&gt; &lt;span style="color:blue;"&gt;void&lt;/span&gt; Main(&lt;span style="color:blue;"&gt;string&lt;/span&gt;[] args)&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span&gt;List&lt;/span&gt;&amp;lt;&lt;span style="color:blue;"&gt;int&lt;/span&gt;&amp;gt; numbers = &lt;span style="color:blue;"&gt;new&lt;/span&gt; &lt;span&gt;List&lt;/span&gt;&amp;lt;&lt;span style="color:blue;"&gt;int&lt;/span&gt;&amp;gt;() { 1, 2, 3, 4, 5, 6, 7, 8, 9 };&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span&gt;List&lt;/span&gt;&amp;lt;&lt;span style="color:blue;"&gt;int&lt;/span&gt;&amp;gt; numbers2;&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;nbsp;&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; numbers2 = FilterList(numbers, e =&amp;gt; e &amp;lt; 5);&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue;"&gt;foreach&lt;/span&gt; (&lt;span style="color:blue;"&gt;int&lt;/span&gt; number &lt;span style="color:blue;"&gt;in&lt;/span&gt; numbers2)&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span&gt;Console&lt;/span&gt;.WriteLine(number);&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;nbsp;&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; numbers2 = FilterList(numbers, e =&amp;gt; e &amp;gt; 5);&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:blue;"&gt;foreach&lt;/span&gt; (&lt;span style="color:blue;"&gt;int&lt;/span&gt; number &lt;span style="color:blue;"&gt;in&lt;/span&gt; numbers2)&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span&gt;Console&lt;/span&gt;.WriteLine(number);&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;nbsp;&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span&gt;Console&lt;/span&gt;.ReadKey();&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;    &lt;p style="margin:0px;"&gt;}&lt;/p&gt; &lt;/div&gt;  &lt;p&gt;Fijaos cómo ahora ya no se declara ningún delegado “Criteria” porque FilterList recibe un Func&amp;lt;T, bool&amp;gt;, es decir, un delegado genérico que tiene un parámetro T y devuelve un bool. Y además hemos sustituido en la llamada a FilterList lo de “delegate(int e)…” por una expresión lambda (=&amp;gt;) que recibe un “e” y devuelve si ese “e” es menor o mayor que 5 (el compilador automáticamente infiere que “e” tiene que ser de tipo int).&lt;/p&gt;  &lt;p&gt;En el próximo artículo veremos como se relacionan las expresiones lambda con los árboles de expresiones, que nos permiten generar y modificar código de forma dinámica dentro del propio programa (código como datos, algo bastante común en los lenguajes funcionales) y la utilidad que tiene esto en una librería para implementar RPGs.&lt;/p&gt;&lt;img src="http://kartones.net/aggbug.aspx?PostID=38027" width="1" height="1"&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/5SqlWWCXzWixZexkh2Nx3V5V3DQ/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/5SqlWWCXzWixZexkh2Nx3V5V3DQ/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/5SqlWWCXzWixZexkh2Nx3V5V3DQ/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/5SqlWWCXzWixZexkh2Nx3V5V3DQ/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/JadEngineBlog/~4/J6S6DGP-V90" height="1" width="1"/&gt;</description><category domain="http://kartones.net/blogs/jadengine/archive/tags/Statecraft/default.aspx">Statecraft</category><category domain="http://kartones.net/blogs/jadengine/archive/tags/RPG/default.aspx">RPG</category><category domain="http://kartones.net/blogs/jadengine/archive/tags/C_2300_/default.aspx">C#</category><feedburner:origLink>http://kartones.net/blogs/jadengine/archive/2009/03/15/caracter-237-sticas-de-c-3-0-expresiones-lambda.aspx</feedburner:origLink></item><item><title>Implementando el reglamento de un RPG</title><link>http://feedproxy.google.com/~r/JadEngineBlog/~3/O9uug9nrBt8/implementando-el-reglamendo-de-un-rpg.aspx</link><pubDate>Mon, 09 Feb 2009 07:52:00 GMT</pubDate><guid isPermaLink="false">b86c0850-82e5-42ed-a9d8-bde9e8f94ec1:37099</guid><dc:creator>Vicente</dc:creator><slash:comments>4</slash:comments><wfw:commentRss>http://kartones.net/blogs/jadengine/rsscomments.aspx?PostID=37099</wfw:commentRss><comments>http://kartones.net/blogs/jadengine/archive/2009/02/09/implementando-el-reglamendo-de-un-rpg.aspx#comments</comments><description>&lt;p&gt;&lt;b&gt;Aviso:&lt;/b&gt; este artículo es bastante largo, aunque no demasiado técnico, así que debería ser fácil de seguir.&lt;/p&gt;  &lt;p&gt;Desde hace bastantes años siempre he tenido la idea de portar las reglas del &lt;a href="http://en.wikipedia.org/wiki/Dungeons_&amp;amp;_Dragons"&gt;Dungeons and Dragons&lt;/a&gt; (o algo similar) al ordenador, pero siempre he terminado fracasando por varios motivos:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Son sistemas muy complicados. &lt;/li&gt;    &lt;li&gt;Están llenos de excepciones. &lt;/li&gt;    &lt;li&gt;Tienen que ser muy extensibles porque seguramente aparecerán nuevas reglas con el paso del tiempo. &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Estos días he tenido bastante tiempo libre y he decido intentar por n-esima vez hacer un “mini-framework” que me permita implementar algo parecido a una simplificacón del &lt;a href="http://en.wikipedia.org/wiki/D20_System"&gt;sistema d20&lt;/a&gt; para mis propios proyectos. El resto de este artículo va a tratar de los problemas que he encontrado para realizar esta implementación básica (aún le faltan muchas cosas). Al final de todo hay un link con el código fuente para él que le quiera echar un vistazo.&lt;/p&gt;  &lt;p&gt;El primer problema que me he encontrado siempre al intentar hacer este tipo de sistemas es que los objetos tienen muchísimas propiedades. Por ejemplo un personaje tiene atributos, habilidades, dotes, conjuros, equipo, clases,… A pesar de agrupar en clases y usar todas las herramientas que proporciona la programación orientada a objetos siempre he terminado teniendo en cada clase un ejército de propiedades que se vuelve inmanejable.&lt;/p&gt;  &lt;p&gt;Así que decidí atacar el problema de otra forma: cada clase tiene una tabla hash que representa sus propiedades. De esta forma cada clase puede tener “infinitas” propiedades y además las puedo definir cuando quiera. Si quiero una propiedad hago:&lt;/p&gt;  &lt;pre&gt;&lt;pre style="margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;objeto.Set(&amp;quot;&lt;span&gt;Propiedad&lt;/span&gt;&amp;quot;, valor);&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;Y si quiero obtener el valor hago:&lt;/p&gt;

&lt;pre&gt;&lt;pre style="margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;&lt;span&gt;object&lt;/span&gt; resultado = objeto.Get(&amp;quot;&lt;span&gt;Propiedad&lt;/span&gt;&amp;quot;);&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;La verdad que casi cualquiera que vea esto pensará que esta aproximación tiene muchos problemas:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Se usan strings para los nombres de las propiedades y es muy fácil equivocarse al escribirlos (confundir una mayúscula, una letra,…) y que el programa de un error o devuelva un valor erróneo. Depurar esto es un jaleo bastante serio. &lt;/li&gt;

  &lt;li&gt;Hay que calcular hashes de strings todo el rato (una operación bastante lenta). &lt;/li&gt;

  &lt;li&gt;No es tipada: tenemos objects por todos los lados que tenemos que castear al tipo correcto (lento y propenso a errores). &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;La verdad que yo mismo no estaba muy convencido de que esto fuera una buena idea hasta que me encontré &lt;a href="http://steve-yegge.blogspot.com/2008/10/universal-design-pattern.html"&gt;este&lt;/a&gt; artículo de Steve Yegge donde habla del patrón &lt;a href="http://en.wikipedia.org/wiki/Prototype_pattern"&gt;prototype&lt;/a&gt; y de la programación basada en prototipos en vez de orientada a objetos.&lt;/p&gt;

&lt;p&gt;El artículo, aún siendo largo, es bastante interesante y explica bastante bien que es y como se usan los prototipos. Resumiendo mucho: un prototipo es una tabla hash que contiene todas las propiedades y operaciones de un objeto (en vez de ser entidades independientes como en la programación orientada a objetos).&lt;/p&gt;

&lt;p&gt;Dado que yo programo en C# y que este lenguaje no da soporte para prototipos (como por ejemplo &lt;a href="http://en.wikipedia.org/wiki/Io_%28programming_language%29"&gt;IO&lt;/a&gt;), implementé las ideas del post de Steve en la clase &lt;b&gt;Prototype&lt;/b&gt;. Esta clase contiene:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Un campo &lt;i&gt;parent&lt;/i&gt; que es el prototipo del que se “hereda”. &lt;/li&gt;

  &lt;li&gt;Un campo &lt;i&gt;properties&lt;/i&gt; que es el diccionario de propiedades. &lt;/li&gt;

  &lt;li&gt;Una propiedad &lt;i&gt;IsReadOnly&lt;/i&gt; que permite hacer al prototipo de solo lectura. &lt;/li&gt;

  &lt;li&gt;Cuatro métodos (&lt;i&gt;Get&lt;/i&gt;, &lt;i&gt;Set&lt;/i&gt;, &lt;i&gt;Contains&lt;/i&gt; y &lt;i&gt;Remove&lt;/i&gt;) que permiten modificar la información del prototipo. &lt;/li&gt;

  &lt;li&gt;Y un método &lt;i&gt;Clone&lt;/i&gt; que permite crear un nuevo prototipo que herede del actual. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Lo único interesante de esta clase es que los métodos &lt;i&gt;Get&lt;/i&gt; y &lt;i&gt;Contains&lt;/i&gt; permiten buscar valores en el padre del prototipo. Es decir, &lt;i&gt;parent&lt;/i&gt; cumple la función de la superclase en la programación orientada a objetos. Como podéis ver, esta implementación no es nada complicada y permite hacer cosas como:&lt;/p&gt;

&lt;pre&gt;&lt;pre style="margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;Prototype guardia = &lt;span&gt;new&lt;/span&gt; Prototype();&lt;br /&gt;&lt;/pre&gt;&lt;pre style="margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;guardia.Set(&amp;quot;&lt;span&gt;Ataque&lt;/span&gt;&amp;quot;, 10);&lt;br /&gt;&lt;/pre&gt;&lt;pre style="margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;guardia.Set(&amp;quot;&lt;span&gt;Vida&lt;/span&gt;&amp;quot;, 5);&lt;br /&gt;&lt;/pre&gt;&lt;pre style="margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;&lt;/pre&gt;&lt;pre style="margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;Prototype alitar = guardia.Clone();&lt;br /&gt;&lt;/pre&gt;&lt;pre style="margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;alitar.Set(&amp;quot;&lt;span&gt;Nombre&lt;/span&gt;&amp;quot;, &amp;quot;&lt;span&gt;Alitar&lt;/span&gt;&amp;quot;);&lt;br /&gt;&lt;/pre&gt;&lt;pre style="margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;alitar.Set(&amp;quot;&lt;span&gt;TieneMiedoALosDragones&lt;/span&gt;&amp;quot;, &lt;span&gt;true&lt;/span&gt;);&lt;br /&gt;&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;Como se puede ver, he definido un guardia prototipo y luego un guardia especial que he llamado Alitar y que tiene miedo a los dragones. Alitar se comportará como cualquier otro guardia, pero cuando vea un dragón huirá en vez de luchar (¿quizás también tendría que ponerle más inteligencia? :p).&lt;/p&gt;

&lt;p&gt;Una vez resuelto el problema fácil, queda el difícil (y bastante más interesante): calcular lo que vale una variable en un RPG. Por ejemplo: ¿cuanto vale el bonificador de ataque cuerpo a cuerpo de un personaje? En el d20 este número depende de muchísimas cosas:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;La fuerza del personaje (o la destreza según que arma esté usando y si tiene las dotes adecuadas). &lt;/li&gt;

  &lt;li&gt;El nivel de cada clase del personaje. &lt;/li&gt;

  &lt;li&gt;Sus dotes. &lt;/li&gt;

  &lt;li&gt;Conjuros. &lt;/li&gt;

  &lt;li&gt;Otras habilidades o modificadores circunstanciales. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Básicamente calcular ciertos valores en un RPG es un lío increíble. Hace tiempo descubrí una herramienta llamada &lt;a href="http://pcgen.sourceforge.net/"&gt;PCGen&lt;/a&gt; que es un generador de personajes para el sistema d20. Esta herramienta tiene un lenguaje de definición de reglas muy potente, por ejemplo:&lt;/p&gt;

&lt;p align="center"&gt;&lt;b&gt;&lt;i&gt;BONUS:COMBAT|AC|Level / 2|TYPE=NaturalArmor.REPLACE&lt;/i&gt;&lt;/b&gt;&lt;/p&gt;

&lt;p align="left"&gt;Esta línea significa un bonificador de combate a la armadura (AC) igual al nivel del personaje dividido entre dos, del tipo armadura natural que reemplaza a cualquier bonificador existente del mismo tipo. Este ejemplo es bastante básico, pero hay verdaderas virguerías definidas con él.&lt;/p&gt;

&lt;p align="left"&gt;Así que realmente el segundo problema son dos subproblemas:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;div align="left"&gt;Como definir modificadores y expresiones matemáticas (Level / 2).&lt;/div&gt;
  &lt;/li&gt;

  &lt;li&gt;
    &lt;div align="left"&gt;Como saber que modificadores afectan a una variable y como evaluar el valor de la misma.&lt;/div&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p align="left"&gt;El primer subproblema es “sencillo” de resolver si uno no se complica mucho la vida. En mi caso decidí imponer a las expresiones la restricción de que las diferentes partes que la forman deberían estar separadas por un espacio. Esto me permite partir la expresión con una sola llamada a &lt;a href="http://msdn.microsoft.com/en-us/library/system.string.split.aspx"&gt;String.Split&lt;/a&gt;. Luego un simple parser recorre los pedazos de la expresión y los clasifica en cuatro tipos:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;div align="left"&gt;&lt;b&gt;Números:&lt;/b&gt; 3, 5.7, 23434,…&lt;/div&gt;
  &lt;/li&gt;

  &lt;li&gt;
    &lt;div align="left"&gt;&lt;b&gt;Operadores:&lt;/b&gt; +, –, *, /, ^&lt;/div&gt;
  &lt;/li&gt;

  &lt;li&gt;
    &lt;div align="left"&gt;&lt;b&gt;Símbolos:&lt;/b&gt; (, )&lt;/div&gt;
  &lt;/li&gt;

  &lt;li&gt;
    &lt;div align="left"&gt;&lt;b&gt;Variables:&lt;/b&gt; cualquier otra cosa&lt;/div&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p align="left"&gt;Esto debería ser suficiente para definir cualquier tipo de operación matemática que pueda ser de utilidad. En el fichero &lt;b&gt;ExpressionParser.cs&lt;/b&gt; se puede ver el código de este pequeño parser. Una cosa “curiosa” del código es que al final del parseo se ejecuta una función llamada &lt;i&gt;ShuntingYard&lt;/i&gt;. Esta función implementa el algoritmo de &lt;a href="http://en.wikipedia.org/wiki/Shunting_yard_algorithm"&gt;Shunting-Yard&lt;/a&gt; inventado por &lt;a href="http://en.wikipedia.org/wiki/Edsger_W._Dijkstra"&gt;Djikstra&lt;/a&gt; que permite pasar expresiones en formato &lt;a href="http://en.wikipedia.org/wiki/Infix_notation"&gt;infijo&lt;/a&gt; (2 + 3) a formato &lt;a href="http://en.wikipedia.org/wiki/Postfix_notation"&gt;postfijo&lt;/a&gt; o notación polaca inversa (2 3 +).&lt;/p&gt;

&lt;p align="left"&gt;¿Y por qué hacer semejante cosa? Porque la notación postfijo tiene una gran ventaja: es muy fácil de evaluar. Estoy seguro que hacerse un evaluador de expresiones en formato infijo no es demasiado difícil, pero en formato postfijo es trivial y el coste de transformar la expresión es muy bajo (y solo hay que pagarlo una vez).&lt;/p&gt;

&lt;p align="left"&gt;Y por último hay que ver como buscar los modificadores que afectan a una variable y como calcular su valor. Imaginemos que tenemos un objeto Espada definido de esta forma:&lt;/p&gt;

&lt;pre&gt;&lt;pre style="margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;Prototype arma = &lt;span&gt;new&lt;/span&gt; Prototype();&lt;br /&gt;&lt;/pre&gt;&lt;pre style="margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;arma.Set(&amp;quot;&lt;span&gt;Nombre&lt;/span&gt;&amp;quot;, &amp;quot;&lt;span&gt;Espada&lt;/span&gt;&amp;quot;);&lt;br /&gt;&lt;/pre&gt;&lt;pre style="margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;arma.Set(&amp;quot;&lt;span&gt;Dureza&lt;/span&gt;&amp;quot;, 5);&lt;/pre&gt;&lt;/pre&gt;

&lt;p align="left"&gt;Para obtener su dureza basta con escribir:&lt;/p&gt;

&lt;pre&gt;&lt;pre style="margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;&lt;span&gt;int&lt;/span&gt; dureza = arma.Get&amp;lt;&lt;span&gt;int&lt;/span&gt;&amp;gt;(&amp;quot;&lt;span&gt;Dureza&lt;/span&gt;&amp;quot;);&lt;/pre&gt;&lt;/pre&gt;

&lt;p align="left"&gt;Ahora imaginemos que cojo a la Espada y la modifico añadiéndole otro prototypo que representa que está hecha de Mithril, lo que le da una dureza extra.&lt;/p&gt;

&lt;p align="left"&gt;&lt;a href="http://kartones.net/blogs/jadengine/imagen1_4ADEE8EE.png"&gt;&lt;img src="http://kartones.net/blogs/jadengine/imagen1_thumb_33637316.png" style="border-width:0px;display:block;float:none;margin-left:auto;margin-right:auto;" title="imagen1" alt="imagen1" width="131" border="0" height="156" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p align="left"&gt;Para calcular su dureza ahora hay que buscar en sus modificadores pero también en los del objeto Mithril. En el siguiente diagrama se puede ver un ejemplo un poco más complicado:&lt;/p&gt;

&lt;p align="left"&gt;&lt;a href="http://kartones.net/blogs/jadengine/imagen2_12DC3364.png"&gt;&lt;img src="http://kartones.net/blogs/jadengine/imagen2_thumb_5D63713E.png" style="border-width:0px;display:block;float:none;margin-left:auto;margin-right:auto;" title="imagen2" alt="imagen2" width="281" border="0" height="246" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p align="left"&gt;Se puede ver que se ha formado una estructura en forma de árbol, así que para buscar los modificadores decidí utilizar una &lt;a href="http://en.wikipedia.org/wiki/Breadth-first_search"&gt;búsqueda en anchura&lt;/a&gt;: primero la raiz, luego los hijos, luego los hijos de los hijos,…&lt;/p&gt;

&lt;p align="left"&gt;Pero ahora imaginemos que esa espada está en manos de un personaje que es de la clase bárbaro, y que los bárbaros hacen que todos los objetos en sus manos sean menos duros (porque tienden a romperlos).&lt;/p&gt;

&lt;p align="left"&gt;&lt;a href="http://kartones.net/blogs/jadengine/imagen3_3CDC318C.png"&gt;&lt;img src="http://kartones.net/blogs/jadengine/imagen3_thumb_3C6FFE97.png" style="border-width:0px;display:block;float:none;margin-left:auto;margin-right:auto;" title="imagen3" alt="imagen3" width="329" border="0" height="310" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p align="left"&gt;Como se puede ver la dureza del arma ha sido modificada por un valor que no está en sus hijos, si no que está en otra parte del árbol. Así que hay que modificar un poco la búsqueda en anchura:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;div align="left"&gt;Se busca la verdadera raíz del árbol a partir del nodo al que se le pidió el valor.&lt;/div&gt;
  &lt;/li&gt;

  &lt;li&gt;
    &lt;div align="left"&gt;Se inicia la búsqueda en anchura desde este nodo.&lt;/div&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p align="left"&gt;Pero sigamos imaginando: ahora el personaje también tiene una Armadura y esta a su vez es de Adamantio.&lt;/p&gt;

&lt;p align="left"&gt;&lt;a href="http://kartones.net/blogs/jadengine/imagen4_50F54E15.png"&gt;&lt;img src="http://kartones.net/blogs/jadengine/imagen4_thumb_29BB04E0.png" style="border-width:0px;display:block;float:none;margin-left:auto;margin-right:auto;" title="imagen4" alt="imagen4" width="441" border="0" height="291" /&gt;&lt;/a&gt;Está claro que si pregunto por la dureza de la Espada no debería influir para nada los modificadores a la dureza de la Armadura o del Adamantio. Para resolver este nuevo problema hay que añadir una nueva propiedad a los modificadores: visibilidad (global o local). Y hay que volver a cambiar la búsqueda en anchura:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;div align="left"&gt;Se guarda el nodo que inició la búsqueda (la Espada).&lt;/div&gt;
  &lt;/li&gt;

  &lt;li&gt;
    &lt;div align="left"&gt;Se comienza la búsqueda desde la raíz (el Personaje).&lt;/div&gt;
  &lt;/li&gt;

  &lt;li&gt;
    &lt;div align="left"&gt;Si el modificador está en un nodo fuera del subárbol definido por el nodo que inició la búsqueda, solo se aplicarán los modificadores globales. Si el modificador está definido en un nodo perteneciente al subárbol se aplicarán todos los tipos de modificadores.&lt;/div&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p align="left"&gt;&lt;a href="http://kartones.net/blogs/jadengine/imagen5_6984EB65.png"&gt;&lt;img src="http://kartones.net/blogs/jadengine/imagen5_thumb_372117E6.png" style="border-width:0px;display:block;float:none;margin-left:auto;margin-right:auto;" title="imagen5" alt="imagen5" width="469" border="0" height="312" /&gt;&lt;/a&gt;La búsqueda se inició en el objeto Espada, así que fuera del subárbol que define (marcado en rojo) solo se aplican los modificadores marcados como global. Así conseguimos que se aplique el modificador de Bárbaro pero no el de Armadura o Adamantio.&lt;/p&gt;

&lt;p align="left"&gt;Esta forma de buscar modificadores cubre todos los casos que se me han ocurrido. Seguro que hay situaciones que no resuelvo, pero no me pienso complicar más la vida (de momento y sin una buena razón). &lt;/p&gt;

&lt;p align="left"&gt;Ya está la búsqueda de modificadores, ahora queda ver como calcular el valor de una variable. El valor de una variable es modificado por los objetos de tipo &lt;b&gt;Modifier&lt;/b&gt; que a su vez contienen expresiones matemáticas en forma de objetos &lt;b&gt;Expression&lt;/b&gt;. Estas expresiones pueden ser simples como hemos visto hasta ahora o depender de otras variables, por ejemplo:&lt;/p&gt;

&lt;p align="left"&gt;&lt;a href="http://kartones.net/blogs/jadengine/imagen6_0FE6CEB1.png"&gt;&lt;img src="http://kartones.net/blogs/jadengine/imagen6_thumb_68AC857B.png" style="border-width:0px;display:block;float:none;margin-left:auto;margin-right:auto;" title="imagen6" alt="imagen6" width="507" border="0" height="355" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p align="left"&gt;Ahora la dureza de la Espada depende de su peso también. Para resolver esto la evaluación de variables se ejecutará de la siguiente manera:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;div align="left"&gt;Cuando se comienza a evaluar una variable se apunta en una tabla de variables calculadas con el valor de menos infinito.&lt;/div&gt;
  &lt;/li&gt;

  &lt;li&gt;
    &lt;div align="left"&gt;Si esta variable tiene un modificador que contiene una variable, se consulta a la tabla de variables ya calculadas.&lt;/div&gt;

    &lt;ul&gt;
      &lt;li&gt;
        &lt;div align="left"&gt;Si el valor de la variable es menos infinito hay una referencia circular (variable = variable) y el valor no se puede resolver. Excepción.&lt;/div&gt;
      &lt;/li&gt;

      &lt;li&gt;
        &lt;div align="left"&gt;Si es otra cosa se devuelve el valor y se continúa evaluando la variable actual.&lt;/div&gt;
      &lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;

  &lt;li&gt;
    &lt;div align="left"&gt;Si la variable no se encuentra en la tabla de variables ya calculadas se inicia una nueva evaluación para esa variable (vuelta al principio de este proceso).&lt;/div&gt;
  &lt;/li&gt;

  &lt;li&gt;
    &lt;div align="left"&gt;Cuando se termina de calcular el valor de una variable se actualiza en la tabla.&lt;/div&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p align="left"&gt;La clase &lt;b&gt;Evaluator&lt;/b&gt; es la que se encarga de la búsqueda de modificadores y evaluación de variables.&lt;/p&gt;

&lt;p align="left"&gt;El código fuente de todo este jaleo se puede descargar desde este &lt;a href="http://kartones.net/files/folders/gamesources/entry37098.aspx"&gt;link&lt;/a&gt; (está bajo licencia MIT así que se puede hacer cualquier cosa con él). El zip contiene una solución de Visual Studio 2008 (C#) que está compuesta de dos proyectos:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;div align="left"&gt;&lt;b&gt;GravityAge.Statecraft.Core:&lt;/b&gt; el código de los prototipos y la evaluación de variables. Está bastante comentado así que debería ser fácil de comprender si se ha entendido este artículo.&lt;/div&gt;
  &lt;/li&gt;

  &lt;li&gt;
    &lt;div align="left"&gt;&lt;b&gt;GravityAge.Statecraft.Tests:&lt;/b&gt; unas cuantas pruebas unitarias para comprobar que todo está más o menos bien (debería hacer más, pero de momento con estas me basta). Hay una prueba que no se pasa (comprobar que una expresión infijo está bien formada) pero no sé como hacer que el parser se de cuenta de eso sin complicarme la vida demasiado, así que dejo el test roto para que no se me olvide que algún día debería solucionarlo.&lt;/div&gt;
  &lt;/li&gt;
&lt;/ul&gt;&lt;img src="http://kartones.net/aggbug.aspx?PostID=37099" width="1" height="1"&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/hCtjUcftSrNW2IBwqhau88r-niI/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/hCtjUcftSrNW2IBwqhau88r-niI/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/hCtjUcftSrNW2IBwqhau88r-niI/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/hCtjUcftSrNW2IBwqhau88r-niI/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/JadEngineBlog/~4/O9uug9nrBt8" height="1" width="1"/&gt;</description><category domain="http://kartones.net/blogs/jadengine/archive/tags/Statecraft/default.aspx">Statecraft</category><category domain="http://kartones.net/blogs/jadengine/archive/tags/RPG/default.aspx">RPG</category><feedburner:origLink>http://kartones.net/blogs/jadengine/archive/2009/02/09/implementando-el-reglamendo-de-un-rpg.aspx</feedburner:origLink></item><item><title>Desarrollando un juego para Surface</title><link>http://feedproxy.google.com/~r/JadEngineBlog/~3/dPKIJiGRvXE/desarrollando-un-juego-para-surface.aspx</link><pubDate>Thu, 15 Jan 2009 05:46:00 GMT</pubDate><guid isPermaLink="false">b86c0850-82e5-42ed-a9d8-bde9e8f94ec1:36371</guid><dc:creator>Vicente</dc:creator><slash:comments>2</slash:comments><wfw:commentRss>http://kartones.net/blogs/jadengine/rsscomments.aspx?PostID=36371</wfw:commentRss><comments>http://kartones.net/blogs/jadengine/archive/2009/01/15/desarrollando-un-juego-para-surface.aspx#comments</comments><description>&lt;p&gt;Este finde antes de irme de viaje he podido participar en otro “12 Meses 12 Proyectos”. 12m12p es una idea que se nos ocurrió a un grupo de amigos de Madrid de juntarnos de vez en cuando e intentar hacer un juego completo en un fin de semana. Normalmente no terminamos nada, pero nos lo pasamos muy bien :)&lt;/p&gt;  &lt;p&gt;Esta vez se decidió hacer un juego de &lt;a href="http://en.wikipedia.org/wiki/Air_hockey"&gt;Air Hockey&lt;/a&gt; para &lt;a href="http://www.microsoft.com/SURFACE/index.html"&gt;Surface&lt;/a&gt;, ya que teníamos acceso a los SDKs de la mesita (aunque no teníamos una para probar, una lástima). Y sorprendentemente, conseguimos terminarlo y dejarlo bastante pulido :)&lt;/p&gt;  &lt;p&gt;En este 12m12p participamos Luis, Riqui, Antón, Pedro, Olmo y un servidor y en el blog de &lt;a href="http://www.luisguerrero.net/post/2009/01/12/Primera-aplicacion-de-Microsoft-Surface.aspx"&gt;Luis&lt;/a&gt; podéis encontrar varias imágenes y un vídeo de ejemplo. El juego está desarrollado en C#+WPF y nos agenciamos un &lt;a href="http://www.hp.com/united-states/campaigns/touchsmart/"&gt;HP TouchSmart&lt;/a&gt; para hacer las pruebas, pero a pesar de que soporta multitouch no reconoce cada toque como un ratón diferente así que acabamos poniendo varios ratones a un portatil normal para jugar.&lt;/p&gt;  &lt;p&gt;La verdad que voy a echar bastante de menos 12m12p estos meses que voy a estar fuera, ya que son una oportunidad muy buena para vivir un proyecto (aunque sea pequeño) de principio a fin, donde lo que importa es terminar como sea la aplicación (si la gente viera algunas partes del código iban a llorar :p).&lt;br /&gt;&lt;/p&gt;&lt;img src="http://kartones.net/aggbug.aspx?PostID=36371" width="1" height="1"&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/zJUaMdk7W9tIgwffuH4TZ1NP6dM/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/zJUaMdk7W9tIgwffuH4TZ1NP6dM/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/zJUaMdk7W9tIgwffuH4TZ1NP6dM/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/zJUaMdk7W9tIgwffuH4TZ1NP6dM/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/JadEngineBlog/~4/dPKIJiGRvXE" height="1" width="1"/&gt;</description><category domain="http://kartones.net/blogs/jadengine/archive/tags/Personal/default.aspx">Personal</category><category domain="http://kartones.net/blogs/jadengine/archive/tags/Videojuegos/default.aspx">Videojuegos</category><feedburner:origLink>http://kartones.net/blogs/jadengine/archive/2009/01/15/desarrollando-un-juego-para-surface.aspx</feedburner:origLink></item><item><title>DevCamp 08 – ¡Ira XNA!</title><link>http://feedproxy.google.com/~r/JadEngineBlog/~3/fz4I1UcM9Go/devcamp-08-161-ira-xna.aspx</link><pubDate>Sat, 15 Nov 2008 15:50:54 GMT</pubDate><guid isPermaLink="false">b86c0850-82e5-42ed-a9d8-bde9e8f94ec1:27627</guid><dc:creator>Vicente</dc:creator><slash:comments>2</slash:comments><wfw:commentRss>http://kartones.net/blogs/jadengine/rsscomments.aspx?PostID=27627</wfw:commentRss><comments>http://kartones.net/blogs/jadengine/archive/2008/11/15/devcamp-08-161-ira-xna.aspx#comments</comments><description>&lt;p&gt;Con esta frase terminé mi conferencia de XNA en la DevCamp 08 de Microsoft, para quien no conozca a que película hicimos un guiño entre Pedro, Riqui y yo que vea este &lt;a href="http://es.youtube.com/watch?v=7kGvL_SILe4" target="_blank"&gt;link&lt;/a&gt; :) La verdad que como siempre la organización del evento fue de 10, 90 frikis en el Trip de Guadalajara a cuerpo de rey.&lt;/p&gt;  &lt;p&gt;Y sin enrollarme mucho más, aquí dejo las transparencias de mi presentación, por si alguien les quiere dar un vistazo.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://kartones.net/files/folders/directxxna/entry27503.aspx" target="_blank"&gt;XNA – Cómo facilitar el desarrollo de videojuegos&lt;/a&gt;&lt;/p&gt;&lt;img src="http://kartones.net/aggbug.aspx?PostID=27627" width="1" height="1"&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/ymTx87ieF50eFYtv6NtI5BYe7Ow/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/ymTx87ieF50eFYtv6NtI5BYe7Ow/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/ymTx87ieF50eFYtv6NtI5BYe7Ow/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/ymTx87ieF50eFYtv6NtI5BYe7Ow/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/JadEngineBlog/~4/fz4I1UcM9Go" height="1" width="1"/&gt;</description><category domain="http://kartones.net/blogs/jadengine/archive/tags/Personal/default.aspx">Personal</category><category domain="http://kartones.net/blogs/jadengine/archive/tags/XNA/default.aspx">XNA</category><feedburner:origLink>http://kartones.net/blogs/jadengine/archive/2008/11/15/devcamp-08-161-ira-xna.aspx</feedburner:origLink></item><item><title>Meme de desarrollo de software</title><link>http://feedproxy.google.com/~r/JadEngineBlog/~3/zGFK3249cE0/meme-de-desarrollo-de-software.aspx</link><pubDate>Mon, 21 Jul 2008 22:19:57 GMT</pubDate><guid isPermaLink="false">b86c0850-82e5-42ed-a9d8-bde9e8f94ec1:14159</guid><dc:creator>Vicente</dc:creator><slash:comments>2</slash:comments><wfw:commentRss>http://kartones.net/blogs/jadengine/rsscomments.aspx?PostID=14159</wfw:commentRss><comments>http://kartones.net/blogs/jadengine/archive/2008/07/22/meme-de-desarrollo-de-software.aspx#comments</comments><description>&lt;p&gt;Hace unas semanas &lt;a href="http://blep.blogspot.com/"&gt;ethernet&lt;/a&gt; public&amp;#243; este &lt;a href="http://blep.blogspot.com/2008/07/meme-de-desarrollo-de-software.html"&gt;meme&lt;/a&gt; en su blog y me puso en la lista, as&amp;#237; que aqu&amp;#237; van las respuestas :)&lt;/p&gt;  &lt;h5&gt;Cu&amp;#225;ntos a&amp;#241;os ten&amp;#237;as cuando empezate a programar&lt;/h5&gt;  &lt;p&gt;Unos 14-15 a&amp;#241;os.&lt;/p&gt;  &lt;h5&gt;C&amp;#243;mo empezaste a programar&lt;/h5&gt;  &lt;p&gt;Como me pasaba todo el d&amp;#237;a pegado al PC de un amigo (un 386) mis padres me apuntaron a una academia de inform&amp;#225;tica donde me &lt;strike&gt;ense&amp;#241;aron&lt;/strike&gt; hicieron copiar programas de Basic. Como no aprend&amp;#237;a nada de nada me cambiaron a otra donde s&amp;#237; que aprend&amp;#237; Basic y un poco de C (y Wordperfect O_o).&lt;/p&gt;  &lt;h5&gt; Cual fue el primer lenguaje que usaste&lt;/h5&gt;  &lt;p&gt;Basic y unos meses despu&amp;#233;s C. Y el &amp;#250;ltimo a&amp;#241;o de bachillerato mucho Div Games Studio :)&lt;/p&gt;  &lt;h5&gt;Cual fue el primer programa real que programaste&lt;/h5&gt;  &lt;p&gt;Un curso de aprender C en C :p (mi proyecto de fin de academia). Luego matamarcianos y cosas as&amp;#237; con Div.&lt;/p&gt;  &lt;h5&gt;Cual fue tu primera experiencia profesional&lt;/h5&gt;  &lt;p&gt;Pues fue bastante tard&amp;#237;a la verdad: las pr&amp;#225;cticas de empresa en HP. Hice algunas cosas antes con la Fundaci&amp;#243;n de Ayuda contra la Drogadicci&amp;#243;n y Juvenalia pero tuvieron muy poco de programaci&amp;#243;n.&lt;/p&gt;  &lt;h5&gt;Si t&amp;#250; hubieras sabido lo que sabes ahora cuando empezaste a programar, &amp;#191;hubieras empezado a hacerlo?&lt;/h5&gt;  &lt;p&gt;S&amp;#237;. Me encanta desarrollar software, me parece un reto muy entretenido y la verdad que no me arrepiento de la ruta que tome para mi vida en este aspecto.&lt;/p&gt;  &lt;h5&gt;Si tuvieras que decir una sola cosa de las que has aprendido a lo largo de los a&amp;#241;os a un nuevo programador, qu&amp;#233; le dir&amp;#237;as&lt;/h5&gt;  &lt;p&gt;No reinventes la rueda por favoooooor.&lt;/p&gt;  &lt;h5&gt;Qu&amp;#233; es lo m&amp;#225;s divertido que has programado?&lt;/h5&gt;  &lt;p&gt;La librer&amp;#237;a de IA de Jad Engine. En particular la parte de algoritmos gen&amp;#233;ticos a la que di muchas vueltas y que creo que ha quedado bastante bien (aunque su utilidad para juegos sea muy discutible :p).&lt;/p&gt;  &lt;h5&gt;A qui&amp;#233;n le pasas el meme&lt;/h5&gt;  &lt;p&gt;A todos los dem&amp;#225;s coders que hay en Kartones.net (en particular a Kartones, flipper y Pedrito que les conozco m&amp;#225;s, pero vamos, va para todos ;)).   &lt;/p&gt;&lt;img src="http://kartones.net/aggbug.aspx?PostID=14159" width="1" height="1"&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/b3N0SZkp_TI_GzZtyOP2ivpabeo/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/b3N0SZkp_TI_GzZtyOP2ivpabeo/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/b3N0SZkp_TI_GzZtyOP2ivpabeo/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/b3N0SZkp_TI_GzZtyOP2ivpabeo/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/JadEngineBlog/~4/zGFK3249cE0" height="1" width="1"/&gt;</description><category domain="http://kartones.net/blogs/jadengine/archive/tags/Personal/default.aspx">Personal</category><feedburner:origLink>http://kartones.net/blogs/jadengine/archive/2008/07/22/meme-de-desarrollo-de-software.aspx</feedburner:origLink></item><item><title>Migrando a VS 2008</title><link>http://feedproxy.google.com/~r/JadEngineBlog/~3/cxevpkHqYuk/migrando-a-vs-2008.aspx</link><pubDate>Sun, 13 Jul 2008 10:54:00 GMT</pubDate><guid isPermaLink="false">b86c0850-82e5-42ed-a9d8-bde9e8f94ec1:13555</guid><dc:creator>Vicente</dc:creator><slash:comments>0</slash:comments><wfw:commentRss>http://kartones.net/blogs/jadengine/rsscomments.aspx?PostID=13555</wfw:commentRss><comments>http://kartones.net/blogs/jadengine/archive/2008/07/13/migrando-a-vs-2008.aspx#comments</comments><description>&lt;p&gt;Hace un par de semanas por fin migramos Jade y Pluto de VS2005 a VS2008. Llevábamos bastante tiempo queriendo hacerlo pero muchas de las características del Framework 3.5 aún no estaban soportadas en Mono así que no nos decidíamos. Pero coincidiendo con el movimiento de &lt;a href="http://www.codeplex.com"&gt;Codeplex&lt;/a&gt; a &lt;a href="http://www.assembla.com"&gt;Assembla&lt;/a&gt;&amp;nbsp; y viendo que &lt;a href="http://www.mono-project.com/Mono_Project_Roadmap"&gt;Mono 1.9&lt;/a&gt; ya sí que soporta casi todo lo nuevo (excepto LINQ to SQL que no creo que usemos en la vida) decidimos migrar las soluciones a VS2008.&lt;/p&gt;  &lt;p&gt;El migrarnos a 2008 tiene varias ventajas:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;El VS2008 funciona mucho mejor en Windows Vista que el VS2005.&lt;/li&gt;    &lt;li&gt;Podemos aprovechar las nuevas características del lenguaje (propiedades automáticas, métodos extensionales, expresiones lambda, LINQ to Objects,...) y las nuevas clases que se han añadido al Framework (&lt;a href="http://msdn.microsoft.com/en-us/library/bb359438.aspx"&gt;HashSet&lt;/a&gt;,...).&lt;/li&gt;    &lt;li&gt;Con el SP1 tendremos un nuevo compilador que optimiza mejor los tipos por valor.&lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;Las dos primeras ventajas son interesantes pero no son de vida o muerte. En cambio la tercera si que se merece unas líneas extra. Actualmente el compilador del Framework es incapaz de optimizar funciones que tengan en su firma un tipo por valor. Por ejemplo, si Vector3 es una estructura, no se podría optimizar esta función:&lt;/p&gt;  &lt;div style="border:1px solid gray;margin:20px 0px 10px;padding:4px;overflow:auto;font-size:8pt;width:97.5%;cursor:text;max-height:200px;line-height:12pt;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;"&gt;   &lt;div style="border-style:none;padding:0px;overflow:visible;font-size:8pt;width:100%;color:black;line-height:12pt;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;"&gt;     &lt;pre style="border-style:none;margin:0em;padding:0px;overflow:visible;font-size:8pt;width:100%;color:black;line-height:12pt;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;background-color:white;"&gt;&lt;span&gt;   1:&lt;/span&gt; &lt;span&gt;public&lt;/span&gt; &lt;span&gt;static&lt;/span&gt; Vector3 &lt;span&gt;operator&lt;/span&gt; +(Vector3 left, Vector3 right)&lt;/pre&gt;

    &lt;pre style="border-style:none;margin:0em;padding:0px;overflow:visible;font-size:8pt;width:100%;color:black;line-height:12pt;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;"&gt;&lt;span&gt;   2:&lt;/span&gt; {&lt;/pre&gt;

    &lt;pre style="border-style:none;margin:0em;padding:0px;overflow:visible;font-size:8pt;width:100%;color:black;line-height:12pt;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;background-color:white;"&gt;&lt;span&gt;   3:&lt;/span&gt;     &lt;span&gt;return&lt;/span&gt; &lt;span&gt;new&lt;/span&gt; Vector3(left.X + right.X, left.Y + right.Y, left.Z + right.Z);&lt;/pre&gt;

    &lt;pre style="border-style:none;margin:0em;padding:0px;overflow:visible;font-size:8pt;width:100%;color:black;line-height:12pt;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;"&gt;&lt;span&gt;   4:&lt;/span&gt; }&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;No poder optimizar significa:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;No se puede hacer un &lt;a href="http://en.wikipedia.org/wiki/Inline_expansion"&gt;inline&lt;/a&gt; de la función.&lt;/li&gt;

  &lt;li&gt;Como hay que realizar la llamada, y los tipos son por valor, hay que copiarlos.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Esto es lentísimo y la función sumar vectores (o cualquier otra operación matemática) es imprescindible para un motor 3D. Hasta ahora para solucionar este problema había que hacerse una función como esta (en &lt;a href="http://creators.xna.com/"&gt;XNA&lt;/a&gt; existe este mismo problema y se utiliza esta misma solución):&lt;/p&gt;

&lt;div style="border:1px solid gray;margin:20px 0px 10px;padding:4px;overflow:auto;font-size:8pt;width:97.5%;cursor:text;max-height:200px;line-height:12pt;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;"&gt;
  &lt;div style="border-style:none;padding:0px;overflow:visible;font-size:8pt;width:100%;color:black;line-height:12pt;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;"&gt;
    &lt;pre style="border-style:none;margin:0em;padding:0px;overflow:visible;font-size:8pt;width:100%;color:black;line-height:12pt;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;background-color:white;"&gt;&lt;span&gt;   1:&lt;/span&gt; &lt;span&gt;public&lt;/span&gt; &lt;span&gt;static&lt;/span&gt; &lt;span&gt;void&lt;/span&gt; Add(&lt;span&gt;ref&lt;/span&gt; Vector3 value1, &lt;span&gt;ref&lt;/span&gt; Vector3 value2, &lt;span&gt;out&lt;/span&gt; Vector3 &lt;span&gt;value&lt;/span&gt;)&lt;/pre&gt;

    &lt;pre style="border-style:none;margin:0em;padding:0px;overflow:visible;font-size:8pt;width:100%;color:black;line-height:12pt;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;"&gt;&lt;span&gt;   2:&lt;/span&gt; {&lt;/pre&gt;

    &lt;pre style="border-style:none;margin:0em;padding:0px;overflow:visible;font-size:8pt;width:100%;color:black;line-height:12pt;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;background-color:white;"&gt;&lt;span&gt;   3:&lt;/span&gt;     &lt;span&gt;value&lt;/span&gt;.X = value1.X + value2.X;&lt;/pre&gt;

    &lt;pre style="border-style:none;margin:0em;padding:0px;overflow:visible;font-size:8pt;width:100%;color:black;line-height:12pt;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;"&gt;&lt;span&gt;   4:&lt;/span&gt;     &lt;span&gt;value&lt;/span&gt;.Y = value1.Y + value2.Y;&lt;/pre&gt;

    &lt;pre style="border-style:none;margin:0em;padding:0px;overflow:visible;font-size:8pt;width:100%;color:black;line-height:12pt;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;background-color:white;"&gt;&lt;span&gt;   5:&lt;/span&gt;     &lt;span&gt;value&lt;/span&gt;.Z = value1.Z + value2.Z;&lt;/pre&gt;

    &lt;pre style="border-style:none;margin:0em;padding:0px;overflow:visible;font-size:8pt;width:100%;color:black;line-height:12pt;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;"&gt;&lt;span&gt;   6:&lt;/span&gt; }&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;Donde los valores y el resultado van todos por referencia, con lo cual hay que pagar el coste de llamar a la función pero al menos no hay que copiar las estructuras. Pero el problema de funciones de este estilo es que escribir código matemático es horrendo. Por ejemplo:&lt;/p&gt;

&lt;div style="border:1px solid gray;margin:20px 0px 10px;padding:4px;overflow:auto;font-size:8pt;width:97.5%;cursor:text;max-height:200px;line-height:12pt;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;"&gt;
  &lt;div style="border-style:none;padding:0px;overflow:visible;font-size:8pt;width:100%;color:black;line-height:12pt;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;"&gt;
    &lt;pre style="border-style:none;margin:0em;padding:0px;overflow:visible;font-size:8pt;width:100%;color:black;line-height:12pt;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;background-color:white;"&gt;&lt;span&gt;   1:&lt;/span&gt; &lt;span&gt;public&lt;/span&gt; &lt;span&gt;override&lt;/span&gt; Vector3 Calculate()&lt;/pre&gt;

    &lt;pre style="border-style:none;margin:0em;padding:0px;overflow:visible;font-size:8pt;width:100%;color:black;line-height:12pt;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;"&gt;&lt;span&gt;   2:&lt;/span&gt; {&lt;/pre&gt;

    &lt;pre style="border-style:none;margin:0em;padding:0px;overflow:visible;font-size:8pt;width:100%;color:black;line-height:12pt;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;background-color:white;"&gt;&lt;span&gt;   3:&lt;/span&gt;     Vector3 result = Vector3.Zero;&lt;/pre&gt;

    &lt;pre style="border-style:none;margin:0em;padding:0px;overflow:visible;font-size:8pt;width:100%;color:black;line-height:12pt;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;"&gt;&lt;span&gt;   4:&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;

    &lt;pre style="border-style:none;margin:0em;padding:0px;overflow:visible;font-size:8pt;width:100%;color:black;line-height:12pt;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;background-color:white;"&gt;&lt;span&gt;   5:&lt;/span&gt;     &lt;span&gt;foreach&lt;/span&gt; (IMovableEntity target &lt;span&gt;in&lt;/span&gt; _targets)&lt;/pre&gt;

    &lt;pre style="border-style:none;margin:0em;padding:0px;overflow:visible;font-size:8pt;width:100%;color:black;line-height:12pt;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;"&gt;&lt;span&gt;   6:&lt;/span&gt;     {&lt;/pre&gt;

    &lt;pre style="border-style:none;margin:0em;padding:0px;overflow:visible;font-size:8pt;width:100%;color:black;line-height:12pt;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;background-color:white;"&gt;&lt;span&gt;   7:&lt;/span&gt;         Vector3 targetPos = target.Position;&lt;/pre&gt;

    &lt;pre style="border-style:none;margin:0em;padding:0px;overflow:visible;font-size:8pt;width:100%;color:black;line-height:12pt;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;"&gt;&lt;span&gt;   8:&lt;/span&gt;         Vector3 ownPos = Owner.Position;&lt;/pre&gt;

    &lt;pre style="border-style:none;margin:0em;padding:0px;overflow:visible;font-size:8pt;width:100%;color:black;line-height:12pt;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;background-color:white;"&gt;&lt;span&gt;   9:&lt;/span&gt;         Vector3 direction = Vector3.Subtract(&lt;span&gt;ref&lt;/span&gt; ownPos, &lt;span&gt;ref&lt;/span&gt; targetPos);&lt;/pre&gt;

    &lt;pre style="border-style:none;margin:0em;padding:0px;overflow:visible;font-size:8pt;width:100%;color:black;line-height:12pt;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;"&gt;&lt;span&gt;  10:&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;

    &lt;pre style="border-style:none;margin:0em;padding:0px;overflow:visible;font-size:8pt;width:100%;color:black;line-height:12pt;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;background-color:white;"&gt;&lt;span&gt;  11:&lt;/span&gt;         Vector3 desiredSpeed = Vector3.Multiply(&lt;span&gt;ref&lt;/span&gt; direction, Owner.MaximumSpeed);&lt;/pre&gt;

    &lt;pre style="border-style:none;margin:0em;padding:0px;overflow:visible;font-size:8pt;width:100%;color:black;line-height:12pt;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;"&gt;&lt;span&gt;  12:&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;

    &lt;pre style="border-style:none;margin:0em;padding:0px;overflow:visible;font-size:8pt;width:100%;color:black;line-height:12pt;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;background-color:white;"&gt;&lt;span&gt;  13:&lt;/span&gt;         Vector3 ownVel = Owner.Velocity;&lt;/pre&gt;

    &lt;pre style="border-style:none;margin:0em;padding:0px;overflow:visible;font-size:8pt;width:100%;color:black;line-height:12pt;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;"&gt;&lt;span&gt;  14:&lt;/span&gt;         Vector3 difference = Vector3.Subtract(&lt;span&gt;ref&lt;/span&gt; desiredSpeed, &lt;span&gt;ref&lt;/span&gt; ownVel);&lt;/pre&gt;

    &lt;pre style="border-style:none;margin:0em;padding:0px;overflow:visible;font-size:8pt;width:100%;color:black;line-height:12pt;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;background-color:white;"&gt;&lt;span&gt;  15:&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;

    &lt;pre style="border-style:none;margin:0em;padding:0px;overflow:visible;font-size:8pt;width:100%;color:black;line-height:12pt;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;"&gt;&lt;span&gt;  16:&lt;/span&gt;         result = Vector3.Add(&lt;span&gt;ref&lt;/span&gt; result, &lt;span&gt;ref&lt;/span&gt; difference);&lt;/pre&gt;

    &lt;pre style="border-style:none;margin:0em;padding:0px;overflow:visible;font-size:8pt;width:100%;color:black;line-height:12pt;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;background-color:white;"&gt;&lt;span&gt;  17:&lt;/span&gt;     }&lt;/pre&gt;

    &lt;pre style="border-style:none;margin:0em;padding:0px;overflow:visible;font-size:8pt;width:100%;color:black;line-height:12pt;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;"&gt;&lt;span&gt;  18:&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;

    &lt;pre style="border-style:none;margin:0em;padding:0px;overflow:visible;font-size:8pt;width:100%;color:black;line-height:12pt;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;background-color:white;"&gt;&lt;span&gt;  19:&lt;/span&gt;     &lt;span&gt;return&lt;/span&gt; result;&lt;/pre&gt;

    &lt;pre style="border-style:none;margin:0em;padding:0px;overflow:visible;font-size:8pt;width:100%;color:black;line-height:12pt;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;"&gt;&lt;span&gt;  20:&lt;/span&gt; }&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;Ese código deberían ser 4 operaciones encadenadas, pero como no podemos usar los operadores +,-,*,... hace falta utilizar un montón de valores temporales (y además es feo de leer de narices).&lt;/p&gt;

&lt;p&gt;Hace poco Reed hizo benchmarks con el nuevo compilador del Framework 3.5 SP1 Beta usando los operadores y las llamadas se optimizan correctamente, con lo que ahora usar +,-,... es más rápido (porque se hace el inline) y además el código es mucho más cómodo de leer. Así que ahora iremos cambiando el código de Jade para que utilice los operadores matemáticos.&lt;/p&gt;&lt;img src="http://kartones.net/aggbug.aspx?PostID=13555" width="1" height="1"&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/m3fEmXhFOQXlJmEvYulHOL9-BGA/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/m3fEmXhFOQXlJmEvYulHOL9-BGA/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/m3fEmXhFOQXlJmEvYulHOL9-BGA/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/m3fEmXhFOQXlJmEvYulHOL9-BGA/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/JadEngineBlog/~4/cxevpkHqYuk" height="1" width="1"/&gt;</description><category domain="http://kartones.net/blogs/jadengine/archive/tags/Jad+Engine/default.aspx">Jad Engine</category><category domain="http://kartones.net/blogs/jadengine/archive/tags/Pluto/default.aspx">Pluto</category><feedburner:origLink>http://kartones.net/blogs/jadengine/archive/2008/07/13/migrando-a-vs-2008.aspx</feedburner:origLink></item></channel></rss>
