csharp06a00

Nesta terceira parte da série sobre novidades do C# 6.0 serão apresentados os seguintes recursos:

  • Uma nova forma para inicializar instâncias do tipo Dictionary;
  • Exception Filters;
  • A nova versão do utilitário NuGet.

OBSERVAÇÃO: todos os exemplos detalhados nas seções seguintes foram implementados através do Visual Studio Ultimate 2015 Preview.

Inicialização de instâncias do tipo Dictionary

Em versões anteriores do C# existiam dois modos possíveis para a inicialização de objetos do tipo Dictionary:

  • Empregando o método Add, logo após a geração da instância da classe Dictionary (Listagem 1);
  • Utilizando pares formados por chave e valor, com estes dois elementos separados pelos caracteres “{” e “}” (Listagem 2).
...

Dictionary<string, string> capitais =
    new Dictionary<string, string>();

capitais.Add("SP", "São Paulo");
capitais.Add("RJ", "Rio de Janeiro");
capitais.Add("MG", "Minas Gerais");
capitais.Add("RS", "Porto Alegre");
capitais.Add("BA", "Salvador");
capitais.Add("SC", "Santa Catarina");
capitais.Add("DF", "Brasília"); 

...

Listagem 1: Inicializando um Dictionary através do método Add

...

Dictionary<string, string> capitais =
    new Dictionary<string, string>()
    {
        {"SP", "São Paulo"},
        {"RJ", "Rio de Janeiro"},
        {"MG", "Minas Gerais"},
        {"RS", "Porto Alegre"},
        {"BA", "Salvador"},
        {"SC", "Santa Catarina"},
        {"DF", "Brasília"}
    };

...

Listagem 2: Inicializando um Dictionary logo após o mesmo ser instanciado

Ainda considerando o exemplo que envolve capitais e respectivos estados, na Listagem 3 é demonstrado como ficaria a declaração da referência correspondente no C# 6.0. Já na Imagem 1 é apresentado o resultado da execução deste bloco de código.

Os elementos que constituem as chaves podem vir agora delimitados por colchetes (“[” e “]”), estando separados dos valores por um sinal de igual. Os diferentes itens (chave + valor) que compõem a coleção, por sua vez, encontram-se separados por vírgulas. É importante destacar que embora esta alternativa faça uso de uma sintaxe considerada mais intuitiva por muitos, a mesma não substitui as outras possibilidades herdadas de versões anteriores da linguagem.

using System;
using System.Collections.Generic;

namespace TesteInicializacaoDictionary
{
    class Program
    {
        static void Main(string[] args)
        {
            Dictionary<string, string> capitais =
                new Dictionary<string, string>()
                {
                    ["SP"] = "São Paulo",
                    ["RJ"] = "Rio de Janeiro",
                    ["MG"] = "Minas Gerais",
                    ["RS"] = "Porto Alegre",
                    ["BA"] = "Salvador",
                    ["SC"] = "Santa Catarina",
                    ["DF"] = "Brasília"
                };

            Console.WriteLine("Alguns exemplos de capitais brasileiras:\n");
            foreach (var capital in capitais)
            {
                Console.WriteLine("{0} - {1}",
                capital.Value, capital.Key);
            }

            Console.ReadKey();
        }
    }
}

Listagem 3: Nova alternativa para declaração de objetos Dictionary no C# 6.0

csharp06c01
Imagem 1. Resultado dos testes demonstrando a nova forma de inicialização de objetos do tipo Dictionary

Exception Filters

O tratamento de um tipo específico de exceção nem sempre pode ser realizado a partir de um bloco genérico de instruções. As informações de diferentes condições de erro podem ser encapsuladas em uma mesma estrutura derivada do tipo Exception (namespace System), com dados adicionais estando associados a propriedades específicas da classe em questão. Um bom exemplo que ilustra este cenário na plataforma .NET é a classe SqlException (namespace System.Data.SqlClient), a qual conta com a propriedade Number para detalhar um variado e extenso conjunto de problemas (erros internos num servidor de banco de dados, falhas de conexão, dentre outros comportamentos anormais que possam vir a ocorrer).

Em versões anteriores da linguagem C# a implementação de diversos tratamentos a partir de um mesmo tipo de exceção implicava, basicamente, na codificação de diversos trechos condicionais dentro de um bloco “catch” (ou em um método acionado através deste último). Na Listagem 4 está um exemplo que demonstra uma situação deste gênero:

  • Exceções baseadas na classe TesteException estão sendo manipuladas em único bloco “catch”, com diferentes condições sendo tratadas em blocos específicos;
  • Cada bloco “if” exibirá uma diferente mensagem, considerando para isto uma faixa de valores associados à propriedade NivelSeveridade.
using System;

namespace TesteExceptionFilters
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Testando a geração de exceções...");

            try
            {
                throw new TesteException("Gerando um erro para demonstração...");
            }
            catch (TesteException ex)
            {
                if (ex.NivelSeveridade == 1)
                {
                    Console.WriteLine(
                        "Aconteceu um erro com um nível de severidade baixo...");
                }
                else if (ex.NivelSeveridade <= 3)
                {
                    Console.WriteLine(
                        "Aconteceu um erro com um nível de severidade moderado...");
                }
                else
                {
                    Console.WriteLine(
                        "Aconteceu um erro com um nível de severidade alto...");
                }
            }

            Console.ReadKey();
        }
    }
}

Listagem 4: Exemplo de tratamento de várias condições para uma mesma exceção

Já a definição do tipo TesteException pode ser observada na Listagem 5. Para efeitos de teste a propriedade NivelSeveridade está sendo preenchida com um valor aleatório que varia de 1 a 5, fazendo uso para isto de uma instância da classe Random (namespace System).

using System;

namespace TesteExceptionFilters
{
    public class TesteException : Exception
    {
        private int _nivelSeveridade;

        public int NivelSeveridade
        {
            get
            {
                return this._nivelSeveridade;
            }
        }

        public TesteException(string mensagem)
            : base(mensagem)
        {
            Random r = new Random();
            this._nivelSeveridade = r.Next(1, 5);
        }
    }
}

Listagem 5: Implementação da classe TesteException

O recurso conhecido como “Exception Filters” foi incorporado ao C# 6.0, tendo por objetivo simplificar cenários como o proposto no exemplo desta seção. A partir da inclusão de uma cláusula when a blocos iniciados por catch, esta construção permite a codificação de seções específicas para diferentes tratamentos englobando um mesmo tipo de exceção.

Na Listagem 6 é possível observar o código inicial refatorado, com o tratamento de erros do tipo TesteException já empregando Exception Filters. O resultado da execução destas instruções pode ser visualizado na Imagem 2.

using System;

namespace TesteExceptionFilters
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Testando a geração de exceções...");

            try
            {
                throw new TesteException("Gerando um erro para demonstração...");
            }
            //catch (TesteException ex) if (ex.NivelSeveridade == 1) -- Versões anteriores
            catch (TesteException ex) when (ex.NivelSeveridade == 1)
            {
                Console.WriteLine(
                    "Aconteceu um erro com um nível de severidade baixo...");
            }
            //catch (TesteException ex) if (ex.NivelSeveridade <= 3) -- Versões anteriores
            catch (TesteException ex) when (ex.NivelSeveridade <= 3)
            {
                Console.WriteLine(
                    "Aconteceu um erro com um nível de severidade moderado...");
            }
            catch (TesteException)
            {
                Console.WriteLine(
                    "Aconteceu um erro com um nível de severidade alto...");
            }

            Console.ReadKey();
        }
    }
}

Listagem 6: Exemplo de utilização dos Exception Filters

csharp06c02
Imagem 2. Resultado dos testes demonstrando o uso de Exception Filters

A nova versão do utilitário NuGet

O utilitário NuGet foi reformulado no Visual Studio 2015 (Imagem 3), com uma nova interface projetada para tornar mais simples o gerenciamento dos pacotes utilizados por projetos .NET.

csharp06c03
Imagem 3. A nova interface do utilitário NuGet

Dentre os novos recursos implementados, merecem destaque:

  • A interface gráfica, que deixou de ser um formulário modal e agora permite a abertura de diversas janelas para o gerenciamento de dependências nos diferentes projetos de uma solução;
  • É possível também a seleção da versão de um package a ser utilizado em um projeto, funcionalidade esta que representa uma solicitação antiga de muitos desenvolvedores (Imagem 4);
  • A possibilidade de consolidar as diferentes versões em uso de um pacote ao longo de vários projetos, de forma a se utilizar um único release do package em questão;
  • Opções de configuração para a resolução automática de conflitos que envolvam diferentes versões de uma mesma dependência.

csharp06c04
Imagem 4. Selecionando a versão de um package através do utilitário NuGet

Conclusão

Conforme aconteceu nos posts anteriores, esta terceira parte abordou mais uma vez novidades do C# 6.0 e do Visual Studio 2015. Embora a linguagem C# não tenha passado por modificações profundas, os recursos incorporados à mesma procuraram focar pontos como um menor esforço de codificação e a evolução de estruturas já existentes.

Agradeço novamente o feedback recebido nos outros 2 posts, lembrando que em breve estarei disponibilizando um quarto e último artigo.

Até uma próxima oportunidade!

Links

A C# 6.0 Language Preview
http://msdn.microsoft.com/en-us/magazine/dn683793.aspx

New Features in C# 6
http://blogs.msdn.com/b/csharpfaq/archive/2014/11/20/new-features-in-c-6.aspx

NuGet 3.0 Preview
http://blog.nuget.org/20141112/nuget-3.0-preview.html

The New and Improved C# 6.0
http://msdn.microsoft.com/en-us/magazine/dn802602.aspx

What’s New In C# 6.0
http://channel9.msdn.com/Events/Visual-Studio/Connect-event-2014/116

Renato Groffe

Atua como consultor em atividades voltadas ao desenvolvimento de softwares há mais de 13 anos. Bacharel em Sistemas de Informação, com especialização em Engenharia de Software. Microsoft Certified Technology Specialist (Web, WCF, Distributed Applications, ADO.NET, Windows Forms), Microsoft Specialist (HTML5 with JavaScript and CSS3, Developing ASP.NET MVC 4 Web Applications), Oracle Certified Associate (PL/SQL), Sun Certified (SCJP, SCWCD), ITIL Foundation V2, Cobit 4.1 Foundation.

Facebook Google+ 

Comentários

comentarios