Pesquisar

6 de dez de 2008

ConquerMemory Tool 3.26 for Conquer 5079 (MultiClient)

English:

Working on patch 5079

Multi Client

You Need .Net2: Download


------------------------------------

Português:

Funciona na atualização 5079

Multi Client

Necessário .Net2: Download


18 de nov de 2008

C# 4.0 covariância e contravariância

Pra quem se lembra da série de artigos sobre covariância e contravariância, tenho uma boa notícia, elas serão implementadas no C# 4.0!

Pra quem não estiver a fim de ler os 11 artigos(alguns deles de dar nó no cérebro), recomendo o artigo do Giovanni Bassi, que resumiu de forma prática o que é covariância e contravariância

7 de nov de 2008

MSDN Ramp Up

Um novo programa de aprendizado da Microsoft, que no final do curso te da 25% de desconto em certificações e 50% de desconto em e-Learning. Link: http://www.myrampup.com/

Cursos disponíveis:

SharePoint for Developers track - learn more

Visual Studio 2008 track - learn more

Aspiring Developer - learn more

Success with Java and C# - learn more

Next Level Visual Basic - learn more

Next Level Microsoft.NET - learn more

5 de nov de 2008

Exame 71-564 em Beta

Mais um exame em Beta, desta vez o MCPD do ASP.NET 3.5. As inscrições começam hoje no site da Prometric. O código promocional pra fazer o exame de graça é RSC43, o número é limitado então não perca tempo. Você pode fazer o exame a partir do dia 6 de Novembro até dia primeiro de Dezembro.

You are invited to take beta exam 71-564: Pro: Designing and Developing ASP.NET Applications Using the Microsoft® .NET Framework 3.5. If you pass the beta exam, the exam credit will be added to your transcript and you will not need to take the exam in its released form. The results will not appear on your transcript until several weeks after the final form of the exam is released. The 71-xxx identifier is used for registering for beta versions of MCP exams, when the exam is released in its final form the 70-xxx identifier is used for registration.


71-564: Pro: Designing and Developing ASP.NET Applications Using the Microsoft® .NET Framework 3.5 counts as credit towards the following certification(s).

· Microsoft Certified Professional Developer: ASP.NET Developer 3.5. In order to earn this certification you must also hold the Microsoft Certified Technology Specialist: .NET Framework 3.5, ASP.NET Applications.

Availability

Registration begins: November 5, 2008

Beta exam period runs: November 6, 2008– December 1, 2008



Receiving this invitation does not guarantee you a seat in the beta; we recommend that you register immediately. Beta exams have limited availability and are operated under a first-come-first-served basis. Once all beta slots are filled, no additional seats will be offered.



Testing is held at Prometric testing centers worldwide, although this exam may not be available in all countries (see Regional Restrictions). All testing centers will have the capability to offer this exam in its live version.



Regional Restrictions: India, Pakistan, China

Registration Information

Please use the following promotional code when registering for the exam: RSC43
You must register at least 24 hours prior to taking the exam.


To register in North America, please call:

· Prometric: (800) 755-EXAM (800-755-3926)



Outside the U.S./Canada, please contact:

· Prometric: http://www.register.prometric.com/ClientInformation.asp

Test Information and Support

You are invited to take this beta exam at no charge.
You will be given four hours to complete the beta exam. Please plan accordingly.
Find exam preparation information: http://www.microsoft.com/learning/exams/70-564.mspx

4 de nov de 2008

Poster .Net 4.0

Como ocorreu com as versões anteriores, foi disponibilizado um poster com os tipos e namespaces do .Net 4.0, claro que muitas coisas ainda devem ser alteradas, mas não parece ter muitas classes novas e ainda a maioria que consta no poster é do .Net 3.5 SP1.

Você pode fazer o download aqui.

27 de out de 2008

Artigo "Skype API" na .Net Magazine

Neste mês sai meu primeiro artigo na .Net Magazine nº56, "Skype API - Aprenda a integrar seu software ao Skype". A revista deve chegar às bancas ainda esta semana e conta com muitos outros assuntos interessantes. O próximo artigo deve sair na edição 58 em dezembro e pretendo continuar escrevendo, apesar de estar bastante ocupado nas últimas semanas.

Espero que gostem e enviem seu feedback por email ou comentário

Visual Studio 2010 e .NET Framework 4.0 CTP

Sim, você não leu errado, o Visual Studio 10 e .Net 4.0 já está disponível, é claro em versão CTP.
Entre as novidades está o melhor suporte a Multi-Thread, variáveis dinâmicas!! e argumentos opcionais para os métodos em C#.

Faça o download em: https://connect.microsoft.com/VisualStudio/content/content.aspx?ContentID=9790

25 de out de 2008

Mais sobre exames de certificação

Foi publicada uma lista em que os novos exames estarão disponíveis em versão final ou beta:

SQL Exams

70-432 - Disponível

70-433 - 10/12/2008 (Final)

70-448 - Disponível

70-450 - 12/11/2008 (Final)

70-451 - 26/11/2008 (Final)

70-452 - 10/11/2008 (Final)

70-453 - 11/11/2008 (Final)

70-454 - 9/12/2008 (Final)

70-455 - 10/11/2008 (Final)

Developer Exams

70-505 - 3/11/2008 à 21/11/2008 (beta)

70-563 - 13/10/2008 à 30/10/2008 (beta)

70-564 - 6/11/2008 à 1/12/2008 (beta)

70-565 - 10/11/2008 à 3/12/2008 (beta)

70-566, 70-567, 70-568, e 70-569 não terão beta, e serão disponibilizados na mesma época que os MCPD.

17 de out de 2008

ASP.NET MVC Beta

Hoje foi liberado o ASP.NET MVC Beta. No site oficial: http://www.asp.net/mvc/ você vai encontrar muitas informações e tutoriais. Para fazer o download clique aqui.

Para usar o ASP.NET MVC você precisa do .Net 3.5 ou superior e o Visual Studio 2008 ou Visual Web Developer 2008 Express SP1.

Este Beta é quase completo, e teremos poucas novidades entre ele e a versão final. As novidades desde o Preview 5:

-New "Add View" Menu in Visual Studio
-New \Scripts directory and jQuery Support
-Built-in Model Binder Support for Complex Types
-Refactored Model Binder Infrastructure
-Strongly Typed UpdateModel and TryUpdateModel WhiteList Filtering
-Improved Unit Testing of UpdateModel and TryUpdateModel Scenarios
-Strongly Typed [AcceptVerbs] attribute
-Better Validation Error Messages
-HTML Helper Cleanup and Refactoring
-Silverlight / ASP.NET MVC Project Integration
-ASP.NET MVC Futures Assembly
-\Bin and GAC Assembly Deployment

Ah, o Scott Guthrie deixou escapar uma novidade do .Net 4.0. Haverá suporte a roteamento de URL nos WebForms.

16 de out de 2008

Exame 70-563 em Beta

O Exame 70-563 está em Beta, o que quer dizer que você pode participar gratuitamente, e se passar ele será adicionado ao seu transcript.

Para se increver vá ao site da Prometric e depois de agendar a data do exame, você vai para a tela de pagamento e informações pessoais, no topo do formulário tem uma opção pra adicionar o código da promoção ou voucher, use o seguinte: DW897.

O exame só esta disponível até dia 30 de Outubro e as vagas são limitadas.

Mais informações no convite:

"You are invited to take beta exam 71-563: Pro: Designing and Developing Windows Applications Using the Microsoft .NET Framework 3.5. If you pass the beta exam, the exam credit will be added to your transcript and you will not need to take the exam in its released form. The results will not appear on your transcript until several weeks after the final form of the exam is released. The 71-xxx identifier is used for registering for beta versions of MCP exams, when the exam is released in its final form the 70-xxx identifier is used for registration.

71-563: Pro: Designing and Developing Windows Applications Using the Microsoft .NET Framework 3.5 counts as credit towards the following certification(s).

· Microsoft Certified Professional Developer: Windows Developer 3.5. 

Find exam preparation information: http://www.microsoft.com/learning/exams/70-563.mspx


Availability

Registration begins: October 11, 2008

Beta exam period runs: October 13, 2008– October 30, 2008

Receiving this invitation does not guarantee you a seat in the beta; we recommend that you register immediately. Beta exams have limited availability and are operated under a first-come-first-served basis. Once all beta slots are filled, no additional seats will be offered. 

Testing is held at Prometric testing centers worldwide, although this exam may not be available in all countries (see Regional Restrictions). All testing centers will have the capability to offer this exam in its live version.

Regional Restrictions: India, Pakistan, China 

Registration Information

Please use the following promotional code when registering for the exam: DW897
You must register at least 24 hours prior to taking the exam.

To register in North America, please call:

· Prometric: (800) 755-EXAM (800-755-3926)

Outside the U.S./Canada, please contact:

· Prometric: http://www.register.prometric.com/ClientInformation.asp


Test Information and Support

You are invited to take this beta exam at no charge. 
You will be given four hours to complete the beta exam. Please plan accordingly."

14 de out de 2008

Silverlight 2

Finalmente saiu a versão final do Silverlight 2, você pode baixar a versão Windows e Mac a partir do site oficial: http://silverlight.net/GetStarted/.

Você pode desenvolver para Silverlight 2 usando qualquer linguagem .Net, como C#, VB.NET, IronRuby, etc.

Algumas funcionalidades que encontramos no Silverlight 2:

  • WPF UI Framework: Suporta um subconjunto das funcionalidades do WPF, o que torna os componentes reutilizáveis;

  • Rich Controls: Vários controles como TextBox, CheckBox, RadioButton, ComboBox, StackPanel, Grid, Panel, Slider, ScrollViewer, Calendar, DatePicker, DataGrid, ListBox, etc;

  • Rich Networking Support: REST, WS*/SOAP, POX, RSS;

  • Rich Base Class Library: Collections, IO, Generics, Threading, Globalization, XML, Local Storage, etc;

  • Rich Media Support: Video Codecs para viídeos de alta definição e streaming;

6 de out de 2008

MSDN Magazine - Setembro 2008

Está disponível a edição de Setembro da MSDN Magazine. Assuntos de capa:

  • ID de hierarquia: Modele hierarquias de dados com o SQL Server 2008
    Aqui, nós explicamos como o novo tipo de dados hierarchyID do SQL Server 2008 ajuda a resolver alguns dos problemas de modelagem e consulta de informações hierárquicas. Kent Tegels

  • Prism: Padrões para criação de aplicativos compostos com WPF
    Apresentamos os benefícios da criação de aplicativos compostos com o Composite Application Guidance for WPF de padrões e práticas da Microsoft. Glenn Block

  • Serviços de dados: Crie aplicativos Web centrados em dados com o Silverlight 2
    Os Serviços de Dados ADO.NET oferecem pontos de extremidade acessíveis pela Web, que permitem filtrar, classificar, formatar e paginar dados sem que você precise criar essa funcionalidade. Shawn Wildermuth

  • WPF avançado: Entendendo eventos e comandos roteados no WPF
    Saiba como eventos e comandos roteados no Windows Presentation Foundation formam a base da comunicação entre as partes de sua interface do usuário. Brian Noyes

Download em Português

5 de out de 2008

MSDN Magazine - Agosto 2008

Está disponível a edição de Agosto da MSDN Magazine. Assuntos de capa:

  • Data 2.0: Expor e utilizar dados no mundo de serviços web 
    O objetivo da Estrutura de Serviços de Dados do ADO.NET é criar uma estrutura simples baseada em REST para expor e consumir serviços centrados em dados com facilidade. Elisa Flasko and Mike Flasko

  • BizTalk EDI: Desenvolva uma solução EDI robusta com o BizTalk Server 
    Apresentamos a funcionalidade EDI do BizTalk Server 2006 R2, ilustrando a criação de esquemas, o mapeamento de documentos, a entrega e transmissão de EDI e a manipulação de exceções. Mark Beckner

  • Silverlight: Crie animações com XAML e Expression Blend 
    Neste trecho de seu futuro livro, Laurence Moroney explica as noções básicas de animação do Silverlight e as ferramentas de animação disponíveis no Expression Blend. Laurence Moroney

  • Write On!: Crie aplicativos web desenhando com o Silverlight 2 
    Criamos um aplicativo Silverlight 2.0 usando o InkPresenter para permitir que os usuários anotem uma coleção predefinida de imagens, executem o reconhecimento de manuscrito e salvem as anotações e o texto reconhecido em um banco de dados do lado do servidor. Julia Lerman

  • Wicked Code: Faça controles personalizados para o Silverlight 2 
    Se você não está familiarizado com o WPF (Windows Presentation Foundation), criar o primeiro controle personalizado do Silverlight pode ser uma experiência assustadora. Este artigo o orientará nesse processo. Jeff Prosise
Download em Português

29 de set de 2008

Microsoft anuncia o Visual Studio 2010 e .NET Framework 4.0

A Microsoft apresentou hoje a nova versão de sua plataforma de desenvolvimento e ferramentas, que levarão os nomes Visual Studio 2010 e .NET Framework 4.0.

O anúncio de hoje incluiu uma demonstração do Visual Studio Team System (VSTS) 2010 (codinome “Rosario”), que deve ajudar a democratizar o ALM (gerenciamento do ciclo de vida de aplicações) com uma solução única que traz todos os membros de uma organização de desenvolvimento para o ciclo de vida da aplicação em desenvolvimento e remove muitas das barreiras existentes para a integração.

Detalhes adicionais sobre as outras áreas serão fornecidos no decorrer do ciclo de desenvolvimento do Visual Studio 2010.

Anúncio: http://www.microsoft.com/presspass/press/2008/sep08/09-29VS10PR.mspx

Mais Informações: http://msdn.microsoft.com/en-us/vstudio/products/cc948977.aspx


26 de set de 2008

Silverlight 2 Release Candidate disponível

Está disponível o RC0 do Silverlight 2, você pode baixá-lo a partir da página: http://silverlight.net/GetStarted/sl2rc0.aspx

Para informações sobre as novidades, visite o blog do Scott Guthrie

13 de ago de 2008

Visual Studio 2008 Certification Training Kits

As novas certificações estão chegando e com elas os novos Training Kits.
Vou postar uma lista com a data prevista pro lançamento dos novos Training Kits, que inclusive estão em pré-venda na Amazon.

MCTS Self-Paced Training Kit (Exam 70-502): Microsoft® .NET Framework 3.5—Windows® Presentation Foundation
ISBN: 9780735625662
Disponibilidade: Já disponível

MCTS Self-Paced Training Kit (Exam 70-503): Microsoft® .NET Framework 3.5—Windows® Communication Foundation
ISBN: 9780735625655
Disponibilidade: Setembro/2008

MCTS Self-Paced Training Kit (Exam 70-505): Microsoft® .NET Framework 3.5—Windows® Forms Application Development
ISBN: 9780735626379
Disponibilidade: Janeiro/2009

MCTS Self-Paced Training Kit (Exam 70-561): Microsoft® .NET Framework 3.5 - ADO.NET Application Development
ISBN: 9780735625631
Disponibilidade: Janeiro/2009

MCTS Self-Paced Training Kit (Exam 70-562): Microsoft .NET Framework 3.5 - ASP.NET Application Development
ISBN: 9780735625624
Disponibilidade: Abril/2009

MCPD Self-Paced Training Kit (Exam 70-564): Designing and Developing ASP.NET Applications Using Microsoft .NET Framework 3.5
ISBN: 9780735626560
Disponibilidade: Maio/2009

11 de ago de 2008

Visual Studio 2008 SP1 e .NET Framework 3.5 SP1

Em menos de um ano desde o lançamento da versão RTM do VS2008 já temos disponível o SP1 do Visual Studio 2008 e .Net 3.5

Esse Service Pack é especial pois além das correções de bugs também das novas funcionalidades:

  • .NET Framework Client Profile: um subconjunto do .NET Framework 3.5 voltado para aplicações desktop;
  • ASP.NET Dynamic Data: possibilita o scaffolding para aplicações ASP.NET;
  • Suporte ao SQL Server 2008, lançado recentemente;
  • ADO.NET Data Services, conhecido antigamente pelo codinome Astoria;
  • ADO.NET Entity Framework;

Entre outros...

Infelizmente o ASP.NET MVC não está incluso e continua ainda em Preview, que porteriormente vai passar por Beta só então chegará na versão final.

Links para o download:

http://msdn.microsoft.com/en-us/vstudio/cc533448.aspx

http://go.microsoft.com/fwlink/?LinkId=122095

18 de jul de 2008

MSDN Magazine - Julho 2008

Está disponível a edição de Julho da MSDN Magazine. Assuntos de capa:

  • Serviços de dados: Desenvolva aplicativos eficientes e escalonáveis com os Serviços de Dados do SQL Server
    Aqui o autor apresenta os Serviços de Dados do SQL Server, que expõem sua funcionalidade em relação a interfaces padrão de Web service. David Robinson

  • ADO.NET: Obtenha uma modelagem de dados flexível com o Entity Framework
    A autora responde a perguntas sobre o Entity Framework e permite entender como e por que ele foi desenvolvido. Elisa Flasko

  • Dados e WPF: Personalize a Exibição de Dados com Ligação de Dados e WPF
    Aqui, apresentamos técnicas para a ligação de dados programática e declarativa e a exibição com o Windows Presentation Foundation. Josh Smith

  • Transações: Construa sistemas escaláveis que gerenciam falhas sem perder dados
    Sistemas que gerenciam falhas sem perder dados são enganosos. Aprenda como conquistar sistemas escalonáveis e eficientes. Udi Dahan

  • WCF P2P: Como projetar compartilhamento de estado em redes de mesmo nível
    Saiba como habilitar recursos ponto a ponto em aplicativos de negócios, permitindo que compartilhem estado em uma rede de mesmo nível sem servidor. Kevin Hoffman

Download em Português

17 de jul de 2008

Google Code Jam - Saving the Universe

Infelizmente meus planos de participar do Google Code Jam já eram. Marquei pra competir no dia 26(Sábado), até ai tudo ok, mas pra ajudar fizeram as eliminatórias HOJE, numa quinta-feira. Claro, como a maioria das pessoas estava trabalhando, quando cheguei ja tinha acabado o tempo...
De qualquer forma fiz o primeiro desafio, em C#, vou postar o código fonte pra vocês.

O desafio é salvar o Universo =). Segundo o Google, se você buscar pelo nome de um buscador nele mesmo(Ex.: Buscar Google, no Google) o universo vai implodir. Você recebe uma lista de Buscadores e a lista de Palavras à buscar(que vai ser sempre o nome de um dos buscadores). Então tem que gerar um algoritmo que faça que a busca, sem buscar a Palavra no Buscador com mesmo nome(pra nao implodir o Universo). Até aí nada demais, seria só um if pra fazer o switch entre qual buscador vai usar cada vez.

O desafio é fazer esse switch da forma mais otimizada possível, dizendo qual o número mínimo de switchs em cada caso, exemplos:

5
Yeehaw
NSM
Dont Ask
B9
Googol
10
Yeehaw
Yeehaw
Googol
B9
Googol
NSM
B9
NSM
Dont Ask
Googol
5
Yeehaw
NSM
Dont Ask
B9
Googol
7
Googol
Dont Ask
NSM
NSM
Yeehaw
Yeehaw
Googol

O primeiro número indica a quantidade de Buscadores, seguido pelos nomes dos mesmo, depois o número de Searchs e as respectivas Buscas.

No caso acima, devemos retornar:

Case #1: 1
Case #2: 0

Segue o código:

class Saving_the_Universe
{
    const string CaminhoEntrada = @"C:\Documents and Settings\Felipe\Meus documentos\Visual Studio 2008\Projects\CodeJam\CodeJam\Saving_the_Universe_Entrada.txt";
    const string CaminhoSaida = @"C:\Documents and Settings\Felipe\Meus documentos\Visual Studio 2008\Projects\CodeJam\CodeJam\Saving_the_Universe_Saida.txt";
 
    static List<string> Buscadores = new List<string>();
    static List<string> Querys = new List<string>();
 
    static void Main(string[] args)
    {
        StreamReader Entrada = new StreamReader(CaminhoEntrada);
        if (File.Exists(CaminhoSaida))
            File.Delete(CaminhoSaida);
 
        StreamWriter Saida = new StreamWriter(CaminhoSaida);
 
        int CasoAtual = 1;
        int CasosTotais = int.Parse(Entrada.ReadLine());
 
        string Temp = "";
 
        while (CasoAtual <= CasosTotais)
        {
            Buscadores.Clear();
            Querys.Clear();
 
            Temp = Entrada.ReadLine();
            for (int i = 0; i < int.Parse(Temp); i++)
            {
                Buscadores.Add(Entrada.ReadLine());
            }
 
            Temp = Entrada.ReadLine();
            for (int i = 0; i < int.Parse(Temp); i++)
            {
                Querys.Add(Entrada.ReadLine());
            }
 
            Saida.WriteLine("Case #{0}: {1}", CasoAtual, Algoritmo());
 
            CasoAtual++;
        }
 
        Entrada.Close();
        Saida.Close();
        Console.ReadKey(true);
    }
 
    static int Algoritmo()
    {
        Dictionary<string, int> QuerysContadas = new Dictionary<string, int>();
        //Pra cada buscador, conta quantas Querys existem chamando eles
        foreach (var item in Buscadores)
        {
            QuerysContadas.Add(item, Querys.Count<string>(p => p == item));
        }
 
        if (QuerysContadas.Values.Min() == 0)
            return 0;
 
 
        int UltimoIndice = 0;
        List<string> PalavraBuscadasNaOrdem = new List<string>();
 
        for (int i = 0; i < Querys.Count; i++)
        {
            if (PalavraBuscadasNaOrdem.Count == 0 || Querys[i] == PalavraBuscadasNaOrdem[PalavraBuscadasNaOrdem.Count - 1])
            {
                foreach (var NomeBuscador in Buscadores)
                {
                    if (Querys.IndexOf(NomeBuscador, i) == -1)
                        return PalavraBuscadasNaOrdem.Count;
 
                    if (UltimoIndice < Querys.IndexOf(NomeBuscador, i) && (PalavraBuscadasNaOrdem.Count == 0 || NomeBuscador != Querys[i]))
                        UltimoIndice = Querys.IndexOf(NomeBuscador, i);
                }
                PalavraBuscadasNaOrdem.Add(Querys[UltimoIndice]);
            }
        }
 
        return 1;
    }
}

16 de jul de 2008

Desafio I - Dynamic Iterators

Vou propor um desafio: Qual o resultado do seguinte código? E por quê?

    public class MainClass
    {
        static bool DeveMudar = false;
 
        public static void Main()
        {
            Console.WriteLine(DeveMudar);
            MetodoQualquer();
            Console.WriteLine(DeveMudar);
            Console.ReadKey();
        }
 
        public static IEnumerable<int> MetodoQualquer()
        {
            DeveMudar = true;
            yield return 1;
        }
    }

14 de jul de 2008

Design Patterns (Padrões de Projeto de Software) II: Observer

Continuando a série de artigos sobre Design Patterns, vamos discutir o Observer.

Vou novamente recorrer a definição da Wikipedia:

Define uma dependência um-para-muitos entre objetos de modo que quando um objeto muda o estado, todos seus dependentes sejam notificados e atualizados automaticamente. Isto é o padrão Observer e permite que objetos interessados sejam avisados da mudança de estado ou outros eventos ocorrendo num outro objeto.

O padrão Observer é também chamado de Publisher-Subscriber, Event Generator, Dependents.


O Observer é composto de duas partes, o Subject que é o objeto que muda de estado com uma frequência imprevisível e os Observers que devem pedir que sejam notificados das mudanças de estado do Subject.

Os Observers podem se "cadastrar" e "descadastrar" para receber essas notificações.

Veja um diagrama do pattern:

E vamos partir para os códigos:

ISubject.cs:


    public interface ISubject
    {
        void Registrar(IObserver observador);
 
        void Desregistrar(IObserver observador);
 
        void Notificar();
    }

IObserver.cs

    public interface IObserver
    {
        void Atualizar();
    }

SubjectConcreto.cs:

        private string _SubjectState = "ON";
 
        public string SubjectState
        {
            get
            {
                return _SubjectState;
            }
            set
            {
                _SubjectState = value;
            }
        }
 
        private List<IObserver> Observers = new List<IObserver>();
 
        #region ISubject Members
 
        public void Registrar(IObserver observador)
        {
            Observers.Add(observador);
        }
 
        public void Desregistrar(IObserver observador)
        {
            Observers.Remove(observador);
        }
 
        public void Notificar()
        {
            foreach (IObserver Observador in Observers)
            {
                Observador.Atualizar();
            }
        }
 
        #endregion
    }

ObserverConcreto.cs:

    public class ObserverConcreto : IObserver
    {
        private string _Nome;
        private string _ObserverState;
        private SubjectConcreto _Subject;
 
        public SubjectConcreto Subject
        {
            get { return _Subject; }
            set { _Subject = value; }
        }
 
        public ObserverConcreto(SubjectConcreto pSubject, string pNome)
        {
            this._Subject = pSubject;
            this._Nome = pNome;
        }
 
        #region IObserver Members
 
        public void Atualizar()
        {
            _ObserverState = _Subject.SubjectState;
            Console.WriteLine("Novo estado do Observer {0} é {1}", _Nome, _ObserverState);
        }
 
        #endregion
    }

Agora que temos nossas classes, vamos testa-las:

        static void Main(string[] args)
        {
            SubjectConcreto s = new SubjectConcreto();
 
            s.Registrar(new ObserverConcreto(s, "X"));
            s.Registrar(new ObserverConcreto(s, "Y"));
            s.Registrar(new ObserverConcreto(s, "Z"));
 
            s.SubjectState = "ABC";
            s.Notificar();
 
            Console.ReadKey();
        }

Iniciamos nossos Observers e já passamos como argumento no método Registrar. Quando mudamos o valor de s que é nosso Subject e Notificamos, o método Atualizar() dos Observers é executado e você verá o seguinte resultado:

No .Net também temos uma forma otimizada de fazer isso, usando delegates e events, que é muito mais simples e elegante, mas nada impede você de implementar essas classes da forma que vimos.

Há quem diga que Designs Patterns são na verdade "defeitos" das linguagens, se persarmos bem estão certos. O Observer é seria uma forma de usar delegates e events nas linguagens que não tem esses recursos, assim como vimos com o Singleton que pode ser implementado de forma muito mais simples no .Net. Até a herança que temos hoje, antigamente era um Design Pattern pra linguagens como C. Em assembly tinhamos um Pattern pra criar métodos! Que até então eram codigos que se repetiam por todo o programa, dificultando a manutenção. Mas continuando ao assunto principal...

Delegates são equivalentes aos ponteiros de função, mas orientado à objetos e "type-safe". Uma instância de delegate mantém uma referência à um método instanciado ou de classe.

Events por sua vez, são construções declaradas numa classe pra ajudar a expor mudanças de estado aos objetos interessados, que são definidos em tempo de execução.  Um event representa os métodos Registrar, Desregistrar e Notificar que usamos no Observer, mas suportado diretamente pelo compilador e pela CLR.

Os delegates são registrados pra cada event desejado em tempo de execução e quando o event é chamado, todos os delegates registrados são invocados.

Fazendo uma comparação direta com o Design Pattern Observer, a classe que declara o event, seria o Subject, mas sem precisarmos criar Interfaces. E o Observer deve instanciar um delegate passando o nome do método a ser notificado e registrá-lo ao event. Também é possível desregistrar os delegates. A notificação do Subject acontece quando o event é invocado.

Pra quem não está acostumado com delegates e events pode parecer um pouco complicado, mas na verdade é bem mais simples, pois você não tem que se preocupar com Interfaces ou classes Base. Veja um exemplo:

    public class Estoque
    {
        //Declaração do delegate
        public delegate void DelegatePerguntaPreco(decimal pPreco);
        //Declaração do event
        public event DelegatePerguntaPreco PrecoMudou;
 
        //Variável observada
        decimal _Preco;
 
        public decimal Preco
        {
            set
            {
                _Preco = value;
 
                //Dispara o event
                PrecoMudou(_Preco);
            }
        }
    }
 
    public class TelaEstoque
    {
        public void MetodoPrecoMudou(decimal pPreco)
        {
            Console.Write("O novo preço é:" + pPreco.ToString("c") + "\r\n");
        }
    }
 
    public class MainClass
    {
 
        public static void Main()
        {
            TelaEstoque objTela = new TelaEstoque();//Observer
            Estoque objEstoque = new Estoque();//Subject
 
            //Cria novo delegate e associa ao método
            //objTela.MetodoPrecoMudou do Observer
            Estoque.DelegatePerguntaPreco aDelegate = new
               Estoque.DelegatePerguntaPreco(objTela.MetodoPrecoMudou);
 
            //Adiciona o delegate ao event
            objEstoque.PrecoMudou += aDelegate;
 
            //Muda o preco 10 vezes
            for (int i = 0; i < 10; i++)
            {
                objEstoque.Preco = i;
            }
 
            //Remove o delegate do event
            objEstoque.PrecoMudou -= aDelegate;
 
            Console.ReadKey();
        }
 
    }

A vantagem dos delegates além da simplicidade é que permite que qualquer classe atue como um Observer, independente das Interfaces implementadas ou da classe Base, só precisamos criar um método com a mesma assinatura do delegate.

10 de jul de 2008

MSDN Magazine - Junho 2008

Está disponível a edição de Junho da MSDN Magazine. Assuntos de capa:

  • SAAS (software como serviço): Conecte aplicativos empresariais com serviços BizTalk hospedados
    Neste artigo, apresentamos os Serviços BizTalk, uma nova tecnologia que oferece os recursos de Barramento de Serviços Corporativos do BizTalk Server como um serviço hospedado. Jon Flanders e Aaron Skonnard

  • Simultaneidade: Ferramentas e técnicas para identificar problemas simultâneos
    Aplicativos paralelos eficientes não aparecem simplesmente executando um antigo aplicativo em um computador com processadores paralelos. É necessário fazer ajustes para aproveitar todas as vantagens. Rahul V. Patil e Boby George

  • Robótica: Simulando o mundo com o Microsoft Robotics Studio
    O Microsoft Robotics Studio não serve apenas para brincar com robôs. Ele também permite criar aplicativos baseados em serviço para uma ampla gama de dispositivos de hardware. Sara Morgan

  • Preenchimento de formulário: Crie fluxos de trabalho para capturar dados e criar documentos
    Saiba como criar um fluxo de trabalho que usa formulários InfoPath e outros documentos do Office a fim de passar dados para atividades direcionadas e para uso em documentos do Office. Rick Spiewak

  • Biblioteca GUI: A simplicidade do Windows Forms para aplicativos nativos
    Neste artigo, o autor John Torjo apresenta um guia para sua biblioteca de GUI C++ chamado eGUI++ e explica como ela torna a programação da interface do usuário mais fácil. John Torjo

Download em Português

3 de jul de 2008

Design Patterns (Padrões de Projeto de Software) I: Singleton

Design Patterns com certeza é um dos assuntos em que tenho mais interesse. Depois que você começa a estudá-los passa a pensar de forma diferente na hora de programar.

Há muito tempo vejo que cada vez que começava a escrever algum programa e o código ia crescendo e ficando mais complexo ficava muito difícil fazer alguma alteração, e testar tudo de novo. Isso quando era possível fazer alguma mudança ou extensão de forma viável.

Definição da Wikipedia:

In software engineering, a design pattern is a general reusable solution to a commonly occurring problem in software design. A design pattern is not a finished design that can be transformed directly into code. It is a description or template for how to solve a problem that can be used in many different situations. Object-oriented design patterns typically show relationships and interactions between classes or objects, without specifying the final application classes or objects that are involved. Algorithms are not thought of as design patterns, since they solve computational problems rather than design problems.

Not all software patterns are design patterns. Design patterns deal specifically with problems at the level of software design. Other kinds of patterns, such as architectural patterns, describe problems and solutions that have alternative scopes.


Em português:

Na engenharia de software, um design pattern é uma solução geral reutilizável para um problema que ocorre comumente na concepção do software. Um design pattern não é um projeto acabado que possa ser diretamente transformado em código. É uma descrição ou modelo de como resolver um problema que pode ser usado em muitas situações diferentes. Design patterns em orientação à objetos tipicamente mostra os relacionamentos e interações entre classes ou objetos, sem especificar a aplicação final das classes ou objetos envolvidos. Algoritmos não são consideradas design patterns, pois eles resolvem problemas computacionais em vez de problemas de design.

Perceba que nem todos software patterns são design patterns. Design patterns lidam especificamente com problemas no nível de design de software. Outros tipos de padrões, como architectural patterns, descrevem problemas e soluções que tem escopos alternativos.


Vamos começar pelo mais simples deles, o Singleton. Que apesar de ser simples tem alguns problemas no qual precisamos ficar atentos, no caso com Multi-Thread.

O padrão Singleton deve garantir que uma classe tenha uma única instância e proporcione um ponto de acesso global.
Um exemplo de uso é no caso de um objeto de log, deixando uma única instância responsável por gerenciar o log.

Vemos aqui um diagrama de classe do Singleton:

Diagrama de Classes


Perceba que temos um construtor private, pois não podemos deixar a classe Cliente criar novas instâncias do Singleton.

Agora apresentando o código, a princípio poderíamos criar um código bem simples como esse:

public static Singleton Instancia

{

    get

    {

        if (_Instancia == null)

            _Instancia = new Singleton();

 

        return _Instancia;

    }

}



Mas teríamos um problema, se um thread A estiver acessando o Singleton pela primeira vez e logo após o if (_Instancia == null) fosse interrompido e então um thread B poderia passar também pela condição, já que o Singleton ainda é null e então instanciar o objeto. Quando o thread A voltasse, ele estaria dentro do if, e criaria outra instância do objeto, o que não é desejado nesse deisgn pattern.

Para resolver este problema, podemos fazer um lock sobre a classe, garantindo que apenas um thread passe pelo lock. Adicionalmente criamos outro if antes do lock, para que depois que a classe estiver devidamente instanciada, não criarmos lock´s toda vez que alguém acessar a Instancia, o que degradaria a performance.
Este modelo se chama "Double Check Lock". Neste modelo, mesmo que dois ou mais threads passem pelo primeiro if, apenas um thread pode passar pelo lock por vez, então se o thread A passar pelo lock primeiro, ele vai verificar no segundo if se o objeto já foi instanciado, se não foi ele irá instanciá-lo. Quando o thread A terminar, irá liberar o lock, e o thread B então continua seu trabalho entrando no lock, mas desta vez ele não conseguirá passar pelo segundo if, pois o thread A já instanciou o objeto.

public static Singleton Instancia

{

    get

    {

        if (_Instancia == null)

        {

            lock (typeof(Singleton))

            {

                if (_Instancia == null)

                    _Instancia = new Singleton();

            }

        }

        return _Instancia;

    }

}



Geralmente quem olha esse código imagina que já temos o necessário, e realmente é o que parece. Mas temos um outro problema que não é visível no código.
Quando o compilamos nosso código, várias otimizações são feitas no código assembly(no caso IL, mas o modelo é aplicável a qualquer linguagem como C++) e essa otimização pode comprometer a integridade do nosso modelo. Pra entender como isso acontece vamos revisar como um objeto é instanciado:

1º - A memória(no Heap) é alocada para guardar o objeto Singleton.
2º - O Singleton é construído dentro do espaço de memória alocado.
3º - O endereço da memória alocada é atribuído à Instância(no Stack).

*Não vou explicar como funciona o Heap e Stack nesse artigo para não perdemos o foco.

Mas o compilador pode reordenar essas instruções quando faz a otimização do código, e o problema aparece quando o passo 2 e 3 são trocados:

1º - A memória(no Heap) é alocada para guardar o objeto Singleton.
2º - O endereço da memória alocada é atribuído à Instância(no Stack).
3º - O Singleton é construído dentro do espaço de memória alocado.

Usando o mesmo exemplo, se o thread A for interrompido depois de passar pelo 2º passo, o thread B ao chegar no if (_Instancia == null) irá receber false, pois _Instancia não tem mais o valor null, já foi atribuído um endereço de memória à ele, então o objeto _Instancia será retornado do jeito que está e quando sua classe Cliente for usá-lo...teremos um erro! O objeto ainda não existe, apenas o espaço alocado na memória.

Para resolvermos este problema no C# podemos usar a keyword volatile, que diz ao processador que não deve reordenar as instruções e deixar a otimização de lado:

public class Singleton

{

    private static volatile Singleton _Instancia = null;

 

    private Singleton()

    {

    }

 

    public static Singleton Instancia

    {

        get

        {

            if (_Instancia == null)

            {

                lock (typeof(Singleton))

                {

                    if (_Instancia == null)

                        _Instancia = new Singleton();

                }

            }

            return _Instancia;

        }

    }

 

    public static void MetodoUm()

    {

    }

 

    public static void MetodoDois()

    {       

    }

}



Em .Net temos uma outra opção, muito mais simples e elegante, mas essa forma é particular do .Net não tendo nada parecido em outras linguagens:

sealed class Singleton

{

    private Singleton() { }

    public static readonly Singleton Instancia = new Singleton();

}


Pra começar mudamos o comportamento da classe, que tinha um "lazy initialization" e o removemos. Não estamos mais usando uma propriedade e sim dando acesso direto ao objeto Singleton, além de marcá-lo como readonly e instanciarmos na declaração.
Então esse método é pior? Perdemos a vantagem do "lazy initialization" e estamos sobre o perigo do acesso em Multi-Thread? Na verdade não, estamos apenas passando a responsabilidade pro .Net.

Sobre o "lazy initialization", antes fizemos uma propriedade que na primeira vez que era chamada criava a instância do objeto. Esse comportamento é o "lazy initialization", só instanciar o objeto quando ele for necessário, se for. O .Net faz isso pra gente, o JIT é esperto o suficiente pra instanciar a propriedade static quando e somente quando alguém usá-la.

E sobre a inicialização Thread-Safe? O readonly cuida disso, já que uma das regras sobre o readonly é que ele só possa ser inicializado de forma estática, o que só vai acontecer uma vez.

Por fim declaramos a classe como sealed, pois não é uma boa prática herdar de um Singleton, além de que se você precisar de outra implementação de Singleton é muito fácil fazer do zero, e evita muitos problemas.

Espero ter sido claro o suficiente, qualquer dúvida é só deixar um comentário. Até o próximo artigo.

2 de jul de 2008

Covariância e Contravariância em C#, Parte Onze: Ao infinito, mas não além

Como discutido ao longo desse espaço, estavamos considerando adicionar Covariância e Contravariância em tipos de parâmetros de delegates e interfaces para uma futura versão do C#.

Variância é extremamente útil em muitos casos, mas expõe um problema irritante em certos casos raros e bizarros. Este é apenas um exemplo:

Considere uma interface "normal" contravariante em seu único parâmetro de tipo genérico, e uma interface "louca" invariante que herda a interface normal em uma forma estranha:

public interface IN<in U> {}
public interface IC<X> : IN<IN<IC<IC<X>>>> {}

Isto é um pouco estranho, mas com certeza válido.

Antes de continuarmos, vamos entender porque isto é válido. A maioria das pessoas quando ve algo como isso imediatamente diz "mas uma interface não pode herdar de si mesma, isso é inválido, é uma cadeia circular na herança!"

Primeiro, não, isso não é correto. Em nenhum lugar a especificação do C# faz este tipo de herança inválido, e de fato, uma forma mais simples disso deve ser válida. Você deve ser capaz de dizer:

interface INumber<X> : IComparable<INumber<X>> { ... }

ou seja, você deve ser capaz de expressar que uma das garantias do contrato de INumber<X> é que você possa sempre comparar um número com outro. Portanto, deve ser válido usar um nome de tipo no argumento de tipo do tipo generic do pai.

No entanto, nem tudo é perfeito. Este tipo particular bruto de herança que dei como exemplo é de fato inválido no CLR, mesmo que não seja inválido no C#. Isso significa que é possível ter um tipo de interface compilada em C# que não pode ser carregada pelo CLR. Isto infelizmente irá gerar problemas, e espero que em uma versão futura do C# faça as definição das regras do C# mais rígidas ou até mais rígidas que as do CLR. Até lá, evite fazer isso.

Segundo, infelizmente, o compilador de C# atualmente tem vários bugs no seu detector de ciclo, como algumas vezes em que coisas se parecem com ciclos mas não são realmente, e são marcados com erros de ciclos. Isto só torna ainda mais difícil a compreensão do que é um ciclo válido e o que não é. Por exemplo, hoje o compilador irá incorretamente dizer que isto é um ciclo de classe base inválido, mesmo que claramente não é:


    public class November<T> { }
    public class Romeo : November<Romeo.Sierra.Tango>
    {
        public class Sierra
        {
           public class Tango { }
        }
    }

De qualquer forma, voltando ao assunto: variância louca. Nós temos as interfaces definidas acima, e então damos ao compilador um pequeno enigma pra resolver:

IC<double> bar = qualquer;
IN<IC<string>> foo = bar;  // Esta atribuição é válida?

Estamos prestes a entrar em um nome generic praticamente impossível de ler, então pra ficar mais fácil, a partir de agora vamos abreviar IN<IC<string>> como NCS. IC<double> será abreviado como CD.

Do mesmo modo, vou abreviar "é convertível de forma implícita" por uma seta. Então a questão é: CD→NCS é true ou false?

Vamos ver. Claramente CD não se converte em NCS diretamente. Mas (por motivos do compilador) talvez o tipo base de CD’s consiga.

O tipo base de CD’s é NNCCD. Será que NNCCD→NCS? Bem, N é contravariante em seus parâmetros assim isto se resume a questão, CS→NCCD?

Claramente não diretamente. Mas talvez CS tenha um tipo base que converta em NCCD. O tipo base de CS é NNCCS. Agora nós temos a questão NNCCS→NCCD ?

N é contravariante em seus parâmetros, agora caímos em CCD→NCCS ?

O compilador vai "reduzindo" o problema se CD→NCS é verdadeiro à CCD→NCCS! Se mantermos uma "redução" como esta então teremos CCCD→NCCCS, CCCCD→NCCCCS, e assim por diante.

Isto é apenas uma fração de algumas das formas em que o sistema de tipos pode ficar estranho. Para se aprofundar mais nesse assunto, você pode ler o Microsoft Research paper.

Parte Anterior: Covariância e Contravariância em C#, Parte Dez: Lidando Com Ambiguidades

25 de jun de 2008

Google Code Jam - Alien Numbers e Always Turn Left

Conseguir fazer os dois primeiros testes do primeiro concurso, o Alien Numbers e Always Turn Left. É possível também baixar o código dos vencedores, que são na maioria em C++.

Queria saber se alguem mais fez em C#, pra trocar umas idéias sobre o algoritmo. O meu ficou bem grande, 460 linhas, fiz orientado a objetos e tudo comentando e separado em métodos, talvez por isso tenha ficado tão grande.

Esse fim de semana vou participar do concurso e quem sabe da pra ganhar uns trocados...

Ah, o primeiro colocado do primeiro concurso que levou U$10000,00 é algum tipo de gênio, o que só levou vinte e poucos minutos pra fazer cada um dos 4 testes, levei 2h pra fazer o primeiro e 3h pro segundo. Do segundo colocado em diante demoraram várias dezenas de horas.

Quem quiser o código fonte é só pedir. Não vou postar pelo tamanho do mesmo.

24 de jun de 2008

Covariância e Contravariância em C#, Parte Dez: Lidando Com Ambiguidades

Suponha que fizemos IEnumerable covariante em T. O que este código deve fazer?

class C : IEnumerable<Girafa>, IEnumerable<Tartaruga>
{
    IEnumerator<Girafa> IEnumerable<Girafa>.GetEnumerator()
    {
        yield return new Girafa();
    }
    IEnumerator<Tartaruga> IEnumerable<Tartaruga>.GetEnumerator()
    {
        yield return new Tartaruga();
    }
    // [etc.]
}
 
class Program
{
    static void Main()
    {
        IEnumerable<Animal> animais = new C();
        Console.WriteLine(animais.First().GetType().ToString());
    }
}

Opções:

1) Erro em tempo de compilação.
2) Erro em tempo de execução.
3) Sempre enumera Girafas.
4) Sempre enumera Tartarugas.
5) Escolha entre Girafas e Tartarugas em tempo de execução.
6) Nenhuma das opções acima.

Se você escolheu outra opção além da 1, deveríamos ter um warning em tempo de compilação?

Continua na parte onze.

Parte Anterior: Covariância e Contravariância em C#, Parte Nove: Criando Incompatibilidades

Covariância e Contravariância em C#, Parte Nove: Criando Incompatibilidades

Nesta parte vamos discutir quais incompatibilidades teremos ao adicionar este recurso.

Simplesmente adicionando variância às regras de conversão nunca deveria causar nenhuma incompatibilidade. Entretanto, a combinação de se adicionar variância às regras de conversão e fazer alguns tipos terem parâmetros variantes causa uma potencial quebra de compatibilidade.

Geralmente as pessoas sabem que não se deve fazer isso:

if (x is Animal) 
  DoSomething();
else if (x is Girafa) 
  DoSomethingElse(); // nunca executa

porque a segunda condição é totalmente englobada pela primeira. Mas hoje no C# 3.0 é perfeitamente normal escrever:

if (x is IEnumerable<Animal>) 
  DoSomething();
else if (x is IEnumerable<Girafa>) 
  DoSomethingElse();

porque não há qualquer conversão sendo usada entre IEnumerable<Animal> e IEnumerable<Girafa>. Se nós adicionarmos covariância no IEnumerable<T> e o programa compilado contendo o fragmento acima usar a nova biblioteca então o comportamento quando dado um IEnumerable<Girafa> irá mudar. O objeto passará a ser atribuível à IEnumerable<Animal>, e por isso o "is" irá retornar "true", mudando a lógica do programa.

Há também a questão de mudar a semântica dos códigos fonte existentes ou tornar programas compiláveis em programas com erros de compilação. Por exemplo, a resolução da sobrecarga pode falhar onde deveria ser usada com sucesso. Se nós temos:

interface IBar<T>{} // Vindo de outro assembly
...
void M(IBar<Tigre> x){}
void M(IBar<Girafa> x){}
void M(object x) {}
...
IBar<Animal> y = qualquer;
M(y);

Então a resolução da sobrecarga pega a versão que recebe um object porque é a única escolha aplicável. Se nós mudarmos a definição de IBar para

interface IBar<-T>{}

e recompilar então teremos um erro de ambiguidade porque agora todos os três são aplicáveis e não há uma única melhor escolha.

Sempre queremos evitar incompatibilidades se possível, mas as vezes novos recursos são suficientemente atraentes e as incompatibilidades são tão raras que vale a pena. Acho que criando a variância em interfaces e delegates vamos permitir muito mais cenários interessantes do que incompatibilidades.

Será que este recurso irá trazer tantos benefícios que vale a pena gastar tempo desenvolvendo-o pra uma futura versão do C#?

Continua na parte dez: Covariância e Contravariância em C#, Parte Dez: Lidando Com Ambiguidades

Parte Anterior: Covariância e Contravariância em C#, Parte Oito: Opções de Sintaxe

23 de jun de 2008

Covariância e Contravariância em C#, Parte Oito: Opções de Sintaxe

Como discutimos anteriormente, nós introduzimos variância de interface e delegate em uma hipotética futura versão do C#, então precisamos de uma sintaxe para ela. Aqui estão algumas possibilidades.

Opção 1:

interface IFoo<+T, -U> { T Foo(U u); }

A CLR usa a convenção que estamos usando em toda a série de "+ sendo covariante e - contravariante”. Embora isto tenha algum valor mnemónico (porque + quer dizer "é compatível com um tipo maior"), muitas pessoas (incluindo membros da comissão de design do C#!) têm dificuldades em se lembrar o que é exatamente.

Esta convenção também é utilizada pela linguagem de programação Scala.

Opção 2:


interface IFoo<T:*, *:U> { …

Este indica mais graficamente "alguma coisa que é extendida por T" e "alguma coisa a qual extende U". É similiar as keywords Java, onde elas dizem "extends U" ou "super T".

Embora isto não seja terrível, penso que isto funde um pouco as noções de extensão e compatibilidade de atribuição. Eu não quero implicar que IEnumerable<Animal> é a base de IEnumerable<Girafa>, mesmo que Animal seja a base de Girafa. Em vez disso, quero dizer que IEnumerable<Girafa> é convertível para IEnumerable<Animal>, ou a atribuição é compatível. Eu não quero exceder os conceitos o mecanismo de herança. Isto é ruim, nós estamos unindo classes base com interfaces base.

Opção 3:

interface IFoo<T, U> where T: covariant, U: contravariant { …

Novamente, nada mal. O perigo aqui é similar ao dos sinais mais e menos: que ninguém se lembra o que "contravariante" e "covariante" significa. Este tem a vantagem de que pelo menos você pode buscar pelas palavras e achar alguma explicação.

Opção 4:

interface IFoo<[Covariant] T, [Contravariant] U>  { …

Similar à opção 3.

Opção 5:

interface IFoo<out T, in U> { …

Estamos tomando um rumo diferente com essa sintaxe. Nas opções anteriores nós estávamos descrevendo como o usuário da interface pode trata-lá, respeitando as regras do sistema de conversão de tipos para conversão implícita – que é, quais são as variâncias válidas nos tipos dos parâmetros. Em vez disso, aqui nós estamos descrevendo como o implementador da interface tem a intenção de usar os tipos dos parâmetros.

A desvantagem é que, como discutido em artigos anteriores, você acaba em situações como essa:

delegate void Meta<out T>(Action<T> action);

onde o "out" T seja claramente utilizada em uma posição de entrada.

Continua na parte nove: Covariância e Contravariância em C#, Parte Nove: Criando Incompatibilidades

Parte Anterior: Covariância e Contravariância em C#, Parte Sete: Por que precisamos de uma sintaxe para tudo?

20 de jun de 2008

Google Code Jam

O desafio mundial da Google aos melhores programadores do mundo e que consiste em resolver quatro problemas de algoritmos no menor tempo possível está com inscrições abertas até o próximo dia 17 de julho. A finais regionais acontecerão em Belo Horizonte, em outubro.

Os 500 melhores classificados ganharão uma viagem com tudo pago para as semifinais na capital mineira, de onde serão selecionados os 100 primeiros para a grande final na sede da Google em Mountain View. Além da viagem, também há prêmios em dinheiro:

· 1º lugar: US$ 10 mil

· 2º lugar: US$ 5 mil

· 3º lugar: US$ 2,5 mil

· 4º - 10º lugares: US$ 1,5 mil cada

· 11º - 30º lugares: US$ 1 mil cada

· 31º - 50º lugares: US$ 750 cada

· 51º - 75º lugares: US$ 500 cada

· 76º - 100º lugares: US$ 250 cada

Citando o comunicado da imprensa:

Uma novidade do Google Code Jam 2008 é a inserção de ferramentas próprias que permitem que os participantes programem em qualquer linguagem. Essas ferramentas foram criadas por uma equipe de funcionários que dedica 20% do seu horário de trabalho a projetos inovadores de seu interesse, e que é formada também por vencedores de Code Jams passados.


Nada mal, faturar um trocado, ter seu nome estampado com glória em sites geek pelo mundo afora e conseguir uma vaguinha em Montain View. Mas não pense que a coisa é fácil... em 2006, para se ter uma idéia, o vencedor latino-americano foi o carioca Fábio Dias Moreira, com um total de 753,4 pontos. Já o campeão mundial foi o russo Petr Mitrichev, com 972,02!

Via: Meio Bit

Nota: Fiz o primeiro teste prático(Alien Numbers). E não é fácil, mas também não é impossível. Demorei 2 horas pra criar o algoritmo, ficaria um pouco atrás do segundo colocado neste teste. Recomendo pra quem quiser praticar um pouco de lógica.

3 de jun de 2008

Computação Paralela - CTP de Junho

Saiu o Community Technology Preview da Extensão para Computação Paralela para .Net 3.5.

"Parallel Extensions to the .NET Framework is a managed programming model for data parallelism, task parallelism, and coordination on parallel hardware unified by a common work scheduler. Parallel Extensions makes it easier for developers to write programs that scale to take advantage of parallel hardware by providing improved performance as the numbers of cores and processors increase without having to deal with many of the complexities of today’s concurrent programming models.

Parallel Extensions provides library based support for introducing concurrency into applications written with any .NET language, including but not limited to C# and Visual Basic."


Download

Mais Informações

MSDN Magazine - Maio 2008

Está disponível a edição de Maio da MSDN Magazine. Assuntos de capa:


  • Aplicativos do Office: Integração do VSTO aos tipos de conteúdo do SharePoint
    Veja como criar uma personalização do Visual Studio Tools for Office em nível de documento e integrá-la a um tipo de conteúdo no SharePoint.
    Steve Fox

  • MOSS 2007: Implantação automatizada de aplicativos Web com a API do SharePoint
    Saiba como automatizar implantações de aplicativo do SharePoint personalizado, usar a API do SharePoint e evitar a dificuldade das definições de site personalizadas.
    E. Wilansky, P. Olszewski, and R. Sneddon

  • C++ Plus: Reforce os aplicativos Windows com o Feature Pack do Visual C++ 2008
    Kenny Kerr faz grandes elogios ao novo Feature Pack do Visual C++ 2008, que apresenta recursos convenientes e modernos para o Visual C++.
    Kenny Kerr

  • Segurança: Autenticação mais segura com a solução de senha One-Time Password Solution
    As senhas únicas oferecem soluções para ataques de dicionário, phishing, interceptação e muitas outras violações de segurança. Eis como tudo funciona.
    Dan Griffin

  • Sopa de letrinhas: Uma pesquisa sobre linguagens e paradigmas .NET
    Apresentamos aqui um resumo dos vários paradigmas das linguagens baseadas no CLR por meio de introduções rápidas e exemplos de código.
    Joel Pobar


Download em Português

16 de mai de 2008

Covariância e Contravariância em C#, Parte Sete: Por que precisamos de uma sintaxe para tudo?

Suponha que estamos implementando interface genérica e variância delegada em um futura versão hipotética do C#. Como, hipoteticamente, deveria ser a sintaxe? Há muitas opções que poderíamos considerar.

Antes de pensarmos nas opções, nos perguntamos, "E se não tivermos uma sintaxe para tudo?" Por que não inferimos a variância para o desenvolvedor, de modo que tudo apenas magicamente funcione?

Infelizmente isso não existe, por várias razões.

Primeira, assim parece que a variância devia ser algo que você deliberadamente implementa em sua interface ou delegate. Fazendo isso você começa a perder o controle do objetivo que o usuário busca.

Fazer isso "automagicamente" também significa que, assim como o processo de desenvolvimento e métodos forem adicionados às interfaces, a variância da interface pode mudar inesperadamente. Isto pode introduzir inesperadas e profundas mudanças em outros pontos do programa.

Segundo, tentar fazer isso introduz um novo tipo de ciclo à análise da linguagem. Nós já temos que detectar coisas como ciclos nas classes base, ciclos na interfaces base e ciclos nas regras de tipos genéricos, então em teoria não tem nenhuma novidade. Mas na prática, há alguns problemas.

No artigo anterior não discutimos sobre restrições adicionais que nós precisamos para criar interfaces variantes. Uma restrição importante é que a interface variante que herda de outra interface variante deve fazer de uma maneira que não introduza problemas no sistema de tipos. Basicamente, todas as regras para quando um tipo de parâmetro pode ser covariante ou contravariante precisam "fluir" para a interface base.

Por exemplo, suponha que o compilador esteja tentando deduzir a variância neste programa:

interface IFrob<T> : IBlah<T> { }
interface IBlah<U>
{
    IFrob<U> Frob();
}


E nos perguntamos "é válido para T ser variante em IFrob<T>?" Para responder esta pergunta, nós precisamos determinar se é válido para U ser variante em IBlah. E para responder esta pergunta nós precisamos saber se válido para U ser variante no tipo de saída IFrob<U>, e...voltamos do ponto que começamos!

Não queremos que o compilador entre em um loop infinito quando compilar este programa. Mas esta claro que este programa é perfeitamente válido. Quando detectarmos um ciclo nas classes base, podemos parar e dizer "Seu programa é inválido". Mas não podemos fazer isso aqui. É uma questão complicada.

Terceiro, mesmo se pudéssemos descobrir uma maneira de resolver o problema do ciclo, nós ainda teríamos um problema com o caso acima. Ou seja, há três possíveis respostas logicamente consistentes: "ambas invariantes", "+T, +U" e "-T, -U" todas produzem programas que seriam typesafe. Como podemos escolher?

Podíamos começar em situações ainda piores:

interface IRezrov<V, W>
{
    IRezrov<V, W> Rezrov(IRezrov<W, V> x);
}


Nesta interface louca podemos deduzir que "ambas invariantes", <+V, -W> e <-V, +W> são todas as possibilidades. Novamente, como escolher?

E quarto, mesmo se pudéssemos resolver todos esses problemas, suspeito que o desempenho de tal algoritmo seria potencialmente muito ruim. Isto tem tudo para ter um "crescimento exponencial". Temos outros algoritmos exponenciais no compilador, mas prefiro não adicionar mais, se podemos evitar.

Assim, se adicionarmos interface e variância delegada em uma hipotética futura versão do C#, precisamos dar uma sintaxe para ela.

Continua na parte oito: Covariância e Contravariância em C#, Parte Oito: Opções de Sintaxe

Parte Anterior: Covariância e Contravariância em C#, Parte Seis:Variância de Interface