<?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:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:copyright="http://blogs.law.harvard.edu/tech/rss" xmlns:image="http://purl.org/rss/1.0/modules/image/" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">
    <channel>
        <title>Console.Write(this.Opinion)</title>
        <link>http://eduardomiranda.net/blogs/dotnet/Default.aspx</link>
        <description>arquitetura e desenvolvimento de software</description>
        <language>pt-BR</language>
        <copyright>Eduardo Miranda</copyright>
        <managingEditor>this@eduardomiranda.net</managingEditor>
        <generator>Subtext Version 1.9.5.176</generator>
        <image>
            <title>Console.Write(this.Opinion)</title>
            <url>http://eduardomiranda.net/blogs/images/RSS2Image.gif</url>
            <link>http://eduardomiranda.net/blogs/dotnet/Default.aspx</link>
            <width>77</width>
            <height>60</height>
        </image>
        <atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" href="http://feeds.feedburner.com/EduardoMirandaDotNet" type="application/rss+xml" /><feedburner:emailServiceId>EduardoMirandaDotNet</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>Teched 2009 – “Construindo uma aplicação com silverlight 3”</title>
            <category>Notícias</category>
            <link>http://feedproxy.google.com/~r/EduardoMirandaDotNet/~3/TZxFpr56wik/teched-2009-construindo-uma-aplicacacao-com-silverlight-3.aspx</link>
            <description>&lt;p&gt;Uma das minhas partipações no Teched deste ano foi uma pequena participação na palestra do colega de time, &lt;a target="_blank" href="http://blogs.msdn.com/cguimar/"&gt;Cezar Guimarães&lt;/a&gt;: “Construindo uma aplicação com silverlight 3”. Espero que os ouvintes tenham gostado.&lt;/p&gt;
&lt;p&gt;Minha tarefa, além de aprender alguma coisa de silverlight, era mostrar algumas ferramentas que possibilitam desenvolvedores automatizarem seus testes para silverlight.&lt;/p&gt;
&lt;p&gt;Apresentei o &lt;a target="_blank" href="http://code.msdn.microsoft.com/silverlightut"&gt;Silverlight Unit Test Framework&lt;/a&gt;, criado por &lt;a target="_blank" href="http://www.jeff.wilcox.name"&gt;Jeff Cox&lt;/a&gt; e utilizado pelo time do &lt;a target="_blank" href="http://silverlight.codeplex.com/"&gt;Silverlight Toolkit&lt;/a&gt;, para automatizar seus testes.&lt;/p&gt;
&lt;p&gt;Como referência sugiro o blog do &lt;a target="_blank" href="http://www.jeff.wilcox.name"&gt;Jeff Cox&lt;/a&gt; e o projeto &lt;a target="_blank" href="http://silverlight.codeplex.com/"&gt;Silverlight Toolkit&lt;/a&gt; no codeplex. Neste projeto você encontrará o código-fonte do framework e de &lt;strong&gt;todos &lt;/strong&gt;os testes unitários escritos pelo time utilizando o framework.&lt;/p&gt;
&lt;p&gt;Caso seja necessário utilizar &lt;em&gt;Mocks &lt;/em&gt;ou &lt;em&gt;Stubs &lt;/em&gt;no seu teste, já existe uma versão compilada para Silverlight do &lt;a target="_blank" href="http://code.google.com/p/moq/"&gt;Moq&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;O código desenvolvido e apresentado na palestra encontra-se no blog o Cezar: &lt;a href="http://blogs.msdn.com/cguimar/archive/2009/08/30/teched-2009-c-digo-fonte-de-construindo-uma-aplica-o-com-silverlight-3.aspx"&gt;teched 2009 – código fonte de “construindo uma aplicação com silverlight 3”&lt;/a&gt;.&lt;/p&gt;&lt;img src="http://eduardomiranda.net/blogs/dotnet/aggbug/264.aspx" width="1" height="1" /&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/EduardoMirandaDotNet?a=TZxFpr56wik:7xfFlpxj_Hc:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/EduardoMirandaDotNet?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/EduardoMirandaDotNet?a=TZxFpr56wik:7xfFlpxj_Hc:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/EduardoMirandaDotNet?i=TZxFpr56wik:7xfFlpxj_Hc:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/EduardoMirandaDotNet?a=TZxFpr56wik:7xfFlpxj_Hc:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/EduardoMirandaDotNet?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/EduardoMirandaDotNet?a=TZxFpr56wik:7xfFlpxj_Hc:bcOpcFrp8Mo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/EduardoMirandaDotNet?d=bcOpcFrp8Mo" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/EduardoMirandaDotNet/~4/TZxFpr56wik" height="1" width="1"/&gt;</description>
            <dc:creator>Eduardo Miranda</dc:creator>
            <guid isPermaLink="false">http://eduardomiranda.net/blogs/dotnet/archive/2009/08/31/teched-2009-construindo-uma-aplicacacao-com-silverlight-3.aspx</guid>
            <pubDate>Mon, 31 Aug 2009 19:30:15 GMT</pubDate>
            <wfw:comment>http://eduardomiranda.net/blogs/dotnet/comments/264.aspx</wfw:comment>
            <comments>http://eduardomiranda.net/blogs/dotnet/archive/2009/08/31/teched-2009-construindo-uma-aplicacacao-com-silverlight-3.aspx#feedback</comments>
            <wfw:commentRss>http://eduardomiranda.net/blogs/dotnet/comments/commentRss/264.aspx</wfw:commentRss>
        <feedburner:origLink>http://eduardomiranda.net/blogs/dotnet/archive/2009/08/31/teched-2009-construindo-uma-aplicacacao-com-silverlight-3.aspx</feedburner:origLink></item>
        <item>
            <title>Princípio da inversão de dependência</title>
            <category>Design de software</category>
            <link>http://feedproxy.google.com/~r/EduardoMirandaDotNet/~3/VzNc_2FQtL8/principio-da-inversao-de-dependencia.aspx</link>
            <description>&lt;p&gt;Nesta sexta-feira os estagiários do nosso time fizeram apresentações sobre os princípios SOLID para o time. O &lt;strong&gt;D&lt;/strong&gt; acabou “sobrando” para mim, pois são apenas quatro estagiários. Eu fiz uma apresentação bem simples, quase simplista. Mas como o material já estava pronto, decidi colocar aqui no blog.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Disclaimer&lt;/em&gt;&lt;/strong&gt;: Este código é um simples exemplo cuja única motivação é apresentar o princípio em questão. Tentar utilizá-lo pode causar dor de cabeça, impotência sexual e outras complicações. &lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Dependency Inversion Principle&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Vamos considerar um exemplo simples de aplicação que copia mensagens do console e as escreve novamente no console.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://eduardomiranda.net/blogs/images/eduardomiranda_net/blogs/dotnet/WindowsLiveWriter/Princpiodainversodedependncia_A52A/1_2.png"&gt;&lt;img style="BORDER-RIGHT-WIDTH: 0px; DISPLAY: block; FLOAT: none; BORDER-TOP-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; MARGIN-LEFT: auto; BORDER-LEFT-WIDTH: 0px; MARGIN-RIGHT: auto" title="1" border="0" alt="1" width="398" height="276" src="http://eduardomiranda.net/blogs/images/eduardomiranda_net/blogs/dotnet/WindowsLiveWriter/Princpiodainversodedependncia_A52A/1_thumb.png" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;No dia seguinte é necessário adicionar uma nova funcionalidade, a opção de copiar para o Clipboard ao invés do Console. Posso utilizar uma enumeração como um discriminador do output desejado.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://eduardomiranda.net/blogs/images/eduardomiranda_net/blogs/dotnet/WindowsLiveWriter/Princpiodainversodedependncia_A52A/2_2.png"&gt;&lt;img style="BORDER-RIGHT-WIDTH: 0px; DISPLAY: block; FLOAT: none; BORDER-TOP-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; MARGIN-LEFT: auto; BORDER-LEFT-WIDTH: 0px; MARGIN-RIGHT: auto" title="2" border="0" alt="2" width="554" height="303" src="http://eduardomiranda.net/blogs/images/eduardomiranda_net/blogs/dotnet/WindowsLiveWriter/Princpiodainversodedependncia_A52A/2_thumb.png" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;Para isto preciso alterar a função que implementa minhas regras de negócio (vamos fingir que existe algum &lt;strong&gt;&lt;em&gt;valor&lt;/em&gt;&lt;/strong&gt; em copiar mensagens). O motivo é que minha classe, que está em nível de abstração mais alto depende diretamente de uma classe de um nível mais baixo de abstração.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://eduardomiranda.net/blogs/images/eduardomiranda_net/blogs/dotnet/WindowsLiveWriter/Princpiodainversodedependncia_A52A/3_2.png"&gt;&lt;img style="BORDER-RIGHT-WIDTH: 0px; DISPLAY: block; FLOAT: none; BORDER-TOP-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; MARGIN-LEFT: auto; BORDER-LEFT-WIDTH: 0px; MARGIN-RIGHT: auto" title="3" border="0" alt="3" width="423" height="255" src="http://eduardomiranda.net/blogs/images/eduardomiranda_net/blogs/dotnet/WindowsLiveWriter/Princpiodainversodedependncia_A52A/3_thumb.png" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;O “Dependency inversion principle” nos diz que:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://eduardomiranda.net/blogs/images/eduardomiranda_net/blogs/dotnet/WindowsLiveWriter/Princpiodainversodedependncia_A52A/4_2.png"&gt;&lt;img style="BORDER-RIGHT-WIDTH: 0px; DISPLAY: block; FLOAT: none; BORDER-TOP-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; MARGIN-LEFT: auto; BORDER-LEFT-WIDTH: 0px; MARGIN-RIGHT: auto" title="4" border="0" alt="4" width="500" height="190" src="http://eduardomiranda.net/blogs/images/eduardomiranda_net/blogs/dotnet/WindowsLiveWriter/Princpiodainversodedependncia_A52A/4_thumb.png" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;Ou seja, módulos de alto nível não devem depender de módulo de baixo nível, mas sim de abstrações, algo como:&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;&lt;a href="http://eduardomiranda.net/blogs/images/eduardomiranda_net/blogs/dotnet/WindowsLiveWriter/Princpiodainversodedependncia_A52A/5_2.png"&gt;&lt;img style="BORDER-RIGHT-WIDTH: 0px; DISPLAY: block; FLOAT: none; BORDER-TOP-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; MARGIN-LEFT: auto; BORDER-LEFT-WIDTH: 0px; MARGIN-RIGHT: auto" title="5" border="0" alt="5" width="423" height="255" src="http://eduardomiranda.net/blogs/images/eduardomiranda_net/blogs/dotnet/WindowsLiveWriter/Princpiodainversodedependncia_A52A/5_thumb.png" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;Então para aplicar o princípio em meu exemplo, seria necessário abstrair as atividades de mais baixo nível.&lt;/p&gt;
&lt;p&gt;Abstraindo a atividade de escrever a mensagem&lt;/p&gt;
&lt;p&gt;Utilizando uma interface abstraio a função de escrever a mensagem. Meu módulo de alto nível não sabe mais como imprimir a mensagem no console, conhece apenas a abstração.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://eduardomiranda.net/blogs/images/eduardomiranda_net/blogs/dotnet/WindowsLiveWriter/Princpiodainversodedependncia_A52A/6_2.png"&gt;&lt;img style="BORDER-RIGHT-WIDTH: 0px; DISPLAY: block; FLOAT: none; BORDER-TOP-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; MARGIN-LEFT: auto; BORDER-LEFT-WIDTH: 0px; MARGIN-RIGHT: auto" title="6" border="0" alt="6" width="392" height="405" src="http://eduardomiranda.net/blogs/images/eduardomiranda_net/blogs/dotnet/WindowsLiveWriter/Princpiodainversodedependncia_A52A/6_thumb.png" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Para atender os requisitos, implemento dois writers concretos:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://eduardomiranda.net/blogs/images/eduardomiranda_net/blogs/dotnet/WindowsLiveWriter/Princpiodainversodedependncia_A52A/7_2.png"&gt;&lt;img style="BORDER-RIGHT-WIDTH: 0px; DISPLAY: block; FLOAT: none; BORDER-TOP-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; MARGIN-LEFT: auto; BORDER-LEFT-WIDTH: 0px; MARGIN-RIGHT: auto" title="7" border="0" alt="7" width="514" height="320" src="http://eduardomiranda.net/blogs/images/eduardomiranda_net/blogs/dotnet/WindowsLiveWriter/Princpiodainversodedependncia_A52A/7_thumb.png" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;Agora abstraio a função de ler, que também está ligada a módulos de níveis mais baixos.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://eduardomiranda.net/blogs/images/eduardomiranda_net/blogs/dotnet/WindowsLiveWriter/Princpiodainversodedependncia_A52A/8_2.png"&gt;&lt;img style="BORDER-RIGHT-WIDTH: 0px; DISPLAY: block; FLOAT: none; BORDER-TOP-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; MARGIN-LEFT: auto; BORDER-LEFT-WIDTH: 0px; MARGIN-RIGHT: auto" title="8" border="0" alt="8" width="480" height="306" src="http://eduardomiranda.net/blogs/images/eduardomiranda_net/blogs/dotnet/WindowsLiveWriter/Princpiodainversodedependncia_A52A/8_thumb.png" /&gt;&lt;/a&gt;  &lt;/p&gt;
&lt;p&gt;O código cliente, o que utiliza a minha API, fica deste jeito:&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;&lt;a href="http://eduardomiranda.net/blogs/images/eduardomiranda_net/blogs/dotnet/WindowsLiveWriter/Princpiodainversodedependncia_A52A/9_2.png"&gt;&lt;img style="BORDER-RIGHT-WIDTH: 0px; DISPLAY: block; FLOAT: none; BORDER-TOP-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; MARGIN-LEFT: auto; BORDER-LEFT-WIDTH: 0px; MARGIN-RIGHT: auto" title="9" border="0" alt="9" width="540" height="135" src="http://eduardomiranda.net/blogs/images/eduardomiranda_net/blogs/dotnet/WindowsLiveWriter/Princpiodainversodedependncia_A52A/9_thumb.png" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;Repare que minha solução aumenta a complexidade neste código, agora o cliente precisa saber qual “escritor” e qual “leitor” utilizar. É um trade-off que você deve decidir se vale a pena, ou não.&lt;/p&gt;
&lt;p&gt;Design é tentar maximizar as escolhas e os trade-offs. Dificilmente você irá encontrar decisões sem pontos negativos. Se você não consegue encontrá-los, procure melhor, eles devem estar escondidos em algum lugar.&lt;/p&gt;&lt;img src="http://eduardomiranda.net/blogs/dotnet/aggbug/263.aspx" width="1" height="1" /&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/EduardoMirandaDotNet?a=VzNc_2FQtL8:f_PjzbDZlIE:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/EduardoMirandaDotNet?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/EduardoMirandaDotNet?a=VzNc_2FQtL8:f_PjzbDZlIE:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/EduardoMirandaDotNet?i=VzNc_2FQtL8:f_PjzbDZlIE:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/EduardoMirandaDotNet?a=VzNc_2FQtL8:f_PjzbDZlIE:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/EduardoMirandaDotNet?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/EduardoMirandaDotNet?a=VzNc_2FQtL8:f_PjzbDZlIE:bcOpcFrp8Mo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/EduardoMirandaDotNet?d=bcOpcFrp8Mo" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/EduardoMirandaDotNet/~4/VzNc_2FQtL8" height="1" width="1"/&gt;</description>
            <dc:creator>Eduardo Miranda</dc:creator>
            <guid isPermaLink="false">http://eduardomiranda.net/blogs/dotnet/archive/2009/06/22/principio-da-inversao-de-dependencia.aspx</guid>
            <pubDate>Mon, 22 Jun 2009 14:45:15 GMT</pubDate>
            <wfw:comment>http://eduardomiranda.net/blogs/dotnet/comments/263.aspx</wfw:comment>
            <comments>http://eduardomiranda.net/blogs/dotnet/archive/2009/06/22/principio-da-inversao-de-dependencia.aspx#feedback</comments>
            <wfw:commentRss>http://eduardomiranda.net/blogs/dotnet/comments/commentRss/263.aspx</wfw:commentRss>
        <feedburner:origLink>http://eduardomiranda.net/blogs/dotnet/archive/2009/06/22/principio-da-inversao-de-dependencia.aspx</feedburner:origLink></item>
        <item>
            <title>Novas vagas para o nosso time</title>
            <category>Notícias</category>
            <link>http://feedproxy.google.com/~r/EduardoMirandaDotNet/~3/svkhQxeexBg/novas-vagas-para-o-nosso-time.aspx</link>
            <description>&lt;p&gt;Veja a notícia abaixo e mande seu currículo.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Microsoft Brasil abre vagas para núcleo de desenvolvimento de software Dynamics em SP&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;A Microsoft Brasil amplia sua área de desenvolvimento local de software Dynamics, localizada em São Paulo, e contrata mais engenheiros de software. Os pré-requisitos para concorrer às vagas incluem conhecimento em linguagem de programação orientada a objetos (C#, C++, .Net, Java) e criação de códigos; graduação em Ciências da Computação, Engenharia ou Tecnologia da Informação; excelente capacidade de comunicação; e inglês fluente. A experiência no desenvolvimento de aplicações de negócios pode ser uma vantagem no processo de seleção. &lt;/p&gt;  &lt;p&gt;Os profissionais criarão novas funcionalidades das soluções de gestão empresarial e do relacionamento com o cliente, Dynamics ERP e Dynamics CRM, respectivamente. O centro de desenvolvimento de software foi inaugurado em 2006 e agora, com as novas contratações, dobrará de tamanho.  A divisão Microsoft Business Solutions, responsável pela linha de produtos Dynamics, é a que mais cresce em todo o mundo, sendo que registrou 140% de aumento no volume de negócios no último ano fiscal, encerrado em junho de 2008. &lt;/p&gt;  &lt;p&gt;Para se candidatar, os interessados devem acessar: &lt;a href="http://ms.peoplehr.com.br/"&gt;http://ms.peoplehr.com.br&lt;/a&gt;. &lt;/p&gt;&lt;img src="http://eduardomiranda.net/blogs/dotnet/aggbug/262.aspx" width="1" height="1" /&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/EduardoMirandaDotNet?a=svkhQxeexBg:CdsUC5qFKJM:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/EduardoMirandaDotNet?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/EduardoMirandaDotNet?a=svkhQxeexBg:CdsUC5qFKJM:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/EduardoMirandaDotNet?i=svkhQxeexBg:CdsUC5qFKJM:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/EduardoMirandaDotNet?a=svkhQxeexBg:CdsUC5qFKJM:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/EduardoMirandaDotNet?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/EduardoMirandaDotNet?a=svkhQxeexBg:CdsUC5qFKJM:bcOpcFrp8Mo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/EduardoMirandaDotNet?d=bcOpcFrp8Mo" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/EduardoMirandaDotNet/~4/svkhQxeexBg" height="1" width="1"/&gt;</description>
            <dc:creator>Eduardo Miranda</dc:creator>
            <guid isPermaLink="false">http://eduardomiranda.net/blogs/dotnet/archive/2008/09/17/novas-vagas-para-o-nosso-time.aspx</guid>
            <pubDate>Wed, 17 Sep 2008 11:28:22 GMT</pubDate>
            <wfw:comment>http://eduardomiranda.net/blogs/dotnet/comments/262.aspx</wfw:comment>
            <comments>http://eduardomiranda.net/blogs/dotnet/archive/2008/09/17/novas-vagas-para-o-nosso-time.aspx#feedback</comments>
            <slash:comments>1</slash:comments>
            <wfw:commentRss>http://eduardomiranda.net/blogs/dotnet/comments/commentRss/262.aspx</wfw:commentRss>
        <feedburner:origLink>http://eduardomiranda.net/blogs/dotnet/archive/2008/09/17/novas-vagas-para-o-nosso-time.aspx</feedburner:origLink></item>
        <item>
            <title>Introdução às expressões Lambda</title>
            <category>Exemplos</category>
            <link>http://feedproxy.google.com/~r/EduardoMirandaDotNet/~3/x3w_DxzT7ps/introducao-expressoes-lambda.aspx</link>
            <description>&lt;p&gt;A série de artigos sobre high-order functions e Linq gerou algumas conversas sobre as lambda expressions que utilizei. Ali, de bate pronto, tive dificuldades de explicar o conceito e percebi que ele não é tão trivial tanto para explicar, como para entender. &lt;/p&gt;
&lt;p&gt;Então vou tentar apresentar de uma forma alternativa, mostrando a evolução da linguagem em direção às lambdas expressions.&lt;/p&gt;
&lt;p&gt;No .Net framework 1.1 os delegates já existiam. Sua utilização prática, no entanto, era restrita aos eventos. Não que isto fosse uma restrição do framework, era mais uma questão de pouco conhecimento dos desenvolvedores mesmo. &lt;/p&gt;
&lt;p&gt;Como expliquei no &lt;a href="http://www.eduardomiranda.net/blogs/dotnet/archive/2008/08/14/brincando-com-c.aspx"&gt;Brincando com C#&lt;/a&gt;, os delegates permitem que uma função seja passada como parâmetro ou retorno de outra função. Desta forma posso delegar parte do meu algoritmo para outra função.&lt;/p&gt;
&lt;p&gt;Por exemplo, se tenho um método que transforma linhas de texto. Por algum motivo a regra de transformação pode variar. Para não precisar reescrever o método inteiro para cada situação, utilizo um delegate para isolar este trecho de código e poder reaproveitar todo o resto.&lt;/p&gt;
&lt;p&gt;O passo-a-passo que a gente já conhece: Declara um delegate, cria um método que recebe o delegate como parâmetro, cria o método que “implementa” o delegate.&lt;/p&gt;
&lt;pre class="csharpcode"&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;delegate&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; Parser(&lt;span class="kwrd"&gt;string&lt;/span&gt; line);

    &lt;span class="kwrd"&gt;public&lt;/span&gt; IEnumerable&amp;lt;&lt;span class="kwrd"&gt;string&lt;/span&gt;&amp;gt; ParseText(IEnumerable&amp;lt;&lt;span class="kwrd"&gt;string&lt;/span&gt;&amp;gt; text, Parser parser)
    {
        var lines = &lt;span class="kwrd"&gt;new&lt;/span&gt; List&amp;lt;&lt;span class="kwrd"&gt;string&lt;/span&gt;&amp;gt;();

        &lt;span class="kwrd"&gt;foreach&lt;/span&gt; (&lt;span class="kwrd"&gt;string&lt;/span&gt; line &lt;span class="kwrd"&gt;in&lt;/span&gt; text)
        {
           lines.Add(parser(line));
        }

        &lt;span class="kwrd"&gt;return&lt;/span&gt; lines;
    }

    &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; RemoveSpaces(&lt;span class="kwrd"&gt;string&lt;/span&gt; line)
    {
        &lt;span class="kwrd"&gt;return&lt;/span&gt; line.Replace(&lt;span class="str"&gt;" "&lt;/span&gt;, &lt;span class="str"&gt;""&lt;/span&gt;);
    }&lt;/pre&gt;
&lt;style type="text/css"&gt;&lt;![CDATA[
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }]]&gt;&lt;/style&gt;
&lt;p&gt;Utilização é simples, chama o Parser, mandando como parâmetro o RemoveSpaces.&lt;/p&gt;
&lt;pre class="csharpcode"&gt;    var parsedLines =  (List&amp;lt;&lt;span class="kwrd"&gt;string&lt;/span&gt;&amp;gt;) ParseText(lines, RemoveSpaces);&lt;/pre&gt;
&lt;style type="text/css"&gt;&lt;![CDATA[
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }]]&gt;&lt;/style&gt;
&lt;p&gt;&lt;strong&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Anonymous methods&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;O .Net Framework 2.0 trouxe a novidade dos anonymous methods. O nome não podia ser mais específico, métodos anônimos são ... anônimos! Ou seja, sem nome. Não é necessário definir formalmente o método, posso simplesmente declará-lo localmente.&lt;/p&gt;
&lt;pre class="csharpcode"&gt;    var parsedLines = (List&amp;lt;&lt;span class="kwrd"&gt;string&lt;/span&gt;&amp;gt;) ParseText(lines, 
                                               &lt;span class="kwrd"&gt;delegate&lt;/span&gt;(&lt;span class="kwrd"&gt;string&lt;/span&gt; line)
                                               {
                                                   &lt;span class="kwrd"&gt;return&lt;/span&gt; line.Replace(&lt;span class="str"&gt;" "&lt;/span&gt;, &lt;span class="str"&gt;""&lt;/span&gt;);
                                               });&lt;/pre&gt;
&lt;style type="text/css"&gt;&lt;![CDATA[
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }]]&gt;&lt;/style&gt;
&lt;p&gt;Sinceramente, para um método que deveria ser anônimo, ele é um método bem declarado e tem uma sintaxe verborrágica. &lt;/p&gt;
&lt;p&gt;Vamos fazer um exercício para imaginar uma sintaxe um pouco mais simples, retirando tudo o que desnecessário nesta declaração. Na Figura marquei o que é inútil nesta declaração. A começar por definir o método como um delegate, já que a chamada do método espera um delegate isto é totalmente desnecessário. Tipificar o(s) parâmetro(s) também é desnecessário, pois a assinatura do método já foi declarada no delegate. Por último, o parêntesis que determina o início e o fim do método.&lt;/p&gt;
&lt;p&gt;&lt;img style="BORDER-BOTTOM: 0px; BORDER-LEFT: 0px; BORDER-TOP: 0px; BORDER-RIGHT: 0px" title="anonMethod" border="0" alt="anonMethod" width="382" height="103" src="http://eduardomiranda.net/blogs/images/eduardomiranda_net/blogs/dotnet/WindowsLiveWriter/IntroduosexpressesLambda_D37A/anonMethod_5.gif" /&gt; &lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;Vemos que seria possível definir uma sintaxe ainda mais simples do que os métodos anônimos. E é exatamente isto que foi feito para o .Net Framework 3.0, com as Lambdas expressions.&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Lambda expressions&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;O .Net Framework 3.0 trouxe esta nova sintaxe para escrever métodos anônimos, mais concisa e mais legível. O exemplo canônico, e mais simples, das expressões lambdas, é o calculo de uma raiz quadrada:&lt;/p&gt;
&lt;p&gt;&lt;img style="BORDER-BOTTOM: 0px; BORDER-LEFT: 0px; BORDER-TOP: 0px; BORDER-RIGHT: 0px" title="lambda" border="0" alt="lambda" width="193" height="63" src="http://eduardomiranda.net/blogs/images/eduardomiranda_net/blogs/dotnet/WindowsLiveWriter/IntroduosexpressesLambda_D37A/lambda_3.gif" /&gt; &lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;A Figura mostra que à esquerda são declarados os parâmetros da expressão, à direita a expressão em si. Neste simples exemplo é definido o parâmetro de entrada x e a expressão é a multiplicação do parâmetro por ele mesmo, ou seja, a sua raiz quadrada.&lt;/p&gt;
&lt;pre class="csharpcode"&gt;    var parsedLines = (List&amp;lt;&lt;span class="kwrd"&gt;string&lt;/span&gt;&amp;gt;) ParseText( lines, line =&amp;gt; line.Replace( &lt;span class="str"&gt;" "&lt;/span&gt;, &lt;span class="str"&gt;""&lt;/span&gt; ) );&lt;/pre&gt;
&lt;style type="text/css"&gt;&lt;![CDATA[
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }]]&gt;&lt;/style&gt;
&lt;p&gt;Nosso exemplo, utilizando uma expressão lambda no lugar do método anônimo, fica bem mais simples e limpo. Uma coisa que pode confundir é como o compilador sabe qual o tipo do parâmetro line? Elementar, a função espera um delegate, cuja assinatura recebe um parâmetro do tipo string, por inferência, o compilador percebe que o parâmetro é do tipo string. A IDE utiliza a mesma regra para oferecer o intellisense, como mostra a Figura.&lt;/p&gt;
&lt;p&gt;&lt;img style="BORDER-BOTTOM: 0px; BORDER-LEFT: 0px; BORDER-TOP: 0px; BORDER-RIGHT: 0px" title="intellisense" border="0" alt="intellisense" width="292" height="214" src="http://eduardomiranda.net/blogs/images/eduardomiranda_net/blogs/dotnet/WindowsLiveWriter/IntroduosexpressesLambda_D37A/intellisense_3.gif" /&gt; &lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;A sintaxe lambda é bem mais robusta e complexa do que mostram estes dois exemplos que fiz aqui. Ela aceita parâmetros com tipo definido, métodos sem parâmetros, entre outras coisas. Um guia mais completo da sintaxe pode ser &lt;a href="http://msdn.microsoft.com/en-us/library/bb397687.aspx"&gt;encontrado aqui&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Espero ter ajudado um pouco na compreensão deste novo conceito do .Net Framework.&lt;/p&gt;&lt;img src="http://eduardomiranda.net/blogs/dotnet/aggbug/261.aspx" width="1" height="1" /&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/EduardoMirandaDotNet?a=x3w_DxzT7ps:G8PXE8BugwQ:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/EduardoMirandaDotNet?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/EduardoMirandaDotNet?a=x3w_DxzT7ps:G8PXE8BugwQ:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/EduardoMirandaDotNet?i=x3w_DxzT7ps:G8PXE8BugwQ:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/EduardoMirandaDotNet?a=x3w_DxzT7ps:G8PXE8BugwQ:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/EduardoMirandaDotNet?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/EduardoMirandaDotNet?a=x3w_DxzT7ps:G8PXE8BugwQ:bcOpcFrp8Mo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/EduardoMirandaDotNet?d=bcOpcFrp8Mo" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/EduardoMirandaDotNet/~4/x3w_DxzT7ps" height="1" width="1"/&gt;</description>
            <dc:creator>Eduardo Miranda</dc:creator>
            <guid isPermaLink="false">http://eduardomiranda.net/blogs/dotnet/archive/2008/09/02/introducao-expressoes-lambda.aspx</guid>
            <pubDate>Tue, 02 Sep 2008 18:02:23 GMT</pubDate>
            <wfw:comment>http://eduardomiranda.net/blogs/dotnet/comments/261.aspx</wfw:comment>
            <comments>http://eduardomiranda.net/blogs/dotnet/archive/2008/09/02/introducao-expressoes-lambda.aspx#feedback</comments>
            <slash:comments>3</slash:comments>
            <wfw:commentRss>http://eduardomiranda.net/blogs/dotnet/comments/commentRss/261.aspx</wfw:commentRss>
        <feedburner:origLink>http://eduardomiranda.net/blogs/dotnet/archive/2008/09/02/introducao-expressoes-lambda.aspx</feedburner:origLink></item>
        <item>
            <title>O problema &amp;eacute; a testabilidade, n&amp;atilde;o o Banco de Dados!</title>
            <category>Arquitetura</category>
            <link>http://feedproxy.google.com/~r/EduardoMirandaDotNet/~3/8aq-elrJj3A/o-problema-eacute-a-testabilidade-natildeo-o-banco-de-dados.aspx</link>
            <description>&lt;p&gt;Outro dia sai do trabalho com uma cópia de um artigo do Alistair Cockburn, &lt;a href="http://alistair.cockburn.us/index.php/Hexagonal_architecture"&gt;Hexagonal architecture&lt;/a&gt;, que fala sobre arquitetura de aplicações. Acabei em uma mesa de bar e o artigo incitou um debate sobre a necessidade de desenvolver aplicações que são agnósticas em relação ao Banco de dados, em outras palavras, aplicações que funcionam com diversos bancos de dados somente com alteração de configurações.&lt;/p&gt;  &lt;p&gt;Para alguns na mesa isto é desnecessário, já que este não é um requisito real na grande maioria dos casos. São raros os exemplos de aplicações que foram migradas de um SGBD para outro e não é possível prever que isto vá acontecer um dia. Portanto, adicionar esta característica a aplicação seria adicionar complexidade desnecessariamente.&lt;/p&gt;  &lt;p&gt;O problema não são os argumentos, mas sim o assunto. Ele é tão polêmico, quanto inútil. Pior que isto, nos distrai do que é realmente importante, como aconteceu nesta conversa que tive.&lt;/p&gt;  &lt;p&gt;Eis a introdução do artigo, que iniciou todo o debate:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;Create your application to work without either a UI or a database &lt;strong&gt;so you can run automated regression-tests against the application&lt;/strong&gt;, work when the database becomes unavailable, and link applications together without any user involvement.&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;O negrito foi colocado propositalmente para destacar o assunto mais importante, que é ofuscado pela inútil discussão sobre banco de dados. Os principais requisitos da divisão de responsabilidades entre camadas e artefatos de uma aplicação são: Testabilidade e manutenibilidade.&lt;/p&gt;  &lt;p&gt;A lógica de comunicação com o Banco de dados é complexa o suficiente para ser considerada uma responsabilidade que deve ser isolada e testada à parte. Mas isto já é feito pela camada de acesso a dado na velha conhecida arquitetura em três camadas.&lt;/p&gt;  &lt;p&gt;Se eu consigo isolar e substituir esta camada por &lt;a href="http://xunitpatterns.com/Test%20Double.html"&gt;test double&lt;/a&gt; para poder testar as outras camadas sem precisar acessar o banco de dados meus já estão infinitamente melhores.&lt;/p&gt;  &lt;p&gt;É possível testar uma aplicação sem isolá-la em pedaços menores. Na verdade isto é até desejável, são conhecidos como testes de aceitação, que testam cenários fim a fim, inclusive a persistência e leitura de dados no banco de dados. Todavia estes testes normalmente são pouco assertivos e consomem bastante tempo. &lt;/p&gt;  &lt;p&gt;Um teste destes pode falhar por que: A UI não está correta, a regra de negócios está com defeito, o código de persistência está incorreto, a conexão de rede falhou, o tempo de resposta expirou, o dado no Banco de dados está incorreto, o Banco de dados está offline ou &amp;lt;preencha aqui o seu motivo favorito&amp;gt;. Ou seja, por qualquer motivo.&lt;/p&gt;  &lt;p&gt;Além disto, a comunicação aplicação SGBD ainda é um pontos que mais consome tempo de execução, o que torna estes testes demorados.&lt;/p&gt;  &lt;p&gt;Em suma, é desejável, senão necessário, conseguir testar minha aplicação sem precisar acessar o banco de dados a cada teste.&lt;/p&gt;  &lt;p&gt;Mas se é possível substituir toda a camada de acesso a dados por uma falsa, ou um test double, então eu consigo substituir por outra que acesse outro repositório de dados. Então a propriedade “banco de dados agnóstica” vem de graça, ou a um custo muito baixo, como resultado da correta divisão de responsabilidades e do desacoplamento das camadas.&lt;/p&gt;  &lt;p&gt;Agora como todas as decisões feitas na construção de um software, custos e benefícios devem ser avaliados. Faz algum tempo que eu acredito que testabilidade não é uma característica negociável, pois o custo de não tê-la é enorme e, mais dia menos dia, virá morder o seu calcanhar.&lt;/p&gt;&lt;img src="http://eduardomiranda.net/blogs/dotnet/aggbug/260.aspx" width="1" height="1" /&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/EduardoMirandaDotNet?a=8aq-elrJj3A:Yjr6_3qBLPI:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/EduardoMirandaDotNet?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/EduardoMirandaDotNet?a=8aq-elrJj3A:Yjr6_3qBLPI:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/EduardoMirandaDotNet?i=8aq-elrJj3A:Yjr6_3qBLPI:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/EduardoMirandaDotNet?a=8aq-elrJj3A:Yjr6_3qBLPI:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/EduardoMirandaDotNet?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/EduardoMirandaDotNet?a=8aq-elrJj3A:Yjr6_3qBLPI:bcOpcFrp8Mo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/EduardoMirandaDotNet?d=bcOpcFrp8Mo" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/EduardoMirandaDotNet/~4/8aq-elrJj3A" height="1" width="1"/&gt;</description>
            <dc:creator>Eduardo Miranda</dc:creator>
            <guid isPermaLink="false">http://eduardomiranda.net/blogs/dotnet/archive/2008/08/22/o-problema-eacute-a-testabilidade-natildeo-o-banco-de-dados.aspx</guid>
            <pubDate>Fri, 22 Aug 2008 14:05:48 GMT</pubDate>
            <wfw:comment>http://eduardomiranda.net/blogs/dotnet/comments/260.aspx</wfw:comment>
            <comments>http://eduardomiranda.net/blogs/dotnet/archive/2008/08/22/o-problema-eacute-a-testabilidade-natildeo-o-banco-de-dados.aspx#feedback</comments>
            <slash:comments>1</slash:comments>
            <wfw:commentRss>http://eduardomiranda.net/blogs/dotnet/comments/commentRss/260.aspx</wfw:commentRss>
        <feedburner:origLink>http://eduardomiranda.net/blogs/dotnet/archive/2008/08/22/o-problema-eacute-a-testabilidade-natildeo-o-banco-de-dados.aspx</feedburner:origLink></item>
        <item>
            <title>Brincando com C# - O que o Linq n&amp;atilde;o faz</title>
            <category>Exemplos</category>
            <link>http://feedproxy.google.com/~r/EduardoMirandaDotNet/~3/UThGZuMl5FA/brincando-com-c---o-que-o-linq-natildeo-faz.aspx</link>
            <description>&lt;p&gt;Depois de todo este trabalho chegamos ao ponto em que eu digo: Tudo isto é desnecessário porque o Linq já nos oferece as três high-order functions em sua implementação.&lt;/p&gt;  &lt;p&gt;Calma, pequeno gafanhoto, muitas vezes o caminho é muito mais interessante que o destino em si.&lt;/p&gt;  &lt;p&gt;Se eu simplesmente mostrasse estas funcionalidades do Linq tudo pareceria confuso e mágico. Agora, sabendo como funcionam as high-order functions, fica muito mais fácil de entender o que está acontecendo.&lt;/p&gt;  &lt;p&gt;Como falei antes algumas pessoas acham a sintaxe Linq sexy, outros não gostam e tem dificuldade de ler o código. A boa notícia é que não é necessário utilizar aquela sintaxe. Nos exemplos abaixo vou utilizar a API do Linq, ao invés da sintaxe de query.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Filter&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Veja como é fácil filtrar uma coleção de objetos utilizando o Linq:&lt;/p&gt;  &lt;pre class="csharpcode"&gt;    List&amp;lt;Cliente&amp;gt; clientesDoPara = clientes.Where(cliente =&amp;gt; cliente.Estado.Equals(&lt;span class="str"&gt;"Pará"&lt;/span&gt;))
                                            .ToList();&lt;/pre&gt;
&lt;style type="text/css"&gt;&lt;![CDATA[
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }]]&gt;&lt;/style&gt;

&lt;p&gt;Utilizando a sintaxe Linq:&lt;/p&gt;

&lt;pre class="csharpcode"&gt;    var clientesDoPara = (from cliente &lt;span class="kwrd"&gt;in&lt;/span&gt; clientes
                          &lt;span class="kwrd"&gt;where&lt;/span&gt; cliente.Estado.Equals(&lt;span class="str"&gt;"Pará"&lt;/span&gt;)
                          select cliente).ToList();&lt;/pre&gt;
&lt;style type="text/css"&gt;&lt;![CDATA[
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }]]&gt;&lt;/style&gt;

&lt;p&gt;&lt;strong&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Map&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Para o map posso utilizar a função select, também sem problemas.&lt;/p&gt;

&lt;pre class="csharpcode"&gt;    var clientes = clientesCrm.Select(clienteCRM =&amp;gt; &lt;span class="kwrd"&gt;new&lt;/span&gt; Cliente(&lt;span class="kwrd"&gt;string&lt;/span&gt;.Format(&lt;span class="str"&gt;"{0} {1}"&lt;/span&gt;, 
                                                                              clienteCRM.FirstName, 
                                                                              clienteCRM.LastName)))
                              .ToList();&lt;/pre&gt;
&lt;style type="text/css"&gt;&lt;![CDATA[
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }]]&gt;&lt;/style&gt;

&lt;p&gt;Uitlizando a sintaxe Linq:&lt;/p&gt;

&lt;pre class="csharpcode"&gt;    var clientes = (from clienteCRM &lt;span class="kwrd"&gt;in&lt;/span&gt; clientesCrm
                    select &lt;span class="kwrd"&gt;new&lt;/span&gt; Cliente(&lt;span class="kwrd"&gt;string&lt;/span&gt;.Format(&lt;span class="str"&gt;"{0} {1}"&lt;/span&gt;,
                                                     clienteCRM.FirstName,
                                                     clienteCRM.LastName))
                   ).ToList();&lt;/pre&gt;
&lt;style type="text/css"&gt;&lt;![CDATA[
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }]]&gt;&lt;/style&gt;

&lt;p&gt;&lt;strong&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Fold ou Reduce&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Este é um pouco mais interessante. Out-of-the-box o Linq já oferece várias implementações específicas, por exemplo Sum, Max, Min. São todos especializações do Reduce. Ele também oferece o genérico, Aggregate, que aceita a função que realiza o fold. Em nosso exemplo o Sum não nos atende, precisamos somar a multiplicação de dois campos. O resultado ficaria assim:&lt;/p&gt;

&lt;pre class="csharpcode"&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;double&lt;/span&gt; TotalAmount()
    {
        &lt;span class="kwrd"&gt;return&lt;/span&gt; lines.Aggregate&amp;lt;SalesLine, &lt;span class="kwrd"&gt;double&lt;/span&gt;&amp;gt;(0d, AcumulaTotalDaLinha);
    }

    &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;double&lt;/span&gt; AcumulaTotalDaLinha(&lt;span class="kwrd"&gt;double&lt;/span&gt; total, SalesLine item)
    {
        &lt;span class="kwrd"&gt;return&lt;/span&gt; total + (item.Quantidade * item.Preco);
    }&lt;/pre&gt;
&lt;style type="text/css"&gt;&lt;![CDATA[
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }]]&gt;&lt;/style&gt;

&lt;p&gt;Mas também posso refatorar meu código e passar o cálculo do total da linha para a própria linha, faz todo o sentido, por sinal, neste caso posso utilizar o Sum:&lt;/p&gt;

&lt;pre class="csharpcode"&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; SalesLine
    {
        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;double&lt;/span&gt; Quantidade { get; set; }
        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;double&lt;/span&gt; Preco { get; set; }

        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;double&lt;/span&gt; Total()
        {
            &lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="kwrd"&gt;this&lt;/span&gt;.Quantidade * &lt;span class="kwrd"&gt;this&lt;/span&gt;.Preco;
        }
    }
        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;double&lt;/span&gt; TotalAmount()
        {
            &lt;span class="kwrd"&gt;return&lt;/span&gt; lines.Select(line =&amp;gt; line.Total())
                        .Sum();
        }
    }&lt;/pre&gt;
&lt;style type="text/css"&gt;&lt;![CDATA[
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }]]&gt;&lt;/style&gt;

&lt;p&gt;Ou simplesmente:&lt;/p&gt;

&lt;pre class="csharpcode"&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;double&lt;/span&gt; TotalAmount()
    {
        &lt;span class="kwrd"&gt;return&lt;/span&gt; lines.Sum(line =&amp;gt; line.Total());
    }&lt;/pre&gt;
&lt;style type="text/css"&gt;&lt;![CDATA[
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }]]&gt;&lt;/style&gt;

&lt;p&gt;&lt;b&gt;&lt;/b&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Perfomance e escopo&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Olhando para os exemplos desta série uma importante dúvida pode surgir: Mas eu preciso transformar TUDO em coleção antes realizar estas operações? Por exemplo, não seria mais performático realizar o filtro ao trazer a coleção do banco de dados ao invés de realizá-la na coleção? O mesmo pode se dizer da integração, é necessário trazer todos os dados, criar uma coleção para depois transformá-los?&lt;/p&gt;

&lt;p&gt;Para responder isto é necessário diferenciar o que é Linq do que são implementações de Linq:&lt;/p&gt;

&lt;p&gt;Linq é a .Net Language-integrated query, ou seja, a sintaxe, e a API, que permite realizar operações sobre objetos IEnumerable. “Apenas” isto.&lt;/p&gt;

&lt;p&gt;Uma implementação de Linq implementa estas operações para um determinado escopo. A Microsoft lançou, junto com o Linq, algumas implementações:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Linq to objects – Permite realizar queries Linq em qualquer coleção do .Net framework que implementa o IEnumerable, como List ou Array. É o que estou utilizando neste exemplo e o que você vê na imensa maioria de exemplos na internet.&lt;/li&gt;

  &lt;li&gt;Linq to SQL – Permite realizar queries Linq em Banco de dados SQL Server. Para possibilitar isto ele realiza um mapeamento entre tabelas do banco de dados e objetos .Net. As queries realizadas nestes objetos são transformadas em comandos T-SQL e executados no Banco de dados, retornando objetos instanciados.&lt;/li&gt;

  &lt;li&gt;Linq to XML – Permite realizar queries Linq em arquivos XML. Para isto foi criada uma nova API de manipulação de XML, localizada em &lt;a href="http://msdn.microsoft.com/en-us/library/system.xml.linq.aspx"&gt;System.Xml.Linq&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Além destes existem diversas implementações de Linq criadas por terceiros. Desde “brincadeiras” como o &lt;a href="http://www.codeplex.com/LINQFlickr"&gt;Linq to Flickr&lt;/a&gt; até implementações para ferramentas de ORM. Uma ótima leitura para quem quer entender melhor isto é a série do Frans Bouma sobre a implementação do &lt;a href="http://www.codeplex.com/LINQFlickr"&gt;Linq to LLBLGen&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Então, respondendo a pergunta original: Não, o Linq não é restrito a coleções de objetos .Net, você pode fazer as mesmas queries em um Banco de dados SQL Server, por exemplo. &lt;/p&gt;

&lt;p&gt;Quanto a performance ela não depende do Linq mas da implementação. Eu posso fazer um Linq to AnySGBD que simplesmente traz todas as linhas da tabelas e realiza o filtro em .Net, certamente não será a implementação mais performática disponível :)&lt;/p&gt;&lt;img src="http://eduardomiranda.net/blogs/dotnet/aggbug/259.aspx" width="1" height="1" /&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/EduardoMirandaDotNet?a=UThGZuMl5FA:F7LEZDRdu7A:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/EduardoMirandaDotNet?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/EduardoMirandaDotNet?a=UThGZuMl5FA:F7LEZDRdu7A:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/EduardoMirandaDotNet?i=UThGZuMl5FA:F7LEZDRdu7A:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/EduardoMirandaDotNet?a=UThGZuMl5FA:F7LEZDRdu7A:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/EduardoMirandaDotNet?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/EduardoMirandaDotNet?a=UThGZuMl5FA:F7LEZDRdu7A:bcOpcFrp8Mo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/EduardoMirandaDotNet?d=bcOpcFrp8Mo" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/EduardoMirandaDotNet/~4/UThGZuMl5FA" height="1" width="1"/&gt;</description>
            <dc:creator>Eduardo Miranda</dc:creator>
            <guid isPermaLink="false">http://eduardomiranda.net/blogs/dotnet/archive/2008/08/21/brincando-com-c---o-que-o-linq-natildeo-faz.aspx</guid>
            <pubDate>Thu, 21 Aug 2008 17:25:47 GMT</pubDate>
            <wfw:comment>http://eduardomiranda.net/blogs/dotnet/comments/259.aspx</wfw:comment>
            <comments>http://eduardomiranda.net/blogs/dotnet/archive/2008/08/21/brincando-com-c---o-que-o-linq-natildeo-faz.aspx#feedback</comments>
            <wfw:commentRss>http://eduardomiranda.net/blogs/dotnet/comments/commentRss/259.aspx</wfw:commentRss>
        <feedburner:origLink>http://eduardomiranda.net/blogs/dotnet/archive/2008/08/21/brincando-com-c---o-que-o-linq-natildeo-faz.aspx</feedburner:origLink></item>
        <item>
            <title>Brincando com C# - High-order extension</title>
            <category>Exemplos</category>
            <link>http://feedproxy.google.com/~r/EduardoMirandaDotNet/~3/CbSOvP3W8UM/brincando-com-c---high-order-extension.aspx</link>
            <description>&lt;p&gt;Antes de continuar falando sobre Linq vou apresentar como ficariam os outros dois exemplos típicos de High-order functions seguindo a estrutura do Filter.&lt;/p&gt;  &lt;p&gt;&lt;b&gt;Map&lt;/b&gt;&lt;/p&gt;  &lt;p&gt;Uma função que dada uma coleção de objetos de um tipo, retorna uma coleção de objetos de outro tipo, realizando a transformação.&lt;/p&gt;  &lt;p&gt;Um exemplo é a integração entre dois aplicativos. É normal que entidades comuns, como Cliente, co-existam nas duas aplicações. Também é normal que esta entidade seja exatamente igual nos dois aplicativos. Daí a necessidade de transformações quando os sistemas estiverem trocando informações, desde formato de data, até normalização de tabelas.&lt;/p&gt;  &lt;p&gt;Neste caso, o cliente em um dos aplicativos tem nome e sobrenome, já no outro, existe somente o nome completo. Ao trocar informações esta transformação é necessária.&lt;/p&gt;  &lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;private&lt;/span&gt; List&amp;lt;Cliente&amp;gt; MapClientes(List&amp;lt;ClienteCrm&amp;gt; collection)
{
    List&amp;lt;Cliente&amp;gt; result = &lt;span class="kwrd"&gt;new&lt;/span&gt; List&amp;lt;Cliente&amp;gt;();

    &lt;span class="kwrd"&gt;foreach&lt;/span&gt; (var item &lt;span class="kwrd"&gt;in&lt;/span&gt; collection)
    {
        result.Add(&lt;span class="kwrd"&gt;new&lt;/span&gt; Cliente(&lt;span class="kwrd"&gt;string&lt;/span&gt;.Format(&lt;span class="str"&gt;"{0} {1}"&lt;/span&gt;, item.FirstName, item.LastName)));
    }

    &lt;span class="kwrd"&gt;return&lt;/span&gt; result;
}&lt;/pre&gt;
&lt;style type="text/css"&gt;&lt;![CDATA[
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }]]&gt;&lt;/style&gt;

&lt;p&gt;Não é necessário seguir passo-a-passo, pois já fizemos isto no &lt;a href="http://www.eduardomiranda.net/blogs/dotnet/archive/2008/08/14/brincando-com-c.aspx"&gt;primeiro post,&lt;/a&gt; com o Filter. Isolando as partes que não mudam, das mutáveis, tenho o seguinte método para mapear qualquer par de objetos:&lt;/p&gt;

&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;delegate&lt;/span&gt; TResult Transform&amp;lt;TSource, TResult&amp;gt;(TSource source);

&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; IEnumerable&amp;lt;TResult&amp;gt; Map&amp;lt;TSource, TResult&amp;gt;(&lt;span class="kwrd"&gt;this&lt;/span&gt; IEnumerable&amp;lt;TSource&amp;gt; collection, 
    Transform&amp;lt;TSource, TResult&amp;gt; transform)
{
    List&amp;lt;TResult&amp;gt; result = &lt;span class="kwrd"&gt;new&lt;/span&gt; List&amp;lt;TResult&amp;gt;();

    &lt;span class="kwrd"&gt;foreach&lt;/span&gt; (var item &lt;span class="kwrd"&gt;in&lt;/span&gt; collection)
    {
        result.Add(transform(item));
    }

    &lt;span class="kwrd"&gt;return&lt;/span&gt; result;
}&lt;/pre&gt;
&lt;style type="text/css"&gt;&lt;![CDATA[
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }]]&gt;&lt;/style&gt;

&lt;p&gt;O código que utiliza este método seria:&lt;/p&gt;

&lt;p&gt;Cliente MapClienteCrmToCliente(ClienteCrm clienteCrm)
  &lt;br /&gt;{

  &lt;br /&gt;    return new Cliente(string.Format("{0} {1}", 

  &lt;br /&gt;    clienteCrm.FirstName, 

  &lt;br /&gt;    clienteCrm.LastName));

  &lt;br /&gt;} &lt;/p&gt;

&lt;p&gt;List&amp;lt;Cliente&amp;gt; clientes = (List&amp;lt;Cliente&amp;gt;) clientesCrm.Map&amp;lt;ClienteCrm, Cliente&amp;gt;(MapClienteCrmToCliente);&lt;/p&gt;

&lt;p&gt;&lt;b&gt;Fold ou Reduce&lt;/b&gt;&lt;/p&gt;

&lt;p&gt;Uma função que processa uma coleção de objetos retornando um valor. Este processamento de alguma forma combina os objetos desta coleção para calcular o resultado final. A mais óbvia seria a somatória, dada uma lista de inteiros retorne a soma destes.&lt;/p&gt;

&lt;p&gt;Outro exemplo simples, mas um pouco menos óbvio, seria calcular o valor total de uma venda, que é a soma dos valores totais de cada uma de suas linhas, que é a quantidade de produtos multiplicada pelo preço unitário. O código ficaria assim:&lt;/p&gt;

&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; SalesOrder
{
    &lt;span class="kwrd"&gt;private&lt;/span&gt; List&amp;lt;SalesLine&amp;gt; lines = &lt;span class="kwrd"&gt;new&lt;/span&gt; List&amp;lt;SalesLine&amp;gt;();

    &lt;span class="kwrd"&gt;public&lt;/span&gt; IEnumerable&amp;lt;SalesLine&amp;gt; Lines
    {
        get
        {
            &lt;span class="kwrd"&gt;return&lt;/span&gt; lines;
        }
    }

    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;double&lt;/span&gt; TotalAmount()
    {
        &lt;span class="kwrd"&gt;double&lt;/span&gt; total = 0;

        &lt;span class="kwrd"&gt;foreach&lt;/span&gt; (var item &lt;span class="kwrd"&gt;in&lt;/span&gt; lines)
        {
            total = total + (item.Quantidade * item.Preco);
        }

        &lt;span class="kwrd"&gt;return&lt;/span&gt; total;
    }
}&lt;/pre&gt;
&lt;style type="text/css"&gt;&lt;![CDATA[
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }]]&gt;&lt;/style&gt;

&lt;p&gt;Seguindo o mesmo processo de sempre, eu teria um método Fold genérico:&lt;/p&gt;

&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;delegate&lt;/span&gt; TResult Acumulate&amp;lt;TSource, TResult&amp;gt;(TSource item, TResult initial);

&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; TResult Fold&amp;lt;TSource, TResult&amp;gt;(&lt;span class="kwrd"&gt;this&lt;/span&gt; IEnumerable&amp;lt;TSource&amp;gt; collection, TResult initial, Acumulate&amp;lt;TSource, TResult&amp;gt; acumulate)
{
    TResult result = initial;

    &lt;span class="kwrd"&gt;foreach&lt;/span&gt; (var item &lt;span class="kwrd"&gt;in&lt;/span&gt; collection)
        result = acumulate(item, result);

    &lt;span class="kwrd"&gt;return&lt;/span&gt; result;
}&lt;/pre&gt;
&lt;style type="text/css"&gt;&lt;![CDATA[
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }]]&gt;&lt;/style&gt;

&lt;p&gt;E sua utilização seria:&lt;/p&gt;

&lt;pre class="csharpcode"&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;double&lt;/span&gt; TotalAmount()
    {
        &lt;span class="kwrd"&gt;return&lt;/span&gt; lines.Fold&amp;lt;SalesLine, &lt;span class="kwrd"&gt;double&lt;/span&gt;&amp;gt;(0d, AcumulaTotalDaLinha);
    }

    &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;double&lt;/span&gt; AcumulaTotalDaLinha(SalesLine item, &lt;span class="kwrd"&gt;double&lt;/span&gt; total)
    {
        &lt;span class="kwrd"&gt;return&lt;/span&gt; total + (item.Quantidade * item.Preco);
    }&lt;/pre&gt;

&lt;p&gt;No final das contas esta seria a classe completa, com os três extension methods.&lt;/p&gt;

&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System;
&lt;span class="kwrd"&gt;using&lt;/span&gt; System.Collections.Generic;
&lt;span class="kwrd"&gt;using&lt;/span&gt; System.Linq;

&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; HighOrderExtension
{
    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; IEnumerable&amp;lt;T&amp;gt; Filter&amp;lt;T&amp;gt;(&lt;span class="kwrd"&gt;this&lt;/span&gt; IEnumerable&amp;lt;T&amp;gt; collection, 
                                            Predicate&amp;lt;T&amp;gt; filter)
    {
        var result = from item &lt;span class="kwrd"&gt;in&lt;/span&gt; collection
                     &lt;span class="kwrd"&gt;where&lt;/span&gt; filter(item)
                     select item;

        &lt;span class="kwrd"&gt;return&lt;/span&gt; result.ToList&amp;lt;T&amp;gt;();
    }

    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;delegate&lt;/span&gt; TResult Transform&amp;lt;TSource, TResult&amp;gt;(TSource source);

    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; IEnumerable&amp;lt;TResult&amp;gt; Map&amp;lt;TSource, TResult&amp;gt;(&lt;span class="kwrd"&gt;this&lt;/span&gt; IEnumerable&amp;lt;TSource&amp;gt; collection, 
                                                                Transform&amp;lt;TSource, TResult&amp;gt; transform)
    {
        List&amp;lt;TResult&amp;gt; result = &lt;span class="kwrd"&gt;new&lt;/span&gt; List&amp;lt;TResult&amp;gt;();

        &lt;span class="kwrd"&gt;foreach&lt;/span&gt; (var item &lt;span class="kwrd"&gt;in&lt;/span&gt; collection)
        {
            result.Add(transform(item));
        }

        &lt;span class="kwrd"&gt;return&lt;/span&gt; result;
    }

    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;delegate&lt;/span&gt; TResult Acumulate&amp;lt;TSource, TResult&amp;gt;(TSource item, TResult initial);

    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; TResult Fold&amp;lt;TSource, TResult&amp;gt;(&lt;span class="kwrd"&gt;this&lt;/span&gt; IEnumerable&amp;lt;TSource&amp;gt; collection, TResult initial, Acumulate&amp;lt;TSource, TResult&amp;gt; acumulate)
    {
        TResult result = initial;

        &lt;span class="kwrd"&gt;foreach&lt;/span&gt; (var item &lt;span class="kwrd"&gt;in&lt;/span&gt; collection)
            result = acumulate(item, result);

        &lt;span class="kwrd"&gt;return&lt;/span&gt; result;
    }
}&lt;/pre&gt;

&lt;p&gt;Até a próxima.&lt;/p&gt;&lt;img src="http://eduardomiranda.net/blogs/dotnet/aggbug/258.aspx" width="1" height="1" /&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/EduardoMirandaDotNet?a=CbSOvP3W8UM:P9Vi2YbBJn0:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/EduardoMirandaDotNet?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/EduardoMirandaDotNet?a=CbSOvP3W8UM:P9Vi2YbBJn0:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/EduardoMirandaDotNet?i=CbSOvP3W8UM:P9Vi2YbBJn0:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/EduardoMirandaDotNet?a=CbSOvP3W8UM:P9Vi2YbBJn0:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/EduardoMirandaDotNet?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/EduardoMirandaDotNet?a=CbSOvP3W8UM:P9Vi2YbBJn0:bcOpcFrp8Mo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/EduardoMirandaDotNet?d=bcOpcFrp8Mo" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/EduardoMirandaDotNet/~4/CbSOvP3W8UM" height="1" width="1"/&gt;</description>
            <dc:creator>Eduardo Miranda</dc:creator>
            <guid isPermaLink="false">http://eduardomiranda.net/blogs/dotnet/archive/2008/08/19/brincando-com-c---high-order-extension.aspx</guid>
            <pubDate>Tue, 19 Aug 2008 21:58:11 GMT</pubDate>
            <wfw:comment>http://eduardomiranda.net/blogs/dotnet/comments/258.aspx</wfw:comment>
            <comments>http://eduardomiranda.net/blogs/dotnet/archive/2008/08/19/brincando-com-c---high-order-extension.aspx#feedback</comments>
            <wfw:commentRss>http://eduardomiranda.net/blogs/dotnet/comments/commentRss/258.aspx</wfw:commentRss>
        <feedburner:origLink>http://eduardomiranda.net/blogs/dotnet/archive/2008/08/19/brincando-com-c---high-order-extension.aspx</feedburner:origLink></item>
        <item>
            <title>Brincando com C# - Adicionando o tempero do 3.5</title>
            <category>Exemplos</category>
            <link>http://feedproxy.google.com/~r/EduardoMirandaDotNet/~3/gBhk3Szaeic/brincando-com-c---adicionando-o-tempero-do-3.5.aspx</link>
            <description>&lt;p&gt; &lt;/p&gt;
&lt;p&gt;Mudando o target do projeto de .Net framework 2.0 para 3.5 (veja &lt;a href="http://weblogs.asp.net/scottgu/archive/2007/06/20/vs-2008-multi-targeting-support.aspx"&gt;multi-targeting support&lt;/a&gt;), já existe um ganho imediato: O namespace System já oferece o delegate &lt;a href="http://msdn.microsoft.com/en-us/library/bfcke1bz.aspx"&gt;System.Predicate&amp;lt;T&amp;gt;,&lt;/a&gt; portanto posso apagar o meu delegate e recompilar o código. Isto mostra a aproximação do C#, e do .Net framework, dos paradigmas da programação funcional.&lt;/p&gt;
&lt;p&gt;Mas existem outras novidades que podemos utilizar.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Extension methods&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Com ele podemos estender um tipo sem precisar alterar, ou herdar, este tipo. Bem interessante, apesar de não ajudar muito na legibilidade do seu código. Mas em alguns casos, pode ajudar bastante. &lt;/p&gt;
&lt;p&gt;Por exemplo, uma funcionalidade de Filtro, como a nossa, pode ser utilizada por qualquer coleção que implementa IEnumerable. Por isto, podemos criar um Extension method para este tipo.&lt;/p&gt;
&lt;p&gt; &lt;img title="Figura3" style="BORDER-TOP-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-RIGHT-WIDTH: 0px" height="265" alt="Figura3" width="596" border="0" src="http://eduardomiranda.net/blogs/images/eduardomiranda_net/blogs/dotnet/WindowsLiveWriter/BrincandocomCAdicionandootemperodo3.5_AA99/Figura3_6.gif" /&gt; &lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;A lógica em si não muda nada, mas alguns detalhes o tornam um extension method. A primeira é a classe tem que ser estática. O método também precisa ser estático. A Figura mostra isto. O terceiro ponto é o modifier this no parâmetro collection. Ele indica que um objeto do tipo IEnumerable poderá chamar este método, como se ele pertencesse ao tipo. Veja como muda a sua utilização:&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Chamada antiga:&lt;/em&gt;&lt;/p&gt;
&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;private&lt;/span&gt; List&amp;lt;Cliente&amp;gt; GetClientesDoPara(List&amp;lt;Cliente&amp;gt; clientes)
{
    &lt;span class="kwrd"&gt;return&lt;/span&gt; (List&amp;lt;Cliente&amp;gt;) Filter(clientes, ClienteResideNoPara);
}&lt;/pre&gt;
&lt;style type="text/css"&gt;&lt;![CDATA[
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }]]&gt;&lt;/style&gt;
&lt;p&gt;&lt;em&gt;Nova chamada:&lt;/em&gt;&lt;/p&gt;
&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;private&lt;/span&gt; List&amp;lt;Cliente&amp;gt; GetClientesDoPara(List&amp;lt;Cliente&amp;gt; clientes)
{
    &lt;span class="kwrd"&gt;return&lt;/span&gt; (List&amp;lt;Cliente&amp;gt;) clientes.Filter(ClienteResideNoPara);
}&lt;/pre&gt;
&lt;style type="text/css"&gt;&lt;![CDATA[
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }]]&gt;&lt;/style&gt;
&lt;p&gt;Ao invés de enviar a coleção de clientes como parâmetro da função, o Filter torna uma função daquele tipo. Só para ilustrar, veja que posso utilizar este método em qualquer IEnumerable como, por exemplo, uma coleção de serviços instalados na máquin, do System.ServiceProcess&lt;/p&gt;
&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; FilterServicesTest()
{
    List&amp;lt;ServiceController&amp;gt; servicos = (List&amp;lt;ServiceController&amp;gt;) ServiceController.GetServices()&lt;/pre&gt;
&lt;pre class="csharpcode"&gt;                                                                                    .Filter(ServicosIniciados);
}

&lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;bool&lt;/span&gt; ServicosIniciados(ServiceController controller)
{
    &lt;span class="kwrd"&gt;return&lt;/span&gt; controller.Status == ServiceControllerStatus.Running;
}&lt;/pre&gt;
&lt;style type="text/css"&gt;&lt;![CDATA[
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }]]&gt;&lt;/style&gt;
&lt;p&gt;&lt;strong&gt;Lambda expressions&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Em poucas palavras, as expressões lambda permitem definir uma função anônima, sem a necessidade de formalizar um método. Você pode ler um pouco mais &lt;a href="http://msdn.microsoft.com/en-us/library/bb397687.aspx"&gt;aqui&lt;/a&gt; ou buscar na internet. A sintaxe de uma expressão bem simples é:&lt;/p&gt;
&lt;pre class="csharpcode"&gt;    x =&amp;gt; x * x&lt;/pre&gt;
&lt;style type="text/css"&gt;&lt;![CDATA[
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }]]&gt;&lt;/style&gt;
&lt;p&gt;No lado esquerdo do operador “=&amp;gt;” definem-se os parâmetros da função, neste caso o x, do lado direito, a função que mutiplica o x por ele mesmo, ou seja, sua raiz quadrada.&lt;/p&gt;
&lt;p&gt;É possível utilizar expressões lambdas para simplificar a chamada do Filter. Até agora estávamos usando:&lt;/p&gt;
&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;bool&lt;/span&gt; ClienteResideNoPara(Cliente cliente)
{
    &lt;span class="kwrd"&gt;return&lt;/span&gt; cliente.Estado.Equals(&lt;span class="str"&gt;"Pará"&lt;/span&gt;);
}

&lt;span class="kwrd"&gt;private&lt;/span&gt; List&amp;lt;Cliente&amp;gt; GetClientesDoPara(List&amp;lt;Cliente&amp;gt; clientes)
{
    &lt;span class="kwrd"&gt;return&lt;/span&gt; (List&amp;lt;Cliente&amp;gt;) clientes.Filter(ClienteResideNoPara);
}&lt;/pre&gt;
&lt;style type="text/css"&gt;&lt;![CDATA[
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }]]&gt;&lt;/style&gt;
&lt;p&gt;Ao invés de definir uma função que implementa o delegate, posso simplesmente passar uma lambda como parâmetro e dispensar o método ClienteResideNoPara: &lt;/p&gt;
&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;private&lt;/span&gt; List&amp;lt;Cliente&amp;gt; GetClientesDoPara(List&amp;lt;Cliente&amp;gt; clientes)
{
    &lt;span class="kwrd"&gt;return&lt;/span&gt; (List&amp;lt;Cliente&amp;gt;) clientes.Filter(x =&amp;gt; x.Estado.Equals(&lt;span class="str"&gt;"Pará"&lt;/span&gt;));
}&lt;/pre&gt;
&lt;style type="text/css"&gt;&lt;![CDATA[
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }]]&gt;&lt;/style&gt;
&lt;p&gt;&lt;strong&gt;O charme da sintaxe Linq&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;A sintaxe do Linq definitivamente é garbosa, dá um tom moderno ao código-fonte. Mas não é só isto. Um query Linq também pode nos poupar de utilizar alguns statements, como o foreach e o if. &lt;/p&gt;
&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; IEnumerable&amp;lt;T&amp;gt; Filter&amp;lt;T&amp;gt;(&lt;span class="kwrd"&gt;this&lt;/span&gt; IEnumerable&amp;lt;T&amp;gt; collection, 
                                                                 Predicate&amp;lt;T&amp;gt; filter)
{
    var result = from item &lt;span class="kwrd"&gt;in&lt;/span&gt; collection
                 &lt;span class="kwrd"&gt;where&lt;/span&gt; filter(item)
                 select item;

     &lt;span class="kwrd"&gt;return&lt;/span&gt; result.ToList&amp;lt;T&amp;gt;();
}&lt;/pre&gt;
&lt;style type="text/css"&gt;&lt;![CDATA[
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }]]&gt;&lt;/style&gt;
&lt;p&gt;Elegante, simples e expressivo.&lt;/p&gt;
&lt;p&gt;A seguir vamos falar um pouco mais Linq.&lt;/p&gt;&lt;img src="http://eduardomiranda.net/blogs/dotnet/aggbug/257.aspx" width="1" height="1" /&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/EduardoMirandaDotNet?a=gBhk3Szaeic:g7gHeDVjnaY:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/EduardoMirandaDotNet?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/EduardoMirandaDotNet?a=gBhk3Szaeic:g7gHeDVjnaY:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/EduardoMirandaDotNet?i=gBhk3Szaeic:g7gHeDVjnaY:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/EduardoMirandaDotNet?a=gBhk3Szaeic:g7gHeDVjnaY:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/EduardoMirandaDotNet?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/EduardoMirandaDotNet?a=gBhk3Szaeic:g7gHeDVjnaY:bcOpcFrp8Mo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/EduardoMirandaDotNet?d=bcOpcFrp8Mo" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/EduardoMirandaDotNet/~4/gBhk3Szaeic" height="1" width="1"/&gt;</description>
            <dc:creator>Eduardo Miranda</dc:creator>
            <guid isPermaLink="false">http://eduardomiranda.net/blogs/dotnet/archive/2008/08/15/brincando-com-c---adicionando-o-tempero-do-3.5.aspx</guid>
            <pubDate>Fri, 15 Aug 2008 16:15:23 GMT</pubDate>
            <wfw:comment>http://eduardomiranda.net/blogs/dotnet/comments/257.aspx</wfw:comment>
            <comments>http://eduardomiranda.net/blogs/dotnet/archive/2008/08/15/brincando-com-c---adicionando-o-tempero-do-3.5.aspx#feedback</comments>
            <wfw:commentRss>http://eduardomiranda.net/blogs/dotnet/comments/commentRss/257.aspx</wfw:commentRss>
        <feedburner:origLink>http://eduardomiranda.net/blogs/dotnet/archive/2008/08/15/brincando-com-c---adicionando-o-tempero-do-3.5.aspx</feedburner:origLink></item>
        <item>
            <title>Brincando com C#</title>
            <category>Exemplos</category>
            <link>http://feedproxy.google.com/~r/EduardoMirandaDotNet/~3/smDDAdFTQTo/brincando-com-c.aspx</link>
            <description>&lt;p&gt;&lt;/p&gt;  &lt;p&gt;Não tenho dúvidas de que o C# é a linguagem que melhor evoluiu nos últimos anos. No entanto, são tantas mudanças e novidades que às vezes fica difícil acompanhar e aplicá-las no dia-a-dia.&lt;/p&gt;  &lt;p&gt;Por exemplo, desde o C# 2.0, a linguagem vem sendo influenciada por conceitos de &lt;a href="http://pt.wikipedia.org/wiki/Programa%C3%A7%C3%A3o_funcional"&gt;linguagem funcional&lt;/a&gt;. Estas novidades têm impacto na forma como escrevemos nosso código, nos constructors que utilizamos. E isto não muda de um dia para outro.&lt;/p&gt;  &lt;p&gt;Por isto resolvi fazer algumas brincadeiras com C# para mostrar novas possibilidades na forma de programar já oferecidas pela linguagem. Vou começar com C# 2.0, sem as novidades do 3.5 e depois evoluir os exemplos.&lt;/p&gt;  &lt;p&gt;High order function é um conceito típico da programação funcional: São funções que recebem uma ou mais funções como parâmetro ou retornam uma função. Para explicar melhor vou implementar alguns exemplos clássicos de high order functions: Filter, Map e Fold.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Filter&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Um filtro processa uma coleção de objetos, filtrando-a de acordo com uma regra de decisão. Vamos considerar um exemplo simples, mas funcional, preciso filtrar de uma coleção de clientes todos que residem no estado do Pará. A implementação mais simples para resolver este problema seria: &lt;/p&gt;  &lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;private&lt;/span&gt; List&amp;lt;Cliente&amp;gt; GetClientesDoPara(List&amp;lt;Cliente&amp;gt; clientes)
{
    List&amp;lt;Cliente&amp;gt; resultado = &lt;span class="kwrd"&gt;new&lt;/span&gt; List&amp;lt;Cliente&amp;gt;();

    &lt;span class="kwrd"&gt;foreach&lt;/span&gt; (Cliente cliente &lt;span class="kwrd"&gt;in&lt;/span&gt; clientes)
    &lt;span class="kwrd"&gt;if&lt;/span&gt; (cliente.Estado.Equals(&lt;span class="str"&gt;"Para"&lt;/span&gt;))
        resultado.Add(cliente);

    &lt;span class="kwrd"&gt;return&lt;/span&gt; resultado;
}&lt;/pre&gt;
&lt;style type="text/css"&gt;&lt;![CDATA[
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }]]&gt;&lt;/style&gt;

&lt;p&gt;No dia seguinte preciso filtrar todos os clientes cujo nome começa com “P”. Posso utilizar a velha técnica de reuso de código conhecida como Ctrl+C, Ctrl+V. Todavia, estamos aqui para escrever código de qualidade, então esta opção não é aceitável. Para tornar este método reutilizável, preciso identificar o que pode ser reaproveitado e o que deve ser mutável.&lt;/p&gt;

&lt;p&gt;&lt;img title="Figura2" style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="196" alt="Figura2" src="http://eduardomiranda.net/blogs/images/eduardomiranda_net/blogs/dotnet/WindowsLiveWriter/BrincandocomC_DBEC/Figura2_5.gif" width="516" align="left" border="0" /&gt; &lt;/p&gt;

&lt;p&gt; &lt;/p&gt;

&lt;p&gt; &lt;/p&gt;

&lt;p&gt; &lt;/p&gt;

&lt;p&gt; &lt;/p&gt;

&lt;p&gt; &lt;/p&gt;

&lt;p&gt; &lt;/p&gt;

&lt;p&gt;Tudo que está rachurado é código necessário e repetido para qualquer filtro sobre um cliente. É preciso criar uma nova lista de clientes, iterar sobre a lista atual, adicionar os escolhidos na nova lista e retorná-la ao final. O único trecho que muda é o algoritmo de decisão se o cliente entra ou não na nova lista.&lt;/p&gt;

&lt;p&gt;O problema é que este algoritmo é uma função, que retorna um boleano, ou seja, preciso de uma função high-order, que recebe como parâmetro uma função. A forma de fazer isto em C# é utilizando delegate. Delegates permitem a passagem de uma função, com uma determinada assinatura, para outra função. Então vou: Abstrair a lógica de filtro para uma nova função, chamada FiltraClientes, que recebe a lista de clientes e o delegate da função de decide se o cliente é filtrado ou não; Criar este delegate, que recebe um cliente e retorna um boleano; e abstrair a lógica de filtro em um método que segue a assinatura deste delegate. Veja como ficou:&lt;/p&gt;

&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;delegate&lt;/span&gt; &lt;span class="kwrd"&gt;bool&lt;/span&gt; Predicate(Cliente cliente);

&lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;bool&lt;/span&gt; ClienteResideNoPara(Cliente cliente)
{
    &lt;span class="kwrd"&gt;return&lt;/span&gt; cliente.Estado.Equals(&lt;span class="str"&gt;"Pará"&lt;/span&gt;);
}

&lt;span class="kwrd"&gt;private&lt;/span&gt; List&amp;lt;Cliente&amp;gt; GetClientesDoPara(List&amp;lt;Cliente&amp;gt; clientes)
{
    &lt;span class="kwrd"&gt;return&lt;/span&gt; FilterClientes(clientes, ClienteResideNoPara);
}

&lt;span class="kwrd"&gt;private&lt;/span&gt; List&amp;lt;Cliente&amp;gt; FilterClientes(List&amp;lt;Cliente&amp;gt; clientes, Predicate filter)
{
    List&amp;lt;Cliente&amp;gt; resultado = &lt;span class="kwrd"&gt;new&lt;/span&gt; List&amp;lt;Cliente&amp;gt;();

    &lt;span class="kwrd"&gt;foreach&lt;/span&gt; (Cliente cliente &lt;span class="kwrd"&gt;in&lt;/span&gt; clientes)
        &lt;span class="kwrd"&gt;if&lt;/span&gt; (filter(cliente))
            resultado.Add(cliente);

    &lt;span class="kwrd"&gt;return&lt;/span&gt; resultado;
}&lt;/pre&gt;
&lt;style type="text/css"&gt;&lt;![CDATA[
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }]]&gt;&lt;/style&gt;

&lt;p&gt;Para finalizar utilizo o generics e a interface IEnumerable para tornar tudo independente do tipo da coleção e do objeto, ou seja filtro qualquer coleção de objetos, não interessa o seu tipo.&lt;/p&gt;

&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;delegate&lt;/span&gt; &lt;span class="kwrd"&gt;bool&lt;/span&gt; Predicate&amp;lt;T&amp;gt;(T item);

&lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;bool&lt;/span&gt; ClienteResideNoPara(Cliente cliente)
{
    &lt;span class="kwrd"&gt;return&lt;/span&gt; cliente.Estado.Equals(&lt;span class="str"&gt;"Pará"&lt;/span&gt;);
}

&lt;span class="kwrd"&gt;private&lt;/span&gt; List&amp;lt;Cliente&amp;gt; GetClientesDoPara(List&amp;lt;Cliente&amp;gt; clientes)
{
    &lt;span class="kwrd"&gt;return&lt;/span&gt; (List&amp;lt;Cliente&amp;gt;) Filter(clientes, ClienteResideNoPara);
}

&lt;span class="kwrd"&gt;private&lt;/span&gt; IEnumerable&amp;lt;T&amp;gt; Filter&amp;lt;T&amp;gt;(IEnumerable&amp;lt;T&amp;gt; collection, Predicate&amp;lt;T&amp;gt; filter)
{
    List&amp;lt;T&amp;gt; resultado = &lt;span class="kwrd"&gt;new&lt;/span&gt; List&amp;lt;T&amp;gt;();

    &lt;span class="kwrd"&gt;foreach&lt;/span&gt; (T item &lt;span class="kwrd"&gt;in&lt;/span&gt; collection)
        &lt;span class="kwrd"&gt;if&lt;/span&gt; (filter(item))
            resultado.Add(item);

    &lt;span class="kwrd"&gt;return&lt;/span&gt; resultado;
}&lt;/pre&gt;
&lt;style type="text/css"&gt;&lt;![CDATA[
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }]]&gt;&lt;/style&gt;

&lt;p&gt;Na próxima vou fazer o mesmo exercício para o Map. Aguardem&lt;/p&gt;&lt;img src="http://eduardomiranda.net/blogs/dotnet/aggbug/256.aspx" width="1" height="1" /&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/EduardoMirandaDotNet?a=smDDAdFTQTo:Kie_WOLS11s:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/EduardoMirandaDotNet?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/EduardoMirandaDotNet?a=smDDAdFTQTo:Kie_WOLS11s:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/EduardoMirandaDotNet?i=smDDAdFTQTo:Kie_WOLS11s:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/EduardoMirandaDotNet?a=smDDAdFTQTo:Kie_WOLS11s:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/EduardoMirandaDotNet?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/EduardoMirandaDotNet?a=smDDAdFTQTo:Kie_WOLS11s:bcOpcFrp8Mo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/EduardoMirandaDotNet?d=bcOpcFrp8Mo" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/EduardoMirandaDotNet/~4/smDDAdFTQTo" height="1" width="1"/&gt;</description>
            <dc:creator>Eduardo Miranda</dc:creator>
            <guid isPermaLink="false">http://eduardomiranda.net/blogs/dotnet/archive/2008/08/14/brincando-com-c.aspx</guid>
            <pubDate>Thu, 14 Aug 2008 18:38:19 GMT</pubDate>
            <wfw:comment>http://eduardomiranda.net/blogs/dotnet/comments/256.aspx</wfw:comment>
            <comments>http://eduardomiranda.net/blogs/dotnet/archive/2008/08/14/brincando-com-c.aspx#feedback</comments>
            <slash:comments>2</slash:comments>
            <wfw:commentRss>http://eduardomiranda.net/blogs/dotnet/comments/commentRss/256.aspx</wfw:commentRss>
        <feedburner:origLink>http://eduardomiranda.net/blogs/dotnet/archive/2008/08/14/brincando-com-c.aspx</feedburner:origLink></item>
        <item>
            <title>Resumo da semana &amp;ndash; 12/05/2008</title>
            <category>Notícias</category>
            <link>http://feedproxy.google.com/~r/EduardoMirandaDotNet/~3/thbHEf7KAd4/resumo-da-semana-ndash-12052008.aspx</link>
            <description>&lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Controle de versão / ALM&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Se você é, ou deseja ser, usuário de subversion, este é um &lt;a href="http://weblogs.asp.net/bsimser/archive/2008/05/06/day-to-day-with-subversion.aspx"&gt;artigo interessante&lt;/a&gt; para atividades não tão básicas, porém desejadas.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://www.infoq.com/articles/agile-version-control"&gt;Este artigo&lt;/a&gt; é genérico, sobre controle de versão. Um ótimo documento de como organizar e gerenciar suas branches.&lt;/p&gt;  &lt;p&gt;O Time DevDiv é responsável pelo Team Foundation Server e com certeza seu maior cliente. Uma série de posts está apresentando como eles utilizam o TFS internamente. Por enquanto o foco é gerência de projetos, através do issue tracking. Este é o &lt;a href="http://blogs.msdn.com/teams_wit_tools/archive/2008/05/06/how-microsoft-devdiv-uses-tfs-chapter-6-tracking-multiple-projects.aspx"&gt;último post&lt;/a&gt;, mas vale ler todos.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Arquitetura&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Mr. I.M. Right &lt;a href="http://blogs.msdn.com/eric_brechner/archive/2008/05/01/crash-dummies-resilience.aspx"&gt;discorre sobre resilência&lt;/a&gt; de um aplicativo através de sua capacidade de auto-regeneração. Parece viagem, mas não é.&lt;/p&gt;&lt;img src="http://eduardomiranda.net/blogs/dotnet/aggbug/255.aspx" width="1" height="1" /&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/EduardoMirandaDotNet?a=thbHEf7KAd4:LtBoOin5Pkk:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/EduardoMirandaDotNet?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/EduardoMirandaDotNet?a=thbHEf7KAd4:LtBoOin5Pkk:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/EduardoMirandaDotNet?i=thbHEf7KAd4:LtBoOin5Pkk:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/EduardoMirandaDotNet?a=thbHEf7KAd4:LtBoOin5Pkk:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/EduardoMirandaDotNet?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/EduardoMirandaDotNet?a=thbHEf7KAd4:LtBoOin5Pkk:bcOpcFrp8Mo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/EduardoMirandaDotNet?d=bcOpcFrp8Mo" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/EduardoMirandaDotNet/~4/thbHEf7KAd4" height="1" width="1"/&gt;</description>
            <dc:creator>Eduardo Miranda</dc:creator>
            <guid isPermaLink="false">http://eduardomiranda.net/blogs/dotnet/archive/2008/05/12/resumo-da-semana-ndash-12052008.aspx</guid>
            <pubDate>Mon, 12 May 2008 21:14:37 GMT</pubDate>
            <wfw:comment>http://eduardomiranda.net/blogs/dotnet/comments/255.aspx</wfw:comment>
            <comments>http://eduardomiranda.net/blogs/dotnet/archive/2008/05/12/resumo-da-semana-ndash-12052008.aspx#feedback</comments>
            <slash:comments>1</slash:comments>
            <wfw:commentRss>http://eduardomiranda.net/blogs/dotnet/comments/commentRss/255.aspx</wfw:commentRss>
        <feedburner:origLink>http://eduardomiranda.net/blogs/dotnet/archive/2008/05/12/resumo-da-semana-ndash-12052008.aspx</feedburner:origLink></item>
    </channel>
</rss>
