<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>blog.caelum.com.br &#187; .net</title>
	<atom:link href="http://blog.caelum.com.br/tag/net/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.caelum.com.br</link>
	<description>blog dos desenvolvedores da Caelum</description>
	<lastBuildDate>Thu, 09 Feb 2012 13:04:59 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>RESTfulie com C# &#8211; O poder do dynamic</title>
		<link>http://blog.caelum.com.br/restfulie-com-csharp-o-poder-do-dynamic/</link>
		<comments>http://blog.caelum.com.br/restfulie-com-csharp-o-poder-do-dynamic/#comments</comments>
		<pubDate>Fri, 26 Feb 2010 09:10:23 +0000</pubDate>
		<dc:creator>Luiz Costa</dc:creator>
				<category><![CDATA[Arquitetura]]></category>
		<category><![CDATA[.net]]></category>
		<category><![CDATA[rest]]></category>
		<category><![CDATA[restful]]></category>
		<category><![CDATA[restfulie]]></category>
		<category><![CDATA[soa]]></category>
		<category><![CDATA[web services]]></category>

		<guid isPermaLink="false">http://blog.caelum.com.br/?p=2111</guid>
		<description><![CDATA[Há um mês lançamos uma versão inicial do projeto Restfulie para C#, projeto que tem ganhado bastante visibilidade.  Para deixa-lo tão fácil quanto a versão original em Ruby, utilizamos as novas características dinâmicas da versão 4.0 do C#, alterando a estrutura de objetos em tempo de execução. Algumas pessoas acham esse recurso perigoso demais, outras acham a escolha certa. <a href="http://blog.caelum.com.br/restfulie-com-csharp-o-poder-do-dynamic/#more-2111'" class="more-link">more &#187;</a>]]></description>
			<content:encoded><![CDATA[<p>Há um mês lançamos uma versão inicial do projeto <a id="hkwe" title="Restfulie" href="http://restfulie.caelumobjects.com/">Restfulie</a> para C#, <a href="http://www.infoq.com/interviews/Restfulie">projeto que tem ganhado bastante visibilidade</a>.  Para deixa-lo tão fácil quanto a <a id="zzom" title="versão original" href="http://restfulie.caelumobjects.com/ruby">versão original em Ruby</a>, utilizamos as novas características dinâmicas da versão 4.0 do C#, alterando a estrutura de objetos em tempo de execução. Algumas pessoas acham <a id="ukkx" title="isso perigoso demais" href="http://www.infoq.com/news/2009/11/Compromise-Dynamic-C-Sharp">esse recurso perigoso demais</a>, <a id="wozb" title="outras acham muito poderoso." href="http://are%20dynamic%20languages%20going%20to%20replace%20static%20languages/?">outras acham a escolha certa</a>. </p>
<p>Para enxergar o uso da nova palavra chave <code>dynamic</code>, consideremos um recurso REST que representa um pedido com sua representação em XML como a que segue:</p>
<pre class="brush: xml; title: ; notranslate">
&lt;pedido&gt;
  &lt;data&gt;26/12/2009 11:40&lt;/data&gt;
  &lt;total&gt;300.00&lt;/total&gt;
  &lt;atom:link rel=”refresh” href=”http://www.caelum.com.br/pedidos/1″ xmlns:atom=”http://www.w3.org/2005/Atom”/&gt;
  &lt;atom:link rel=”update” href=”http://www.caelum.com.br/pedidos/1″ xmlns:atom=”…”/&gt;
  &lt;atom:link rel=”pagar” href=”http://www.caelum.com.br/pedidos’/1/pagar” xmlns:atom=”…”/&gt;
  &lt;atom:link rel=”excluir” href=”http://www.caelum.com.br/pedidos/1″ xmlns:atom=”…”/&gt;
  &lt;atom:link rel=”obterCliente” href=”http://www.caelum.com.br/pedidos/1/clientexmlns:atom=” xmlns:atom=”…”/&gt;
&lt;/pedido&gt;
</pre>
<p>É interessante notar que neste XML temos os dados (data, total) e temos ações que podem ser executadas sobre este recurso. Por exemplo, depois que obtivemos a representação deste recurso, é possível executar algumas ações, descritas através de links no próprio xml: <code>pagar</code>, <code>excluir</code>, <code>obterCliente</code>. Para obter a representação de um recurso no restfulie C#  fazemos da seguinte maneira:</p>
<pre class="brush: csharp; title: ; notranslate">
dynamic pedido =
  Restfulie.At(“www.caelum.com.br\pedidos\1”).Get();
</pre>
<p>Repare que o primeiro passo que fazemos ao declarar a variável pedido é ignorar o seu tipo.  Ou melhor, dizer explicitamente que ela é dinâmica, através do tipo <strong><a id="kqsw" title="dynamic" href="http://msdn.microsoft.com/en-us/library/dd264741%28VS.100%29.aspx">dynamic</a></strong>. Isso nos trás uma série de vantagens como, por exemplo, simplesmente acessar suas <a id="cvhs" title="properties" href="http://msdn.microsoft.com/en-us/library/x9fsa0sw.aspx">properties</a>:</p>
<pre class="brush: csharp; title: ; notranslate">
Console.WriteLine(string.Format(“A data do pedido é: {0}”, pedido.Data));
Console.WriteLine(string.Format(“O valor total do pedido é: {0}”, pedido.Total));
</pre>
<p>Além de podermos acessar suas properties, podemos também seguir os links que estão disponíveis na representação, utilizando invocações de métodos:</p>
<pre class="brush: csharp; title: ; notranslate">
pedido.Pagar();
pedido.Excluir();

dynamic cliente = pedido.obterCliente();
Console.WriteLine(string.Format(“Nome do cliente: {0}”, cliente.Nome));
</pre>
<p>Isso é bastante poderoso: perceba que do lado cliente não precisamos definir nada, apenas dizer que uma referência é dinâmica. Mas como esta mágica acontece com o C#?</p>
<p>Além de existir a palavra reservada <code>dynamic</code> existe uma classe <a id="gquj" title="DynamicObject" href="http://msdn.microsoft.com/en-us/library/system.dynamic.dynamicobject%28VS.100%29.aspx">DynamicObject</a> no C#. Diferente de Ruby, em C#, nem todos os objetos podem ser <a id="q8at" title="modificados em Runtime." href="http://dotnetslackers.com/articles/csharp/Dynamic-Binding-in-a-Static-Language-Part-1.aspx">modificados em Runtime.</a> Para que seja possível adicionar comportamento dinâmico em a um objeto, precisamos estender a classe <code>DynamicObject</code>.</p>
<p>Ao estender esta classe, ganhamos a oportunidade de alterar o comportamento do objeto. Quando fizermos então uma invocação a <code>pedido.Total</code>, o que de fato tem que ocorrer aqui? De acordo com o xml de representação do recurso, devemos obter o valor que está na tag &lt;Total&gt;.</p>
<p>Para implementar isso utilizamos um recurso bem parecido com o <a id="mvat" title="method_missing em Ruby" href="http://andersonleiteblog.wordpress.com/2010/02/10/metaprogramacao-method_missing/">method_missing em Ruby</a> e, de certa forma, como as dynamic proxies do Java (apesar destas precisarem de interfaces explícitas). Vejamos a classe <code>DynamicXmlResource</code>:</p>
<pre class="brush: csharp; title: ; notranslate">
class DynamicXmlResource : DynamicObject {
   private XElement xmlRepresentation;

   public override bool TryGetMember(GetMemberBinder binder,
             out object result) {
     //pseudo código que encontra a tag xml de acordo
     //com o nome da property informada
     object = XmlRepresentation.FindXMLTagWithName( binder.Name)
             .ReadTheValue()
     return result != null;
   }
}
</pre>
<p>Esta classe estende <code>DynamicObject</code> e tem um atributo que é a representação do recurso em XML (xmlRepresentation). O mais interessante é o método <code>TryGetMember</code> que  intercepta qualquer invocação a um <code>Get</code> de uma property e nos permite fazer o que for necessário. No nosso caso, o que é feito é buscar o valor da da property no xml, que nesse caso tem o nome igual  ao da tag do xml. Com isso, toda vez que fizermos <code>pedido.Total</code>, o que está acontecendo é a invocação de <code>TryGetMember</code> da classe <code>DynamicXmlResource</code>.</p>
<p>Da mesma forma que existe o método <code>TryGetMember</code>, existem outros que nos permitem alterar o comportamento do objeto. No nosso projeto, também fizemos o uso do <code>TryInvokeMember</code>:</p>
<pre class="brush: csharp; title: ; notranslate">
class DynamicXmlResource : DynamicObject {
  private XElement xmlRepresentation;

  public override bool TryGetMember(GetMemberBinder binder, out object result) {
    result = XmlRepresentation.FindXMLTagWithName(binder.Name).ReadTheValue()
    return result != null;
  }

  public override bool TryInvokeMember(InvokeMemberBinder binder,
        object[] args, out object result) {
    // pseudo código para pegar o link no xml a partir do nome do método
    object link = XmlRepresentation.FindRelAttributeWithName(Binder.Name).ReadTheLink();
    if (link == null)
      throw new ArgumentException
        (string.Format(&quot;There is not method defined with name:&quot;, binder.Name));

    // faz a chamada remota para o servidor através do link.
    HttpRemoteResponse response = 
      (HttpRemoteResponse) this.InvokeRemoteResource(value.ToString(), binder.Name);
    return result != null;
  }
}
</pre>
<p>Este método também é parecido com o <code>method_missing</code>, mas neste caso ele intercepta a chamada de um método. No caso do restfulie,  quando chamamos um método qualquer, o que ele faz é, procurar na representação XML e descobrir o link relacionado com o nome do método. Depois disso é só fazer uma requisição http. Novamente, quando fizermos a invocação <strong>pedido.Pagar()</strong>, ela será interceptada pelo <code>TryInvokeMember</code> e executará uma invocação remota para o Restfulie Server.</p>
<p>Utilizando estas características do C# conseguimos alcançar algo muito próximo do que se faz com o Restfulie Ruby, como comparamos a seguir. Em Ruby:</p>
<pre class="brush: ruby; title: ; notranslate">
pedido = Restfulie.at(“http://restfulie-test.heroku.com/orders/14”).get
puts pedido.customer-name
pedido.cancel
</pre>
<p>E, em C#, temos o código tão sucinto quanto:</p>
<pre class="brush: csharp; title: ; notranslate">
dynamic pedido = Restfulie.At(“http://restfulie-test.heroku.com/orders/14.xml”).Get();
Console.WriteLine(pedido.customer_name);
pedido.Cancel();
</pre>
<p>Uma das consequências da utilização de tipos dinâmicos é que perdemos as vantagens da fase da tipagem estática: não há code complete, e pode ser que a gente erre o nome de um membro, como <code>customer_name</code>, e só viremos a saber disso em tempo de execução. Nada que testes unitários bem colocados não resolvam. </p>
<p>Como podemos ver, a utilização de tipos dinâmicos facilita bastante a utilização da api do Restfulie, assim como diversos outros frameworks vem tirando vantagem com o auxílio desse recurso.</p>
<p>Reforçando a tendência, o Java também anda nesse caminho, com a <a id="usta" title="JSR 292" href="http://jcp.org/en/jsr/detail?id=292">JSR 292</a>, que melhora o suporte de linguagens dinâmicas na JVM. Em abril de 2003 Robert C. Martin escreveu o artigo &#8220;<a id="d-bs" title="Are Dynamic Languages Going to Replace Static Languages?&quot;" href="http://www.artima.com/weblogs/viewpost.jsp?thread=4639">As linguagens dinâmicas vão substituir as estáticas?&#8221;</a> e, no final deste artigo, ele faz seguinte pergunta: <em>Estaremos todos nós programando numa linguagem dinamicamente tipada em 2010?</em>. Isso não aconteceu, mas com certeza cada vez mais cenários de utilização estão surgindo, e a tendência é cada vez mais forte.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.caelum.com.br/restfulie-com-csharp-o-poder-do-dynamic/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Não posso descobrir nem instanciar tipos genéricos! Porque?</title>
		<link>http://blog.caelum.com.br/nao-posso-descobrir-nem-instanciar-tipos-genericos-porque/</link>
		<comments>http://blog.caelum.com.br/nao-posso-descobrir-nem-instanciar-tipos-genericos-porque/#comments</comments>
		<pubDate>Mon, 28 Apr 2008 23:38:45 +0000</pubDate>
		<dc:creator>Paulo Silveira</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[.net]]></category>
		<category><![CDATA[arrays]]></category>
		<category><![CDATA[erasure]]></category>
		<category><![CDATA[generics]]></category>
		<category><![CDATA[reflection]]></category>
		<category><![CDATA[reificação]]></category>
		<category><![CDATA[tipagem]]></category>
		<category><![CDATA[tipos]]></category>

		<guid isPermaLink="false">http://blog.caelum.com.br/2008/04/28/nao-posso-descobrir-nem-instanciar-tipos-genericos-porque/</guid>
		<description><![CDATA[São incontáveis os posts no GUJ com uma pergunta semelhante: &#8220;Posso extrair o nome de um tipo genérico?&#8220;, &#8220;Não consigo extrair tipo do genérico!&#8220;, &#8220;Utilizando generics para instanciar objetos&#8220;, entre outros. Curioso que esse tipo de pergunta tem aumentado muito nos últimos tempos, identificando um possível crescimento no uso do Java 5 em diante. Já <a href="http://blog.caelum.com.br/nao-posso-descobrir-nem-instanciar-tipos-genericos-porque/#more-208'" class="more-link">more &#187;</a>]]></description>
			<content:encoded><![CDATA[<p>São incontáveis os posts no GUJ com uma pergunta semelhante: &#8220;<a href="http://guj.com.br/java/87606-extrair-nome-do-tipo-generico">Posso extrair o nome de um tipo genérico?</a>&#8220;, &#8220;<a href="http://guj.com.br/java/87532-generics---nao-consigo-instanciar-o-tipo">Não consigo extrair tipo do genérico!</a>&#8220;, &#8220;<a href="http://www.guj.com.br/java/82372-utilizando-o-generics-para-instanciar-objetos">Utilizando generics para instanciar objetos</a>&#8220;, entre outros. Curioso que esse tipo de pergunta tem aumentado muito nos últimos tempos, identificando um possível crescimento no uso do Java 5 em diante. Já era a hora!</p>
<p>Eu já havia postado sobre isso quando falei de <a href="http://blog.caelum.com.br/2007/04/08/generics-inferencia-de-tipos-e-reificacao-no-java-7/">reificação de tipos parametrizados</a>, mas de uma maneira mais geral.</p>
<p>A questão básica é a seguinte: Se eu tenho um tipo genérico, que recebe um tipo parametrizado <code>T</code> como argumento, eu posso instanciar <code>T</code> de alguma forma?</p>
<p>Quem sabe tentar assim:</p>
<pre class="brush: java; title: ; notranslate">
class Dao&lt;T&gt; {
  public T cria() {
    return new T();
  }
}
</pre>
<p>Essa forma não funciona. Você não tem garantias sobre os construtores que o tipo <code>T</code> possui. E então se tentarmos assim:</p>
<pre class="brush: java; title: ; notranslate">
class Dao&lt;T&gt; {
  public T cria() {
    return T.class.newInstance();
  }
}
</pre>
<p>Aqui a sintaxe até poderia ser possível, mas infelizmente o java não sabe quem é <code>T</code> nem mesmo em tempo de execução. Nem mesmo com manipulação de bytecode ou qualquer outro recurso. Isso porque o compilador &#8220;apaga&#8221; essa informação depois de utilizada: é a tal da mal falada <strong><a href="http://download.oracle.com/javase/tutorial/java/generics/erasure.html">erasure</a></strong>. </p>
<p><strong>Qual seria a vantagem da erasure?</strong></p>
<p>Antes de mais nada: erasure não serve para poder rodar código do Java 5 em VMs Java 1.4 ou menor! Não é esse o objetivo.</p>
<p>Quando a JSR14 do generics foi proposta, eles queriam mais que compatibilidade para trás em relação a compilação, eles queriam também a possibilidade de migrar o código antigo para poder usar código novo: uma <code>ArrayList</code> precisa poder ser passada como argumento para alguém que receba <code>List&lt;QualquerClasse&gt;</code> como argumento!  </p>
<p>Para ilustrar a situação, imagine que eu tenho uma aplicação grande <strong>X</strong> que usasse a classe  <code>ArrayList</code> em muitos lugares (como a grande maioria das aplicações). Essa aplicação <strong>X</strong> usa a biblioteca <strong>B</strong>, que recebe <code>List</code> como argumento em muitos de seus métodos. Se um dia a bibioteca <strong>B</strong> passasse a usar <code>List</code> genérica, gostaríamos que a aplicação <strong>X</strong> atualizasse <strong>B</strong> sem maiores problemas: sem precisar recompilar nada, nem trocar nada no código fonte. O <a href="http://gafter.blogspot.com/2004/09/puzzling-through-erasure-answer.html">Neal Gafter escreveu muito sobre isso</a> pouco antes da release do Java 5, dada as inúmeras críticas que eles estavam recebendo.</p>
<p>Se o Java tivesse optado por outra maneira de implementar generics, teria ou quebrado compatibilidade com o uso não genérico de classes que viraram genéricas, ou precisaria criar classes paralelas as atuais, praticamente copiadas e coladas, só que estas genéricas, tornando as antigas deprecated ou legadas.</p>
<p><strong>Como o .NET resolveu o mesmo problema?</strong></p>
<p>O .NET seguiu essa segunda forma, e criou uma hierarquia quase que paralela de coleções dentro do name space <code>System.Collections.Generic</code>.</p>
<p>A <a href="http://msdn2.microsoft.com/en-us/library/system.collections.ilist.aspx">IList</a> é a interface que define as operações em uma lista não genérica, e a <a href="http://msdn2.microsoft.com/en-us/library/system.collections.arraylist.aspx">ArrayList</a> é sua implementação mais comumente usada. Quando entrou generics no .NET eles criaram uma outra interface para a lista, com mesmo nome, só que genérica: a <a href="http://msdn2.microsoft.com/en-us/library/5y536ey6.aspx">IList&lt;T&gt;</a>.</p>
<p>A classe <a href="http://msdn2.microsoft.com/en-us/library/6sh2ey19.aspx">List</a> já é a implementação da interface genérica, e é ela quem você vai usar em vez de <code>ArrayList</code>. Ela possui uma definição bem estranha:</p>
<pre class="brush: csharp; title: ; notranslate">
public class List : IList, ICollection, IEnumerable, IList, ICollection, IEnumerable
</pre>
<p>Ela implementa tanto a lista genérica como a não genérica. O .NET tem um recurso que nós não temos, que faz com que apesar dessa lista também implementar a interface não genérica, você só consegue invocar os métodos não genéricos (que trabalham com <code>Object</code>) se estiver se referenciando a ela explicitamente como uma lista não genérica, como o código abaixo:</p>
<pre class="brush: csharp; title: ; notranslate">
IList x = new List&lt;String&gt;();
x.Add(2);
</pre>
<p>Apesar desse código compilar, no .NET temos essa informação dos tipos genéricos em tempo de execução, o que fará gerar uma exceção:</p>
<p><code>System.ArgumentException: The value "2" is not of type "System.String" e cannot be used in this generic collection<br />
</code></p>
<p>No Java teríamos apenas um <em>unchecked warning</em> na linha da declaração da referência, e uma possível <code>ClassCastException</code> mais a frente no código.</p>
<p>Aqui a vantagem é você poder passar uma <code>List</code> genérica para um código .NET antigo, que recebe como argumento uma <code>IList</code> não genérica. Além disso, no .NET você pode sim descobrir quem é <code>T</code> em tempo de execução:</p>
<pre class="brush: csharp; title: ; notranslate">
class ClasseGenerica&lt;T&gt; {
  void metodo() {  Console.WriteLine(typeof(T)); }
}
</pre>
<p><strong>Em resumo</strong>: o sistema de generics do .NET é realmente seguro, não temos como burlá-lo através de <em>unchecked casts</em>, como ocorre em Java. O Java novamente sacrificou alguns recursos interessantes em favor a compatibilidade de versões e interoperabilidade entre classes genéricas e as não genéricas já existentes. Cada um com sua vantagem. Como citei no outro artigo, existem algumas idéias de <a href="http://gafter.blogspot.com/2006/11/reified-generics-for-java.html">dar suporte a tipos genéricos reificados no Java</a>, ao mesmo tempo que outros ficariam ainda com a erasure, sendo que você pode escolher qual o que te agrada para aquela classe genérica em particular. Talvez ter as duas opções adicione ainda mais complexidade a tipagem genérica do Java, mas eu particularmente gosto da idéia.</p>
<p>Mais uma vez um post que era para ser sucinto ficou longo. Agradeço ao Rafael Steil e Rodrigo Kumpera pela colaboração, e ao Lucas Cavalcanti e Guilherme Moreira pedindo para que fosse elaborado um post mais completo sobre esse assunto tão pertinente.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.caelum.com.br/nao-posso-descobrir-nem-instanciar-tipos-genericos-porque/feed/</wfw:commentRss>
		<slash:comments>16</slash:comments>
		</item>
	</channel>
</rss>

