<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-6506598722551528828</id><updated>2011-04-21T11:17:57.982-07:00</updated><category term='.net c# 4.0 covariância visual studio 2010'/><title type='text'>André Bires</title><subtitle type='html'>Pesquisando e aprendendo sobre .NET, WCF, C#, Visual Studio, SQL Server, WPF e WWF.</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://andrebires.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6506598722551528828/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://andrebires.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>André Bires</name><uri>http://www.blogger.com/profile/11852017234829472094</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>1</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-6506598722551528828.post-5810347918247124938</id><published>2009-05-20T04:38:00.000-07:00</published><updated>2009-05-20T06:42:56.821-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='.net c# 4.0 covariância visual studio 2010'/><title type='text'>Novidades do C# 4.0</title><content type='html'>Estava vendo este artigo (&lt;a href="http://software.intel.com/en-us/blogs/2009/03/30/the-c-programming-language-version-40/"&gt;http://software.intel.com/en-us/blogs/2009/03/30/the-c-programming-language-version-40/&lt;/a&gt;) que mostra as novidades que serão implementadas no C# 4.0, que chegará em 2010 juntamente com a nova versão do .NET e do Visual Studio.&lt;br /&gt;&lt;br /&gt;A primeira delas é a criação de tipos dinâmicos, declarados através da keyword dynamic. Objetos deste tipo permite invocarmos seus métodos diretamente sem a necessidade de sabermos o seu tipo, ou seja, como se fosse um object onde teríamos que usar reflection para executar um método. Por exemplo, suponhamos que tenhamos um método GetCalculator() que nos retorna um object, sendo que este object pode ser um COM+ ou um tipo carregado de um assembly .NET qualquer. Sabemos que este object possui um método Add(int a, int b) que retorna um inteiro. Atualmente para executarmos este método, precisamos utilizar reflection. O código ficaria da seguinte forma:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt;         object calculator = GetCalculator();&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;         Type type = calculator.GetType();&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt; &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;         int result = (int)type.InvokeMember("Add",&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;                                    BindingFlags.InvokeMethod,&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;                                             &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt;                                    &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt;null,&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt;                                    &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt;                                             calculator,&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt;                                    &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt;                                             new object[] { 10, 20 });&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Já utilizando o dynamic, isto poderia ser feito da seguinte forma:&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt; &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;         dynamic calculator = GetCalculator();&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;         int result = calculator.Add(10, 20);&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Claro que este tipo de implementação tem seus problemas, principalmente em relação a performance por utilizar reflection e para a verificação do código, pois os erros só são descobertos em tempo de execução. Mas de qualquer jeito, é uma forma mais elegante de se escrever código dinâmico pois não usa uma string para invocar o método.&lt;br /&gt;&lt;br /&gt;Outra novidade interessante são os optional parameters que permite que valores default sejam atribuídos a parâmetros dos métodos, de forma a criar overloads automaticamente sem a necessidade de explicitar cada assinatura do overload do método. Ou seja, ao invés de fazer isso:&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;        public int ExecuteOperation(Operation operation, int a)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;        {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;            return ExecuteOperation(operation, a, 0, 0);&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;        }&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt; &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;        public int ExecuteOperation(Operation operation, int a, int b)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;        {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;            return ExecuteOperation(operation, a, b, 0);&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;        }&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt; &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;        public int ExecuteOperation(Operation operation, int a, int b, int c)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;        {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;            // TODO: Implementação do método&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;            throw new NotImplementedException();&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;        }&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;br /&gt;O C# 4.0 nos permite fazer isso:&lt;br /&gt;&lt;br /&gt;&lt;span style=";font-family:courier new;font-size:85%;"  &gt;        public int ExecuteOperation(Operation operation, int a, int b = 0, int c = 0)&lt;br /&gt;     {&lt;br /&gt;         // TODO: Implementação do método&lt;br /&gt;         throw new NotImplementedException();&lt;br /&gt;     }&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;E caso o programador queira, no exemplo acima, não especificar o valor de b mas especificar o de c, ele invoca o método da seguinte forma:&lt;br /&gt;&lt;br /&gt;&lt;span style=";font-family:courier new;font-size:85%;"  &gt;        calculator.ExecuteOperation(Operation.Add, 1, c: 3);&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;O último recurso é a suporte da linguagem para a covariância e contravariância para generics. Códigos como do exemplo abaixo serão possíveis:&lt;br /&gt;&lt;br /&gt;&lt;span style=";font-family:courier new;font-size:85%;"  &gt;        IEnumerable&amp;lt;string&amp;gt; names = new List&amp;lt;string&amp;gt;();&lt;br /&gt;IEnumerable&amp;lt;object&amp;gt; objects = names;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;No sentido inverso também será possível:&lt;br /&gt;&lt;br /&gt;&lt;span style=";font-family:courier new;font-size:85%;"  &gt;        IEnumerable&amp;lt;object&amp;gt; objects = new List&amp;lt;object&amp;gt;();&lt;br /&gt;IEnumerable&amp;lt;string&amp;gt; names = objects;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;Com isso, suponha que exista um método com a seguinte assinatura:&lt;br /&gt;&lt;br /&gt;&lt;span style=";font-family:courier new;font-size:85%;"  &gt;        public void Write(List&amp;lt;object&amp;gt; objects)&lt;br /&gt;     {&lt;br /&gt;         // TODO: Implementação do método&lt;br /&gt;     }&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Poderemos passar como parâmetro um objeto do tipo &lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt;List&amp;lt;string&amp;gt;.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Para isso tudo isso ser possível, é necessário especificar na classe genérica que a covariância e contravariância é possível, utilizando as keywords in e out, da seguinte forma:&lt;br /&gt;&lt;br /&gt;&lt;span style=";font-family:courier new;font-size:85%;"  &gt;        public interface IEnumerator&amp;lt;out T&amp;gt;&lt;br /&gt;     {&lt;br /&gt;         T Current { get; }&lt;br /&gt;         bool MoveNext();&lt;br /&gt;     }&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;Neste caso, a palavra out indica que é seguro receber um objeto mais especializado (string) e tratá-lo como menos especializado (object), pois neste caso a interface indica ações de somente leitura para T, tornando-a covariante. A contravariância é explicitada com a keyword in:&lt;br /&gt;&lt;br /&gt;&lt;span style=";font-family:courier new;font-size:85%;"  &gt;        public interface IComparer&amp;lt;int T&amp;gt;&lt;br /&gt;     {&lt;br /&gt;         int Compare(T x, T y);&lt;br /&gt;     }&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;Que afirma que é possivel receber como T um tipo menos especializado (object) e tratá-lo como mais especializado (string) como segurança, tornando a interface contravariante.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6506598722551528828-5810347918247124938?l=andrebires.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://andrebires.blogspot.com/feeds/5810347918247124938/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://andrebires.blogspot.com/2009/05/novidades-do-c-40.html#comment-form' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6506598722551528828/posts/default/5810347918247124938'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6506598722551528828/posts/default/5810347918247124938'/><link rel='alternate' type='text/html' href='http://andrebires.blogspot.com/2009/05/novidades-do-c-40.html' title='Novidades do C# 4.0'/><author><name>André Bires</name><uri>http://www.blogger.com/profile/11852017234829472094</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry></feed>
