MCTS em .Net 2.0 Windows-Based Client Development

5/8/2008 6:15:00 PM By Felipe Pessoto

Hoje(dia 7) fiz o exame 70-526 pra concluir o MCTS que é composto de um exame sobre o .Net Framework, o 70-536(Application Development Foundation) que fiz ano passado e um eletivo que pode ser pra aplicações Windows, Web ou Distributed.

O 70-526 é o Windows-Based Client Development, e agora sim ganhei o título de MCTS. Fiz 820 pontos de 1000, sendo que pra passar você precisa de pelo menos 700.

O próximo passo é o MCPD em Designing and Developing Windows®-Based Applications Using the Microsoft® .NET Framework, exame 70-548.

Em agosto deve sair os novos exames pra VS2008, os MCPD vão poder fazer uma prova de UPGRADE, acho que vou seguir esse caminho, tentando tirar o MCPD em .Net2.0 e depois fazer o exame de atualização.

MSDN Magazine - Março e Abril 2008

5/8/2008 6:04:00 PM By Felipe Pessoto

Está disponível as edições de Março e Abril da MSDN Magazine:

ASP.NET MVC: Building Web Apps without Web Forms
Chris Tavares explains how the ASP.NET MVC Framework's Model View Controller pattern helps you build flexible, easily tested Web applications. Chris Tavares

Loosen Up: Tame Your Software Dependencies for More Flexible Apps
James Kovacs explains the dark side of tightly coupled architectures, why they're hard to test and how they limit adaptation. He then proposes a number of solutions. James Kovacs

CI Server: Redefine Your Build Process with Continuous Integration
Jay Flowers demonstrates how to set up and use a Continuous Integration server using both discrete tools and the more comprehensive CI Factory solution. Jay Flowers

Performance: Find Application Bottlenecks with Visual Studio Profiler
We will introduce you to the Visual Studio Profiler by walking through a sample performance investigation, pinpointing code inefficiencies in some sample applications. Hari Pulapaka and Boris Vidolov

Office Development: OBA Solution Patterns In The Real World
OBA solution patterns help architects and developers build Office Business Applications (OBAs). This article introduces the seven core OBA solution patterns and applies one to a real-world problem. Steve Fox

Download Março

Talk Back: Voice Response Workflows with Speech Server 2007
Speech Server 2007 lets you create sophisticated voice-response applications with Microsoft .NET Framework and Visual Studio tool integration. Here’s how. Michael Dunn

Performance: Scaling Strategies for ASP.NET Applications
Performance problems can creep into your Web app as it scales up, and when they do, you need to find the causes and the best strategies to address them. Richard Campbell and Kent Alstad

Silverlight: Building Advanced 3D Animations with Silverlight 2.0
Animating with Silverlight is easier than you think. Here we create a 3D app that folds a polyhedron using XAML, C#, and by emulating the DirectX math libraries. Declan Brennan

Interview++: Bjarne Stroustrup on the Evolution of Languages
Howard Dierking talks to the inventor of C++, Bjarne Stroustrup, about language zealots, the evolution of programming, and what’s in the future of programming. Howard Dierking

Office Development: Manage Metadata with Document Information Panels
Here the author uses Document Information Panels in the Microsoft 2007 Office system to manipulate metadata from Office docs for better discovery and management. Ashish Ghoda

Download Abril

Covariância e Contravariância em C#, Parte Cinco: Contravariância Dupla

4/25/2008 12:14:00 PM By Felipe Pessoto

Na parte quatro da série, falamos sobre como poderiamos ter um tipo de delegate que aceitaria ter valores covariantes no seu tipo de retorno e contravariantes no tipo recebido por argumento. Por exemplo, nós podemos ter um delegate action contravariante:

delegate void Action< -A > (A a);

e então temos

Action<Animal> action1 = (Animal a)=>{ Console.WriteLine(a.NomeLatin); };
Action<Girafa> action2 = action1;

Porque o invocador do action2 irá sempre passar algo que o action1 possa manipular.

Baseado no que vimos até agora no que diz respeito à variância concluimos que "o que está entrando deve ser contravariante, o que sai deve ser variante". Embora pareça que este seria um uso comum de variância que deveria ser implementada numa futura versão do C#, a realidade é um pouco mais complicada. Há uma situação onde é válido usar um argumento covariante como parâmetro de um delegate.

Suponha que você queira criar uma programação funcional de "ordem maior". Por exemplo, talvez você queira definir uma meta-ação – um delegate que recebe actions e faz alguma coisa com eles:

delegate void Meta<A>(Action<A> action);

Por exemplo:

Meta<Mamifero> meta1 = (Action<Mamifero> action)=>{action(new Girafa());};

// A próxima linha é válida porque Action<Animal> é menor que Action<Mamifero>;
// lembrando que Action é contravariante
meta1(action1); 

Então este Meta recebe um Action de Mamiferos, ou o action1 acima, o qual exibe o nome em Latin de qualquer Animal, o que quer dizer que pode ser usado para os Mamifero – e então invoca aquela action usando o new Girafa.

É evidente que o parâmetro de tipo A é usado em uma posição de entrada na definição de Meta<A>, então nós devemos ser capazes de usar contravariancia, certo? Suponha que sim. Isso significa que essa atribuição seria válida:

Meta<Tigre> meta2 = meta1; // deve ser válida se Meta é contraviante no parâmetro

Mas isso significa que isso seria válido:

Action<Tigre> action3 = Tigre=>{ Tigre.Rosnar(); };
meta2(action3);

Seguindo a lógica você verá que no final acabamos chamando (new Girafa()).Rosnar(), o qual claramente viola ambas as regras: do sistema e da natureza. Pode ser um pouco complicado até entender toda a lógica, mas escrevendo o código pode ajudar:

static void Main(string[] args)
        {
            Action<int> a;
 
            Action<Animal> action1 = metodo;
            Action<Girafa> action2 = action1;
 
            Meta<Mamifero> meta1 = metodo2;
 
            meta1(action1);
 
 
            Meta<Tigre> meta2 = meta1;
            Action<Tigre> action3 = metodo3;
            meta2(action3);
 
            Meta<Animal> meta3 = meta1;
 
 
        }
 
        static void metodo3(Tigre Tigre)
        {
            Tigre.Rosnar();
        }
 
        static void metodo2(Action<Mamifero> action)
        {
            action(new Girafa());
        }
 
        static void metodo(Animal a)
        {
            Console.WriteLine(a.NomeLatin);
        }
 
        public delegate void Meta<A>(Action<A> action);

No final do Main, você pode ver que o meta2 é igual ao meta1. O meta1 chama o método 2. O método 2 vai chamar o action passado(no caso o action3 que chama o metodo3) passando um new Girafa() como parâmetro. Neste momento que acontece a inconsistência. Pois estamos chamando o método3 passando uma Girafa, e o método3 iria chamar o método new Girafa()).Rosnar().

Então Meta<A> não pode ser contravariante em A. No entanto ele pode ser covariante:

Meta<Animal> meta3 = meta1; // válido se Meta for covariante

Agora tudo funciona. meta3 recebe um Action sobre Animals e então passa um Girafa para a Action.

Contravariância é complicado. O fato de se inverter o maior/menor relacionamento entre tipos diz que um tipo de parâmetro usado em uma posição de "contravariância dupla" (sendo uma entrada de Action, que é em si uma entrada de Meta) se torna covariante. O segundo desfaz a primeira inversão.

No próximo artigo deixaremos os delegates pra trás e falaremos sobre variância nas interfaces.

Chamar métodos static por tipo variável é ilegal - Parte III

4/17/2008 1:12:00 PM By Felipe Pessoto

Considere agora o método não-static e não-virtual:

public class C { public void M() { /*blablabla*/ } }
public class D : C { public new void M() { /*blablabla*/ } }
public class E<T> where T : C { public static void N(T t) { t.M(); } }

Nesse contexto, uma das seguintes afirmações é verdadeira:

1) Isto é inválido.
2) E<T>.N chama C.M não importa o que T é.
3) E<C>.N chama C.M, mas E<D>.N chama D.M.

Como temos discutido, para métodos static escolhemos a opção 1. Mas com métodos por instância, nós escolhemos a 2! A maioria das pessoas acharia que o método mais derivado(opção 3) seria chamado, mas não. Por quê? Porque temos que considerar que poderíamos ter: public static void N(C t) { t.M(); } o que nos faz esperar que o método menos derivado seja sempre chamado, desde que ele não seja virtual.

Por que não a opção 3? Novamente, tem a ver com análise estática. É que na realidade o que temos em ambos os casos, static e instanciados, C.M e D.M são métodos diferentes. O "new" solicita que eles sejam dois métodos diferentes que somente compartilham o mesmo nome. Você pode pensar em cada método como se ele ocupasse uma "vaga" no objeto, tanto em static como instanciado, nós definimos duas vagas, não uma. No caso do virtual e override então nós teríamos apenas uma vaga, e o conteúdo da vaga seria determinado em tempo de execução. Mas no caso não-virtual há duas vagas diferentes.

Quando o compilador gera o código generic, ele "calcula" todas as vagas em tempo de compilação. O jitter não as altera. Na verdade, o jitter não saberia como! O jitter não tem idéia que D.M tem qualquer coisa a ver com C.M. Novamente, eles são métodos totalmente diferentes que somente coincidentemente compartilham o mesmo nome. Eles têm vagas diferentes então são métodos diferentes.

Disponível ASP.NET Dynamic Data Preview

4/10/2008 12:07:00 PM By Felipe Pessoto

A meses atrás foi liberado um Preview do ASP.NET 3.5 Extensions que continha novas funcionalidades que estão por vir este ano (incluindo melhorias no ASP.NET AJAX, ASP.NET MVC, Suporte ao ASP.NET Silverlight e ASP.NET Dynamic Data).

O ASP.NET Dynamic Data adicionou várias novas funcionalidades que permitem que você construa rapidamente uma página de acesso a dados que funcionam com LINQ to SQL ou LINQ to Entities. ASP.NET Dynamic Data permite que você automaticamente tenha uma página totalmente funcional de entrada de dados e relatórios que são dinamicamente construídas a partir dos meta-dados do seu modelo ORM. Além disso, você pode opcionalmente sobrescrever e customizar qualquer um dos templates usando HTML ou o código que você quiser, dando um controle total ao desenvolvedor.

ASP.NET Dynamic Data Preview

Hoje foi liberado uma atualização do ASP.NET Dynamic Data Preview. Para saber mais e fazer o download clique aqui.

Este novo dynamic data preview agora funciona com os controles de dados padrão do ASP.NET (GridView, ListView, FormView, DetailsView, etc). O suporte ao Dynamic Data permite que esses controles possam manipular automaticamente relacionamentos com chave-estrangeira. Por exemplo, um gridview irá automaticamente mostrar o nome do registro na coluna de chave estrangeira em vez do código dela:

 

O novo dynamic data também suporta validações automáticas (tanto no lado cliente quanto no servidor) levando em consideração as constraints que você tem no seu modelo de dados. Por exemplo, se uma coluna no banco de dados é limitada em 50 caracteres, e está marcada como non-nullable, controles de validação apropriados serão aplicados à página para garantir que essas regras serão seguidas. Se você mudar as constraints dentro das suas classes LINQ to SQL ou LINQ to Entities, a interface gráfica irá automaticamente fazer essas mudanças na próxima vez que for chamada, para garantir que as novas constraints serão obedecidas.

Todas as funcionalidades acima estarão presentes para o LINQ to SQL e LINQ to Entities.


Visual Studio Dynamic Data Project Wizard

Outra novidade foi adicionada ao ASP.NET Dynamic Data, o "Time de Ferramentas Web do VS" também terminou um primeiro preview de um novo assistente para projetos usando dynamic data que permite criar rapidamente um site para manipular dados. O assistente permite que você selecione um banco de dados, e então as tabelas, views e sprocs que você deseja construir no seu modelo LINQ to SQL:



Depois de criar um modelo de dados, o assistente deixa você escolher facilmente o template das páginas para manipular os dados:



Você pode então escolher qual tipo de interface é suportada em cada página: