João Bosco 的个人资料João Bosco Seixas日志列表留言簿 工具 帮助

日志


10月22日

Fundamentos do Framework 2.0 - Tipos por Valor

Fundamentos do Framework

Tipo por Valor

 

 

Esse é o primeiro artigo de uma serie que irá falar sobre fundamento do .NET Framework 2.0 utilizando C#.

O objetivo é falar de alguns pontos importantes do framework para quem está começando com .NET 2.0

Grande parte do conteúdo foi baseado no livro Microsoft .NET FRAMEWORK 2.0 Application Development Foundation que serve de guia para prova 70-536 da Microsoft.

 

Vamos começar essa serie falando sobre algo muito básico. Os tipos por Valor.

Tipos por valor guardam diretamente os dados, enquanto tipos por referencia são apenas apontadores para alguma área de memória.

 

Os tipos por valor são guardados numa área de memória chamada stack(pilha), onde o runtime pode criar, ler, atualizar e deletar rapidamente, com o mínimo de sobrecarga.

Quando você copia um tipo por valor os dados da variável são copiados em outro ponto da pilha. Ficando assim armazenados em dois locais diferentes na pilha, se você altera um deles, o outro continua com o mesmo valor.

A vantagem mais obvia de se usar tipos por valor é a performance. Mais tarde discutiremos os ganhos com tipos por valor.

 

 

Existem 3 categorias básicas de tipos por valor

    • Built-in
    • User-Defined
    • Enumeration

 

Built-in, são tipos fornecidos pelo .NET Framework. Todos os tipos numéricos básicos inclusos no .NET Framework, são tipos por valor.

Exemplos:

 

      • sbyte 
      • byte   
      • short  
      • int      
      • uint    
      • long   
      • float   
      • double

 

 

 

*Nota do Livro*

Segundo os autores o runtime otimiza a performance dos inteiros de 32 bits ou seja, o int (System.Int32).

Para operações de ponto flutuante o recomendado seria double(System.Double), pois suas operações são otimizadas pelo hardware.

 

 

Alguns tipos não numéricos também são tipos por valor.

Exemplos:

char (System.Char)     bool(System.Boolean) date(System.DateTime)

 

Esses são os tipos mais comuns, porem existem outros tipos por valor que são fornecidos pelo framework.

 

Tipos por valor Built-in possuem construtores implícitos, por isso não há necessidade de se declarar com a palavra “new” como é feito com classes normais.

*Lembrando que todos as classes herdam de System.Object.*

Exemplos de inicialização em variáveis por valor.

int x;

bool k = false;

double y = 10.2;

 

No .NET FRAMEWORK 2.0, temos um novo tipo por valor, o Nullable.

Esse tipo pode assumir 3 valores (true, false, null).

Pode ser aplicado em uma rotina onde os valores possíveis são true e false, mas que se deseja ter um controle sobre o campo.

Exemplo, se o usuário preencheu o campo então a variável receberá true ou false de acordo com o escolhido pelo usuário, mas se o usuário não preencheu o campo, então o valor fica null.

Existem também outras possibilidades para o uso do Nullable

Um exemplo de declaração:

Nullable<bool> b = null;

 

Em um futuro artigo iremos falar sobre essa sintaxe de declaração do Nullable, abordando Generics.

 

 

Temos também os tipos User-Defined que são chamados de struturas ou structs.

As structs são tipos por valor, na maioria das vezes se parecem muito com uma classe, a única diferença é que ela é armazenada na pilha como se fosse um objeto referenciado por valor

 

 

Structs são agrupamentos de dados que facilitam o trabalho. Por exemplo, o System.Drawing.Point , que é um struct que contem as coordenadas X e Y de um ponto qualquer.

Você poderia perfeitamente criar uma variável inteira para X e outra para Y, mas agrupa-las numa struct provê uma forma mais fácil de trabalhar com as coordenadas, dando a possibilidade de usar um construtor por exemplo.

 

System.Drawing.Point ponto = new System.Drawing.Point(100,200);

 

 

Como se pode observer, a forma de se trabalhar com struct é idêntica a um classe. Para declarar uma estrutura, é usada a palavra reservada struct em C#.

Segue um exemplo de struct:

 

 struct ponto{

           

            int X, Y; //campos - atributos

           

            //Construtor que recebe as coordenadas X e Y como parametros

            public ponto(int coordX, int coordY){

                       

                        X = coordX;

                        Y = coordY;

}

 

            //Propriedade que manipula a coordenada X

            public int CoordenadaX{

                        get { return X; }

                        set  { X = value; }

}

 

//Propriedade que manipula a coordenada Y

public int CoordenadaY{

                        get { return Y }

                        set  { Y= value; }

}

} 

 

Como da para perceber, pode-se converter facilmente essa struct para uma classe, a diferença é que ela passará a ser um tipo por referencia e ocupará mais espaço na memória. Um tipo por valor, ocupa 4 bytes para cada campo inteiro. No caso dessa struct ela teria o tamanho de 8 bytes, já se fosse uma classe teria 16 bytes.

Structs são normalmente mais eficientes e performáticas que classes, pois um tipo por valor tem melhor desempenho que tipos por referencia.

Lembrando que quando se trabalha dessa maneira com structs, é importante sobrescrever alguns métodos como por exemplo o Equals().

 

Por ultimo vamos falar sobre enumerações, que também é um tipo por valor. Enums, como são comumente conhecidas,  facilitam a legibilidade do código, portanto é uma boa pratica de programação empregar essa funcionalidade sempre que possível. É muito simples de implementar, vamos a um exemplo:

 

           

 

 

 

 

 

enum diaSemana{

                        domingo,

segunda,

                        terca,

                        quarta,

                        quinta,

                        sexta,

                        sabado

}

 

 

O padrão do enumeration é começar a contagem do 0 e ir incrementando 1 a cada elemento.

No exemplo acima temos os seguintes valores:

Domingo = 0

Segunda = 1

Terca = 2

Quarta = 3

Quinta = 4

Sexta = 5

Sábado = 6

 

Porem podemos atribuir nosso próprios valores.

 

Enum mês { janeiro = 1, fevereiro, marco, maio, abril }

 

Nesse exemplo janeiro começa com 1 e os outros elementos são incrementados de 1. Podemos também ter o valor atribuído para todos os elementos.

 

Vamos ver agora 2 exemplos

 

int dia = diaSemana.segunda;

int dia = (int) diaSemana.segunda;

 

O primeiro exemplo está errado em C#, pois o valor de retorno de diaSemana.segunda não é um int.

Já o segundo exemplo está correto, pois faz o cast do valor de retorno para int.

 

As enumerações tem como padrão o tipo int, mas podem assumir outros tipos por valor como Byte, Int32 e UInt64.

Podemos criar um enum do tipo long, no exemplo abaixo podemos demonstrar isso.

enum maximo : long {

                        Max = 2147483648L,

                        Min = 255L

}

 

 

 

Lembrando que sempre será necessário o cast, caso deseje armazenar o valor do campo do enum numa variável, como demonstrado mais acima.

 

Lembrando que enum difere completamente de struct e obviamente de classes. Uma enumeração não pode definir métodos, não pode implementar interfaces e não define propriedades.

 

Em breve entraremos em outro tema, dando continuidade aos Fundamentos do Framework 2.0

Espero que tenham gostado.

Foi minha primeira experiência com blogs e construção de materiais.
Não tenho pretensão de ter feito um bom trabalho logo de primeira, mas acredito que com o tempo eu posso melhorar muito.

Espero que ajude alguem que está começando.

 

Abraços,

João Bosco.