pontoNETpt
A comunidade PontoNetPT está direccionada a todos os programadores que trabalhem com a plataforma .NET.
MAIS UMA INTRO À .NET FRAMEWORK 2.0 - Parte I

Introdução

 

Este artigo foi desenvolvido a partir do meu próprio estudo para o exame de certificação Microsoft Technology Specialist e trata-se, sobretudo, de expor pelas minhas palavras aquilo que assimilei durante este processo.

Tem também referências a trabalhos de outros autores que eu acho que acrescentam valor ao conteúdo aqui exposto, sendo que este artigo é essencialmente baseado no MCTS Self-Paced Training Kit para o exame 70-536 – Microsoft .NET Framework 2.0—Application Development Foundation.

Um outro objectivo deste artigo é também ajudar todos os que tiverem interesse em efectuar o referido exame mas, por qualquer motivo, tenham decidido não adquirir o livro que está na base deste artigo.

Convenções

 

Texto em Itálico – Conteúdo em língua estrangeira

Texto em Courier New (10pt) – Conteúdo que representa pedaços de código-fonte

Capítulo 1 - Aspectos Fundamentais da .NET Framework 2.0

 

A .NET Framework 2.0, resumidamente, é uma plataforma de desenvolvimento de aplicações criada pela Microsoft com um foco muito grande no desenvolvimento de aplicações de um modo rápido (RAD) e com o objectivo de proporcionar uma plataforma independente de linguagem e de plataforma.

Neste capítulo irei introduzir alguns dos aspectos mais básicos da .NET Framework , como Tipos, Atributos e Encapsulação, focando também algumas novidades da .NET Framework 2.0 relativamente à 1.1 e 1.0, como Genéricos, entre outros.

Eu  assumo que quem está a ler este artigo tem pelo menos 2 anos de experiência de programação em .NET, independentemente da plataforma.

Todos os exemplos de código neste artigo serão em C#, excepto quando for necessário referir alguma especificidade da Framework que seja diferente em VB.

1.     Tipos de Valor

 

Um dos erros mais comuns que a maioria dos programadores cometem quando aprendem (e programam com) a .NET Framework tem a ver com a confusão que se faz, por um lado, entre Tipos de Valor e Tipos de Referência e, por outro, com a passagem de valores por Referência ou por Valor.

Tipos de Valor são os tipos mais simples que existem na .NET Framework e incluem todos os tipos de dados numéricos, booleanos, Char e Date, estruturas (mesmo que os seus membros sejam Tipos por Referência) e enumerados (uma vez que os seus tipos intrínsecos são sempre Byte, Short, Integer e/ou Long).

 

1.1.  Tipos de Valor Nativos

 

Estes tipos são os tipos base disponibilizados pela .NET Framework e são a base de construção de outros tipos. Derivam da Classe System.ValueType que, por sua vez, deriva de System.Object.

A principal característica destes tipos tem a ver com o facto de o seu valor estar armazenado na Stack em vez do Heap, ou seja, estão acessíveis mais rapidamente pelo código em excução.

Existem mais de 300 tipos de valor na .NET Framework, mas de entre os mais comuns destacam-se os seguintes:

·         Byte – 1 Byte. Armazena valores de bytes entre 0 e 255, sem sinal.

·         Sbyte - 1 Byte. Armazena valores de bytes entre -128 e 127.

·         Int16 (ou apenas short) – 2 Bytes. Armazena valores inteiros entre – 32768 e 32767.

·         Int32 (ou apenas int) -4 Bytes. Armazena valores inteiros entre – 2147483648 e 2147483647.

·         Uint32 (uint em C#) - 4 Bytes. Armazena valores inteiros entre 0 e 4294967295, sem sinal.

·         Int64 (ou apenas long) -8 Bytes. Armazena valores inteiros entre – 9223372036854776808 e 9223372036854776807.

·         Single (float em C#) - 4 Bytes. Armazena valores de vírgula flutuante entre – 3.402823E+38 e 3.402823E+38.

·         Double - 8 Bytes. Armazena valores de vírgula flutuante entre – 1.79769313486232E+308 e 1.79769313486232E+308.

·         Decimal - 16 Bytes. Armazena valores de vírgula flutuante entre – 79228162514264337593543950335 e 79228162514264337593543950335.

·         Char - 2 Bytes. Armazena um único caracter Unicode.

·         Boolean (ou apenas bool) - 4 Bytes. Armazena valores verdadeiro/falso.

·         DateTime (ou apenas date) - 8 Bytes. Armazena momentos no tempo entre 1/1/0001 e 31/12/9999.

Em tempo de execução, o desempenho dos tipos Int32 (int e uint) são optimizados, por isso é aconselhado o seu uso para contadores e outras variáveis que são utilizadas frequentemente. No caso de operações que necessitem de Tipos de vírgula flutuante, é recomendado o uso de Double, uma vez que o seu desempenho é optimizado ao nível do Hardware.

1.2.  Decalaração de Tipos de Valor

 

Para usar um Tipo de Valor é necessário declarar uma variável do tipo desejado. Estes Tipos possuem um construtor implícito, ou seja, ao declarar uma variável deste tipo estamos a instanciá-la imediatamente. Contudo, é recomendado que este tipo de variáveis seja inicializada logo na sua declaração:

int x = 0;

Uma das funcionalidades novas na .NET Framework 2.0 são os Tipos de Valor Nulos, ou seja, agora é possível criar variáveis de Tipos de Valor que aceitam valores nulos (por exemplo booleanos nulos). Para declarar variáveis de Tipos de Valor que aceitem valores nulos deve usar-se a seguinte sintaxe:

Nullable <int> x = null;

Ou ainda:

int? x = null;

Desta forma evitamos o (mais que) comum erroCannot convert null to 'int' because it is a value type”. Ao declararmos uma variável como Nullable torna disponíveis os membros HasValue e Value, que tornam possível determinar se esta variável tem um valor nulo e, no caso de não ter, ler o seu valor.

if (x.HasValue) // Boa, o valor de x não é nulo!

      Console.WriteLine(“O valor de x é {0}”), x.Value);

else // Ooops, o valor de x é nulo!

      Console.WriteLine(“x é nulo!”);

1.3.  Tipos de Valor Definidos pelo Utilizador (Estruturas)

 

Estruturas (structs) são Tipos de Valor definidos pelo programador, sendo um composto de outros Tipos de Valor que facilitam a utilização de dados inter-relacionados. Tal como os outros Tipos de Valor, são armazenados na Stack, o que os torna bastante eficientes (às vezes mais eficientes que classes). Para se definir estruturas deve fazer-se algo semelhante ao seguinte:

struct SerHumano

{

public float altura;

public float peso;

public short idade;

 

public SerHumano (float _altura, float _peso, short _idade)

{

altura = _altura;

peso = _peso;

idade = _idade;

}

 

public override string ToString()

{

return “Este Ser Humano mede “ + altura + " m, pesa " + peso + " kg e tem " + idade + “ anos.”;

}

}

De notar ainda um pormenor. As estruturas não podem ter um Construtor de defeito (sem parâmetros). O motivo tem a ver com o facto de, para Tipos de Valor, o compilador não gera um construtor de defeito nem uma chamada ao construtor de defeito na instanciação. Ou seja, mesmo que definissemos um construtor de defeito, ele não seria chamado. Para evitar isso, o compilador de C# não permite a sua definição.

Contudo, se utilizarmos o código abaixo, não existe uma chamada a um construtor sem parâmetros. Mas o compilador também não rejeita esta instrução. O que acontece é que os campos da Estrutura são todos inicializados a nulo ou zero, através da utilização do Opcode .InitObj do IL (Intermediate Language).

SerHumano k = new SerHumano();

As estruturas devem possuir as seguintes características:

·         Representar logicamente um valor único

·         Ter um tamanho de instância inferior a 16 Bytes

·         Não irão ser alteradas após a sua criação

·         Não irão ser convertidas para um Tipo de Referência

1.4.  Enumerados

 

Enumerados (Enums) são tipos especiais de Tipos de Valor. São símbolos relacionados com valores fixos e imutáveis. Ou seja, pode dizer-se que se tratam de constantes com nomes mais facilmente acessíveis.

O seu objectivo é simplificar a programação através da atribuição de nomes a valores fixos de uma lista de possíveis valores. Assim, em vez de se referenciar o seu valor, referencia-se o seu nome, tornando o código mais legível e bem estruturado.

public enum Titulos : int { Sr, Sra, Dr, Dra, Prof };

...

Titulos t = Titulos.Prof;

string name = “José Pedras”;

Console.WriteLine(“{0}. {1}”, t, name);

 

De seguida (no próximo artigo) irei falar-vos de Tipos por Referência.

?>


Posted 25-3-2007 17:12 por Pedro Honório Silva

Comments

Pedro Honório Silva wrote re: MAIS UMA INTRO À .NET FRAMEWORK 2.0 - Parte I
on 26-3-2007 0:50
Boas.

Antes de mais, muito obrigado pelo feedback.
De facto tens razão relativamente ao System.ValueType. Foi um typo. Não é um namespace, mas sim uma classe. Já corrigi! ;)

Também tens razão quanto ao construtor de defeito, mas quando referi que não tinha parâmetros era para deixar claro de que construtor estava a falar. Pelos vistos, se calhar teria sido mais claro se não tivesse referido os parâmetros.

Quanto ao .InitObj o que tu disseste é exactamente o mesmo que eu disse, mas por outras palavras, certo?

Quando digo que as estruturas não devem ser alteradas após a sua criação, refiro-me à estrutura em si, não aos seus campos. E o objectivo é dizer que estas estruturas devem ser usadas quando não se pretende alterar a estrutura (como pode ser feito com uma classe) nem se vai converter para um Tipo de Referência. Também alterei o texto de forma a ser mais claro.

Obrigado pelo feedback mais uma vez, ajudou-me a melhorar o texto e, consequentemente, a explicar melhor os conceitos, logo ajudando eventuais leitores do meu texto.

Um abraço.
Anonymous wrote re: MAIS UMA INTRO À .NET FRAMEWORK 2.0 - Parte I
on 1-7-2009 2:31
Boa tarde,

Parabéns pelo artigo. No entanto, queria deixar alguns comentários.

"Estes tipos são os tipos base disponibilizados pela .NET Framework e são a base de construção de outros tipos. Derivam do Namespace System.ValueType."

System.ValueType não é um espaço de nomes mas sim um tipo e qualquer tipo valor deriva de ValueType, não apenas os tipos valor nativos.

"As estruturas não podem ter um Construtor de defeito (sem parâmetros). O motivo tem a ver com o facto de, para Tipos de Valor, o compilador não gera um construtor de defeito nem uma chamada ao construtor de defeito na instanciação."

Antes de mais, para os mais distraídos, um construtor por omissão e um construtor sem parâmetros são duas coisas ligeiramente diferentes. A segunda é um construtor que não tem parâmetros e a primeira é o construtor sem parâmetros que o compilador gera na ausência de um definição do programador. Fica também a informação que é o compilador de C# que não permite a definição de um construtor sem parâmetros, isto porque ele também não gera um construtor por omissão para os tipos valor. No entanto é possível definir, ao nível do IL, um construtor sem parâmetros para os tipos valor. A título de curiosidade, é também por causa disto que não é possível colocar uma iniciação nos campos de um tipo valor:

struct X {
int a = 3; // inválido
}

A afectação seria colocada no construtor, mas como o compilador de C# não o gera, não tem sítio para a colocar.

"O que acontece é que os campos da Estrutura são todos inicializados a nulo ou zero, através da utilização do Opcode .InitObj do IL (Intermediate Language)."

Deixo aqui a nota de que é o compilador de C# que decide usar o initobj. Ao nível da plataforma, é possível invocar o construtor.

"Não devem ser alteradas após a sua criação"

Gostaria de uma explicação mais detalhada neste ponto. Não se deve alterar os campos de um estrutura após a sua criação? E porquê?

"Não devem ser convertidas para um Tipo Referência"

Estamos aqui a falar da acção de boxing, suponho. Acho que a dica deveria ser: Não devem ser utilizadas onde é esperado um tipo referência.

E atenção que as instâncias de tipos valor não estão sempre armazenadas no stack.
Anonymous wrote re: MAIS UMA INTRO À .NET FRAMEWORK 2.0 - Parte I
on 1-7-2009 2:31
Nullable <int> x = null;

Sou leitor assíduo do blog. Muito bom.
Anonymous wrote re: MAIS UMA INTRO À .NET FRAMEWORK 2.0 - Parte I
on 2-7-2009 2:27
Boa tarde,

Parabéns pelo artigo. No entanto, queria deixar alguns comentários.

"Estes tipos são os tipos base disponibilizados pela .NET Framework e são a base de construção de outros tipos. Derivam do Namespace System.ValueType."

System.ValueType não é um espaço de nomes mas sim um tipo e qualquer tipo valor deriva de ValueType, não apenas os tipos valor nativos.

"As estruturas não podem ter um Construtor de defeito (sem parâmetros). O motivo tem a ver com o facto de, para Tipos de Valor, o compilador não gera um construtor de defeito nem uma chamada ao construtor de defeito na instanciação."

Antes de mais, para os mais distraídos, um construtor por omissão e um construtor sem parâmetros são duas coisas ligeiramente diferentes. A segunda é um construtor que não tem parâmetros e a primeira é o construtor sem parâmetros que o compilador gera na ausência de um definição do programador. Fica também a informação que é o compilador de C# que não permite a definição de um construtor sem parâmetros, isto porque ele também não gera um construtor por omissão para os tipos valor. No entanto é possível definir, ao nível do IL, um construtor sem parâmetros para os tipos valor. A título de curiosidade, é também por causa disto que não é possível colocar uma iniciação nos campos de um tipo valor:

struct X {
int a = 3; // inválido
}

A afectação seria colocada no construtor, mas como o compilador de C# não o gera, não tem sítio para a colocar.

"O que acontece é que os campos da Estrutura são todos inicializados a nulo ou zero, através da utilização do Opcode .InitObj do IL (Intermediate Language)."

Deixo aqui a nota de que é o compilador de C# que decide usar o initobj. Ao nível da plataforma, é possível invocar o construtor.

"Não devem ser alteradas após a sua criação"

Gostaria de uma explicação mais detalhada neste ponto. Não se deve alterar os campos de um estrutura após a sua criação? E porquê?

"Não devem ser convertidas para um Tipo Referência"

Estamos aqui a falar da acção de boxing, suponho. Acho que a dica deveria ser: Não devem ser utilizadas onde é esperado um tipo referência.

E atenção que as instâncias de tipos valor não estão sempre armazenadas no stack.
Anonymous wrote re: MAIS UMA INTRO À .NET FRAMEWORK 2.0 - Parte I
on 2-7-2009 2:27
Nullable <int> x = null;

Sou leitor assíduo do blog. Muito bom.

Add a Comment

(requerido)  
(opcional)
(requerido)  
Remember Me?
If you can't read this number refresh your screen
Enter the numbers above:  
Powered by Community Server (Commercial Edition), by Telligent Systems