Pular para o conteúdo principal

Classes: cuidado com esse inicializador!

Com o lançamento da versão 3.x do Microsoft .NET Framework, algumas facilidades foram acrescentadas na inicialização de objetos.

Você não precisa – embora deva– definir um construtor para a classe para que as propriedades sejam incializadas, logo, tornou-se possível ter um codigo semelhante ao seguinte:

    8 public class Funcionario

    9 {

   10    public string Nome { get; set; }

   11    public string Funcao { get; set; }

   12    public decimal Salario { get; set; }

   13 

   14    public void Imprime()

   15    {

   16       Console.WriteLine("Nome: {0}, função: {1}, salário {2:n2}",

   17          Nome, Funcao, Salario);

   18    }

   19 }

Sendo que esta classe pode ser inicializada da seguinte forma:

   20 public class Program

   21 {

   22    public static void Main(string[] args)

   23    {

   24       Funcionario meuFuncionario = new Funcionario

   25       {

   26          Nome = "Vladimir",

   27          Funcao = "Programador"

   28       };

   29 

   30       meuFuncionario.Imprime();

   31    }

   32 }

Mas, considere o seguinte: você escreveu uma classe em uma ClassLibrary e distribuiu em uma DLL. O que acontece se o programador esquecer de passar algum parâmetro como o código abaixo mostra?

   20 public class Program

   21 {

   22    public static void Main(string[] args)

   23    {

   24       Funcionario meuFuncionario = new Funcionario

   25       {

   26          Nome = "Vladimir"

   27       };

   28 

   29       meuFuncionario.Imprime();

   30    }

   31 }

No meu exemplo nada mais grave aconteceria pois a instrução Console.WriteLine() pode tratar com uma string nula. Mas, existem casos como por exemplo se precisarmos somar um valor, que, se este não estiver inicializado poderemos ter algum problema. Considere o seguinte código:

    8 public class Funcionario

    9 {

   10    public string Nome { get; set; }

   11    public string Funcao { get; set; }

   12    public DateTime DataContrato { get; set; }

   13 

   14    public void Imprime()

   15    {

   16       Console.WriteLine("Nome: {0}, função: {1}, data de admissão: {2:dd/MM/yyyy}",

   17          Nome, Funcao,

   18          DataContrato.Date);

   19    }

   20 }

   21 

   22 public class Program

   23 {

   24    public static void Main(string[] args)

   25    {

   26       // inicializa a classe sem passar o salario por dia

   27       Funcionario meuFuncionario = new Funcionario

   28       {

   29          Nome = "Vladimir",

   30          Funcao = "Programador"

   31       };

   32 

   33       // esta instrução irá demonstrar uma data incorreta

   34       meuFuncionario.Imprime();

   35    }

   36 }

Neste caso, uma data incorreta será exibida porque não passamos este valor para o objeto quando inicializamos.

Para resolver este e outros problemas que possam surgir com dados nulos, podemos criar um inicializador padrão sem parâmetros e passar todos os valores para os campos que devem ter um valor como no exemplo abaixo:

    8 public class Funcionario

    9 {

   10    public string Nome { get; set; }

   11    public string Funcao { get; set; }

   12    public DateTime DataContrato { get; set; }

   13 

   14    public Funcionario()

   15    {

   16       // inicializa um valor padrão

   17       DataContrato = DateTime.Today.Date;

   18    }

   19 

   20    public void Imprime()

   21    {

   22       Console.WriteLine("Nome: {0}, função: {1}, data de admissão: {2:dd/MM/yyyy}",

   23          Nome, Funcao,

   24          DataContrato.Date);

   25    }

   26 }

Desta forma, a data nunca estará nula, ainda que não apresente um valor apropriado.

Considere ainda que, alguns tipos como DateTime, decimal ou int, possui valores padrão por default.

Entretanto, se estivemos usando uma classe que tenha métodos, isto poderá causar um “Object Null Reference Exception”.

Outra forma de fazer isto é obrigar a passagem de valores para os campos que nunca deverão estar nulos criando um construtor personalizado:

    8 public class Funcionario

    9 {

   10    public string Nome { get; set; }

   11    public string Funcao { get; set; }

   12    public DateTime DataContrato { get; set; }

   13 

   14    public Funcionario(DateTime _Data)

   15    {

   16       // inicializa um valor padrão

   17       DataContrato = _Data;

   18    }

   19 

   20    public void Imprime()

   21    {

   22       Console.WriteLine("Nome: {0}, função: {1}, data de admissão: {2:dd/MM/yyyy}",

   23          Nome, Funcao,

   24          DataContrato.Date);

   25    }

   26 }

   27 

   28 public class Program

   29 {

   30    public static void Main(string[] args)

   31    {

   32       // classe sendo inicializada com o construtor obrigatório

   33       // e os valores demais propriedades

   34       Funcionario meuFuncionario = new Funcionario (DateTime.Today)

   35       {

   36          Nome = "Vladimir",

   37          Funcao = "Programador"

   38       };

   39 

   40       meuFuncionario.Imprime();

   41    }

   42 }

Desta forma, resolvemos o problema dos valores nulos.

Tratar erros antes que aconteçam é a melhor forma de lidar com eles.

Postagens mais visitadas deste blog

Como gerar scripts para exportar dados no SQL Server 2008

Uma das tarefas mais comuns no trabalho com desenvolvimento de software que consome dados em bancos como o SQL Server 2008 é a necessidade de em algum momento precisarmos exportar os dados de um banco para outro. Quer seja para realizar testes ou fazer simulações existem várias maneiras de se fazer isto. Neste post eu quero demonstrar um recurso do SQL Server Management Studio (SSMS) que permite realizar esta tarefa rapidamente.Para os que estão acostumados a usar esta ferramenta, já devem saber que é possível gerar scripts para o schema e também transferir os dados entre dois bancos distintos. Isto pode ser feito se o SSMS puder conectar-se com as duas bases, de origem e destino. No exemplo que vou dar, o objetivo é gerar o script apenas para uma tabela do banco de dados de exemplo da Microsoft – Northwind.1. Iniciando o assistenteO assistente deve ser iniciado clicando com o botão direito do mouse sobre o banco onde se encontra a tabela a qual iremos gerar o script. Deve se clicar n…

Pivot dinâmico com SQL Server

Passo a passo para usar pivoteamento dinâmicoOs bancos de dados bem configurados e definidos armazenam os dados de forma a otimizar o acesso, evitando duplicidade e garantindo a integridade. Porém, em muitas situações isto pode dificultar a apresentação de forma adequada sendo necessário preparar os dados usando vários recursos entre os quais, fazer o pivoteamento.Se você não precisou ainda usar ou não sabe o que é consiste em transformar cada linha de uma determinada coluna em colunas de uma nova consulta.Assim, considere uma tabela que armazene as notas bimestrais de um boletim. Uma possível estrutura para esta tabela seria algo assim:ColunaTipo de dado/TamanhoDisciplinanvarchar(50)BimestreIntNotanumeric(5,2)Uma consulta select nesta tabela com alguns dados traria um resultado parecido com o abaixo:Porém pode ser que para apresentar estes dados em um relatório seja necessário transformar cada bimestre em uma coluna e agrupar as notas nestas colunas para que fique dessa forma:Isto po…

Desabilitando o auto commit no SSMS (SQL Server Management Studio)

(Ou, como prevenir desastres e manter o emprego a salvo…)Neste post vai uma pequena mas tremendamente útil dica para desabilitar o auto commit da aplicação SQL Server Management Studio (SSMS) que é usada por dez entre dez usuários do banco de dados SQL Server para fazer consultas, alterações e executar scripts no banco de dados. (Preferências à parte, realmente muita gente usa),A primeira e mais importante notícia é que, diferentemente da ferramenta do Oracle, este editor de scripts do SQL Server vem com o recurso de auto commit ativado por padrão, assim, qualquer instrução DML (alteração dos dados com update, insert e delete) ou DDL (alteração no banco como create, drop, alter, etc.) será imediatamente enviada ao banco e persistida.Isto pode ser altamente crítico pois se estiver executando as instruções em um banco de dados de produção não haverá muitas formas de desfazer se é que haverá.Inicialmente, pode se evitar muitos acidades executando estas instruções dentro de um bloco BEGIN…