Você está na página 1de 36

C# - Guia rpido

C# - Guia rpido........................................................................................................1 A linguagem de Programao C#.................................................................................................1 As caractersticas do C#...........................................................................................................2 Palavras-chave e palavras reservadas da linguagem C#.......................................................3 Definindo Constantes.............................................................................................................5 Converso de dados..............................................................................................................5 O condicional if......................................................................................................................8 O condicional switch..............................................................................................................9 Laos de repetio (loop)..........................................................................................................9 Tratamento de erros...............................................................................................................12 O try....................................................................................................................................13 O catch................................................................................................................................13 O finally...............................................................................................................................14 O throw................................................................................................................................15 Arrays e classes de colees (listas) ......................................................................................15 Trabalhando com Arrays......................................................................................................16 Acessando elementos do array............................................................................................16 Redimensionando arrays.....................................................................................................16 Arrays bidimensionais (matrizes).........................................................................................17 Classes de colees (listas).................................................................................................17 Passando arrays como parmetro.......................................................................................18 Formatando valores em C#.....................................................................................................18 Formatador padro..............................................................................................................18 Formatador customizado.....................................................................................................18 Criando um arquivo texto........................................................................................................19 Criando pastas no sistema de arquivos...................................................................................20 Movendo e Copiando arquivos................................................................................................20 Definindo classe e criando objetos.............................................................................................20 Utilizando Construtores...........................................................................................................24 Utilizando Destrutores.............................................................................................................25 Propriedades...........................................................................................................................25 Modificadores de acesso.........................................................................................................26 Mtodos e passagem de parmetros......................................................................................26 Os modificadores in/out/ref.....................................................................................................28 O modificador ref.................................................................................................................29 O modificador out................................................................................................................29 Herana...................................................................................................................................29 Polimorfismo...........................................................................................................................32 Converso entre as classes ....................................................................................................33 Classes Abstratas....................................................................................................................34 Interfaces................................................................................................................................35

A linguagem de Programao C#
A Microsoft define o C# como a principal linguagem de programao para uso na plataforma .NET. Por ser uma derivao da linguagem C++, sem as suas limitaes, e uma linguagem bastante simples de se programar. 1

As caractersticas do C#
Dentre as caractersticas essenciais do C# podemos citar: Simplicidade: os projetistas de C# costumam dizer que essa linguagem to poderosa quanto o C++ e to simples quanto o Visual Basic. Completamente orientada a objetos: em C#, tudo classe. System.Object a classe base de todo o sistema de tipos de C#. Fortemente tipada: isso ajuda a evitar erros por manipulao imprpria de tipos, atribuies incorretas etc. Case sensitive: diferencia caracteres maisculos e minsculos. Controle de verses: cada assemblie gerado, seja como EXE ou DLL, tem informao sobre a verso do cdigo, permitindo a coexistncia de dois assemblies homnimos, mas de verses diferentes no mesmo ambiente. Suporte a cdigo legado: o C# pode interagir com cdigo legado de objetos COM e DLLs escritas em uma linguagem no-gerenciada. Flexibilidade: se o desenvolvedor precisar usar ponteiros, o C# permite, mas ao custo de desenvolver cdigo no-gerenciado, chamado unsafe. Linguagem gerenciada: os programas desenvolvidos em C# executam num ambiente gerenciado, o que significa que todo o gerenciamento de memria feito pelo runtime via o GC (Garbage Collector), e no diretamente pelo programador, reduzindo as chances de cometer erros comuns em linguagens de programao onde o gerenciamento da memria feito diretamente pelo programador.

Ol Mundo: A estrutura bsica de uma aplicao C# (C Sharp)


O cdigo a seguir implementa um programa em modo console (caractere) que executado no prompt de comando. O resultado da execuo a sada Ol Mundo. Salve o cdigo abaixo num arquivo texto e d o nome de OlaMundo.cs. Observe que OlaMundo o nome da classe e do arquivo, e .cs a extenso do arquivo e tambm identifica qual linguagem o cdigo foi implementado, neste caso o C# (CSharp).
using System; //namespace public class OlaMundo //identificao da classe { public static void Main(string[] args) //identificao do mtodo principal { //cdigo Console.WriteLine("Ol Mundo!"); Console.ReadKey(); } }

Todo programa em C# uma classe. O programa acima bem primrio e possui 4 elementos bsicos, uma declarao de namespace, declarao da classe, um mtodo principal, e duas linhas de cdigo. Para compila-l necessrio usar o compilador C#, o CSC.exe. Ele encontrado no diretrio de instalao do .NET Framework e deve estar referenciado no path do Windows. Para referenciar o compilador digite PATH %path %;C:\Windows\Microsoft.NET\Framework\v3.5 no prompt de comando. Neste caso a verso do .NET Framework a 3.5. O programa pode ser compilado atravs do prompt de comando por meio da instruo csc OlaMundo.cs, se nenhum erro ocorrer, ser gerado um assemblie chamado OlaMundo.exe, s executar. Todo programa C# deve ter uma classe que defina o mtodo Main(), que deve ser declarado como esttico usando o modificador static, isto diz ao runtime que o mtodo pode ser chamado sem que a classe seja instanciada. atravs desse modificador que o runtime sabe qual ser o ponto de entrada do programa, para poder passar o controle ao runtime .NET. O M maisculo do mtodo Main obrigatrio, e seu valor de retorno void significa que o mtodo no retorna nenhum valor quando chamado. Veja o cdigo MSIL gerado pela compilao abrindo o assemblie gerado (OlaMundo.exe) com o programa IL Disassembler encontrado junto com o compilador da linguagem. Importante observar que strings em C# utilizam so delimitadas por aspas ( ) enquanto caracteres utilizam apstrofos ( ). Em C# permito 2 tipos de comentrios. No exemplo acima foram utilizados os dois tipos de comentrios: // e /* ... */.
Sintaxe // /* ... */ Descrio
Comentrio de linha: Comentrio iniciado por //, restrito a uma nica linha. Comentrio de bloco: Comentrio delimitado por /* e */, para blocos de cdigo.

Palavras-chave e palavras reservadas da linguagem C#


abstract as base bool break byte case catch char checked class event explicit extern false finally fixed float for foreach goto if new null object operator out override params private protected public readonly struct switch this throw true try typeof uint ulong unchecked unsafe

const continue decimal default delegate do double else enum

implicit in int interface internal is lock long namespace

ref return sbyte sealed short sizeof stackalloc static string

ushort using virtual volatile void while

Variveis, tipos de dados, converso entre tipos de dados e operadores


Esta sesso introduz os operadores, variveis e seus tipos em C# como tambm a converso entre os tipos de dados.

Variveis e seus tipos


A declarao de variveis no C# no possui um comando especfico como em outras linguagens de programao (Dim no Visual Basic e var no Javascript). A declarao de variveis em C# feita informando-se o tipo de dado a ser utilizado e em seguida o nome da varivel, conforme o exemplo a seguir.
string nome; int idade; //Declarando e inicializando a varivel na mesma instruo string sexo = M;

Tipos de dados
Tipo .NET Framework Sintaxe C# Faixa de Dados Significado Classificao
Value-types Value-types Value-types Um caractere Value-types Value-types

System.Boolean bool System.Byte System.SByte System.Char System.Decimal byte sbyte char decimal

True ou false (verdadeiro ouRepresenta valores true e falso) false 0 a 255 (8 bits) -128 a 127 (8 bits) 0 a 65535 (16 bits) Tipo numrico para clculos 1.0 10-28 a 7.9 1028 financeiros (28 casas (128 bits) decimais) 5.0 10-324 aPonto flutuante de preciso 1.7 10308 (64 bits) dupla (15 casas decimais) 1.5 10-45 a 3.4 1038Ponto Flutuante de preciso (32 bits) simples (7 casas decimais) -2.147.483.648 a Inteiro 2.147.483.647 (32 bits) 0 a 4.294.967.295 (32 bits) inteiro sem sinal 9.223.372.036.854.775.808 a 9.223.372.036.854.775.807Inteiro Longo (64 bits) 0 a 18.446.744.073.709.551.615 inteiro longo sem sinal (64 bits) -32.768 a 32.767 (16 bits) 0 a 65.535 (16 bits) Inteiro Short Um inteiro short sem sinal Inteiro de 8-bit sem sinal

System.Double double System.Single System.Int32 System.UInt32 System.Int64 System.UInt64 System.Int16 System.UInt16 System.String float int uint long ulong short ushort string

Value-types Value-types Value-types Value-types Value-types

Value-types

Value-types Value-types de Reference-Type

Seqncia de caracteres (16Uma sequncia bits por caractere) caracteres

Definindo Constantes
Outra estrutura importante que pode ser construda no C# so as constantes. As constantes so valores que no alteram seu valor durante a execuo do programa. Em geral so utilizados para parmetros de configurao ou para valores fixos representados por um nome para maior clareza. As constantes so declaradas atravs da palavra const, e assim como qualquer outra estrutura de programao deve ser declarada dentro de uma classe. O exemplo a seguir mostrar como declarar uma constante.
cont int segundos = 60;

Converso de dados
Quando precisamos atribuir o valor de uma varivel para outra varivel de um tipo diferente o C# exige a utilizao de uma funo de converso. Diferente de outras linguagens, como o Visual Basic, o C# exige a converso explicita de dados na maioria dos casos. Vamos analisar os diferentes tipos de converses possveis no C#.

Converso Explicita
A converso explicita pode ser feita atravs da utilizao de operadores de cast (converso). Um operador de cast utilizado informando-se o tipo de dados entre parnteses antes da atribuio do valor varivel de um tipo diferente. Um exemplo de operao de cast explicito pode ser observada a seguir.
int valorInteiro; double valorGrande = 10; //convertendo valorInteiro = (int)valorGrande;

No exemplo acima para converter um valor do tipo double para o tipo int, necessrio informarmos um operador de converso antes da atribuio (int). Se no informarmos a funo de converso, conforme o exemplo acima recebemos um erro de compilao.

Converso Implicita
Apesar da exigncia de uma funo de converso na maioria dos casos, conforme vimos no exemplo acima, existem alguns casos em que a funo de converso no se faz necessria. Quando fazemos a converso de um tipo de dados de menor magnitude para um de maior magnitude, a funo de converso no necessrio, tendo em vista que no corremos o risco de ter perda de valores no processo de converso, conforme o exemplo a seguir.
int valorInteiro = 10; double valorGrande; //convertendo valorGrande = valorInteiro;

Converses para strings


A converso de strings funciona de uma maneira um pouco diferente do que as converses apresentadas nos exemplos acima. As strings s podem ser convertidas atravs de funes especiais, capazes de realizar este tipo de converso. A converso de uma varivel qualquer para string um processo mais simples dentro de uma aplicao .NET. Para convertermos um valor para o tipo string, basta informarmos a chamada do mtodo ToString() aps o nome da varivel que possui o valor a ser convertido. Todo e qualquer tipo de dados do .NET possui a funo ToString e em alguns casos esta funo pode inclusive receber parmetros. Um exemplo de converso para o tipo string pode ser observado a seguir.
string mensagem; int valor1, valor2; valor1 = 10; valor2 = 15; int result = valor1 + valor2; mensagem = "O resultado da soma de 10 + 15 " + result.ToString();

No exemplo acima estamos somando duas variveis do tipo inteiro concatenando o valor convertido para string em uma varivel chamada mensagem.

Convertendo string para outros valores


A converso de strings para outros valores se d atravs do uso de uma classe especial para converso, a classe Convert. A classe Convert capaz de converter uma string para qualquer tipo primitivo de dados. A funo a ser utilizada deve ser To<Tipo de Dado>. Abaixo temos um exemplo de uso da classe Convert.
string numero = "1000"; int valor = Convert.ToInt32(numero); short valor2 = Convert.ToInt16(numero); DateTime dt = Convert.ToDateTime("01/01/2007");

Outra opo para converso de strings a utilizao da funo Parse de um tipo especfico. A maioria dos tipos de dados suporta a funo Parse, que permite a converso de string para um valor, conforme exemplo a seguir.
string numero = "1000"; int valor = Int32.Parse(numero); short valor2 = Int16.Parse(numero); DateTime dt = DateTime.Parse("01/01/2007");

Validando a converso de tipos


Muitas vezes precisamos testar o dado contido em uma varivel antes de realizamos sua converso para outro tipo de dado. Isso pode ser feito facilmente atravs de tratamentos excees, mas no uma boa prtica de programao, pois consome recursos desnecessrios para uma converso de tipo de dados. Algumas classes de definio de tipos oferecem o mtodo TryParse() que retorna um valor boleano que representa se a converso ocorreu com sucesso ou no, e retorna o valor convertido no segundo parmetro do mtodo como out. Mesmo que o retorno seja falso, ou seja no foi possvel realizar ele vai retornar o segundo parmetro inicializado com 0 (zero). Vejamos um exemplo.
string entradaDados; int resultado; Console.Write("Digite algo: "); entradaDados = Console.ReadLine(); if (int.TryParse(entradaDados, out resultado)) { Console.WriteLine(" inteiro."); } else { Console.WriteLine("NO inteiro."); } Console.WriteLine("Resultado da converso: {0} ", resultado); Console.ReadKey();

Principais operadores
Em C#, os operadores podem ser classificados da seguinte forma: aritmticos, unrios, lgicos, condicionais, relacionais, igualdade e de atribuio.
Operadores Aritmticos Uso
Soma tipos numricos. Tambm usado para concatenar strings. Efetua a diferena de tipos numricos. Efetua a diviso de tipos numricos. Efetua o produto de tipos numricos. Retorna o resto da diviso.

Operador + / * %

Operador Operador lgico AND usado para comparar expresses booleanas. && Operador lgico OR usado para comparar expresses booleanas. || Operador ternrio usado da seguinte forma: ?:
expr. a: expr. b? expr. c.

Operadores Condicionais Uso

Isso equivale a dizer: if (expr. a) expr. b; else expr. c;

Operador < > >= <= is as

Operadores Relacionais Uso


Condio menor que para tipos numricos. Condio maior que para tipos numricos. Condio maior ou igual que para tipos numricos. Condio menor ou igual que para tipos numricos. Compara em tempo de execuo se um objeto compatvel como um tipo qualquer. Esse assunto ser abordado mais adiante. Efetua mascaramento de tipos e caso este falhe, o resultado da operao ser null. Esse assunto ser abordado mais adiante.

Operadores de Igualdade Operador Uso Avalia a igualdade de dois tipos. == Avalia a desigualdade de dois tipos. != Operadores de Atribuio Operador Uso = *= /= %= += -= <<= >>= &= ^= |=
Atribuio simples. No caso de atribuio entre objetos, referncias so atribudas e no valores. Multiplicao seguida de atribuio. Exemplo: x*= 10 que equivalente a x = x*10. Diviso seguida de atribuio. Exemplo: x/= 10 que equivalente a x = x/10. Resduo seguido de atribuio. Exemplo: x%= 10 que equivalente a x = x % 10. Soma seguida de atribuio. Exemplo: x += 10 que equivalente a x = x + 10. Subtrao seguida de atribuio. Exemplo: x -= 10 que equivalente a x = x 10. Deslocamento de X esquerda pelo nmero de bits indicado pela segunda varivel/valor seguido de atribuio. Exemplo: x<<=5 que equivalente a x = x << 5. Deslocamento de X direita pelo nmero de bits indicado pela segunda varivel/valor, seguido de atribuio. Exemplo: x>>5 que equivalente a x = x >>5. Operao AND seguida de atribuio. Exemplo: x &= 0x0a que equivalente a x = x & 0x0a. Operao XOR seguida de atribuio. Exemplo: x ^= 0x0a que equivalente a x = x ^ 0x0a. Operao OR seguida de atribuio. Exemplo: x |= 0x0a que equivalente a x = x | 0x0a.

Tabela 1: Operadores suportados pela linguagem C#.

Comandos condicionais
Em C# existem dois tipos de condicionais: if e switch.

O condicional if
O if avalia uma expresso lgica booleana e qualquer outro tipo ser acusado como erro pelo compilador. Se o resultado for verdadeiro, o bloco de cdigo dentro do if ser executado, caso contrrio, o controle passado para a prxima declarao depois 8

do if. Os projetistas de C# optaram por aceitar unicamente expresses booleanas no if para evitar escrever cdigo com semntica obscura e propensa a resultados inesperados. A declarao if tem trs formas bsicas:
1.
if (expresso) { Declarao }

2.
if (expresso) { Declarao } else { Declarao }

3.
if (expresso) { Declarao } else if (expresso) { Declarao } else (expresso) { Declarao }

O condicional switch
A declarao switch avalia uma expresso cujo resultado pode ser dos tipos sbyte, byte, short, ushort, int, uint, long, ulong, char, string ou enum, e este por sua vez comparado com cada uma das sees case que constituem o switch. Vejamos a sua sintaxe:
switch(expresso) { case constante1: declarao 1; break; case constante2: declarao 2; break; 57 ... [default: declaraes; break; ] }

Em C#, obrigatrio que cada seo case tenha uma declarao break. A seo default, avaliada caso nenhuma das sees case forem verdadeira, equivale ao else do if. Seu uso no obrigatrio. E no pode existir mais de uma seo case com a mesma constante.

Laos de repetio (loop)


A linguagem C# d suporte a quatro tipos diferentes de laos: for, foreach/in, while, e do/while.

O lao for
O lao for trabalha checando uma condio para executar um bloco de cdigo at que essa condio seja verdadeira, no caso do lao for temos que em sua sintaxe declarar sua inicializao, sua condio e seu incremento, veja: 9

for (int i = 0; i <= 10; i++) { //instrues }

No cdigo acima temos a sintaxe um lao for onde na primeira parte declaramos uma varivel do tipo inteiro (int) e a inicializamos com o valor 0 (zero), na segunda parte temos a condio nesse caso verifica se a nossa varivel recm criada menor ou igual a 10 e a terceira e ltima parte o incremento desta varivel, sendo essas trs partes separadas por ';' (ponto e virgula). O funcionamento simples, todo cdigo dentro do bloco for ser executado dez vezes. Para abandonar o lao antes que a condio for seja falsa, usa-se a palavra reservada break.
for (int i = 0; i <= 10; i++) { Console.WriteLine("Iterao nmero {0}", i); if (i == 3) break; }

A palavra reservada continue permite que o fluxo de execuo da iterao corrente seja abandonado, mas no o lao, e que a iterao seguinte d incio no topo do lao, uma vez que a condio do for seja satisfeita.
for(int i=0; i<=10; i++) { Console.WriteLine("Iterao nmero {0}", i); if (i == 3) break; } for(int i=0; i<=10; i++) { Console.WriteLine("Iterao nmero {0}", i); if (i == 3) continue; // a declarao a seguir no ser executada quando i==3 Console.WriteLine ("Iterao nmero {0}", i +2 ); }

O lao foreach/in
O lao foreach usado para percorrer listas. Ele opera sobre Arrays ou colees veja sua sintaxe bsica:
foreach(<tipo de dado> <nome> in <lista>) { //instrues }

Vejamos um exemplo pratico para facilitar o entendimento:

10

string[] nomes = { "Maria", "Joo", "Sebastio", "Josefa" }; foreach (string pessoa in nomes) { Console.WriteLine("{0} ", pessoa); }

Criamos um array de string e colocamos alguns elementos dentro e no nosso lao foreach, como resultado ser exibido todos os elementos dentro de nosso array. As suas vantagens em relao ao lao for so as seguintes: No precisamos nos preocupar com a avaliao da uma condio booleana para garantir a sua execuo; Nem com a inicializao de variveis com o seu incremento/decremento; Nem com a forma de extrao do contedo do array ou coleo, j que ambos possuem formas diferentes de extrao dos seus valores; Quando todos os elementos do array/coleo tiverem sido varridos, o lao foreach/in ser abandonado; O uso do comando break valido para quebrar a execuo.

O lao while
De modo diferente do lao for (embora o objetivo seja o mesmo, ou seja, repetir a execuo de um cdigo testando uma condio) o lao while mais simples de ser entendido, pois sua sintaxe no requer que voc coloque na mesma linha a varivel de inicializao, a condio e o seu incremento. No lao while apenas colocamos a condio que queremos testar, veja como fica:
while (expresso booleana) { //instrues }

Veja como simples o cdigo. Expresso booleana uma expresso que sempre retorna falso ou verdadeiro e a instrues dentro do bloco de cdigo do lao while s ser executada enquanto essa expresso retornar verdadeiro. Veja um exemplo:
int contador = 2; while (contador != 10) { Console.WriteLine(contador.ToString()); contador++; }

Neste caso temos uma varivel chamada contador e seu valor 2, e no lao while testamos se a varivel contador diferente de 10, caso verdadeiro mostramos na tela o valor atual da varivel contador e o incrementos em 1 e o lao while continuar at que essa condio se torne falsa. 11

Temos de ter cuidado para no causar um loop infinito, ou seja, a condio nunca ser falsa e o lao vai continuar at travar a mquina. As palavras reservadas break e continue tambm podem ser usadas no lao while da mesma forma do lao for.

O lao do...while
Se fossemos analisar com cuidado lao while, veramos que dependendo do caso pode nunca ser executado, ou seja, se a condio do lao while retorna falsa de primeira ele nunca vai ser executado. No exemplo anterior se atribussemos o valor 10 a varivel contador em sua declarao, o lao while nunca comearia. Com o do.. while o cdigo ser executado ao menos uma vez porque verificao da condio no final da instruo, veja:
do { //instrues } while (expresso booleana)

Podemos traduzir do para faa, ou seja, faa as instrues enquanto (while) expresso seja verdadeira. Assim garantimos que ao menos uma vez as instrues sero executadas. Exemplo:
int contador = 10; do { Console.WriteLine(contador.ToString()); } while (contador != 10);

Veja que mesmo contador sendo igual a 10 a instruo ser executa ao menos uma vez porque s depois que fazemos a verificao. As palavras reservadas break e continue tambm podem ser usadas no lao do...while da mesma forma do lao for.

Tratamento de erros
Qualquer um que j foi um simples usurio de software j se deparou com uma mensagem de erro na sua frente, alguns softwares tm mensagens que s ajudam o desenvolvedor, alguns s o usurio e outros tem mensagens que no ajudo em nada. O tratamento de erros consiste em interceptar/capturar esses erros a fim de que o programa no aborte inesperadamente e informe ao usurio o que est errado. Na plataforma .NET esses erros so chamados excees (ou exceptions) e so tratados com as instrues try, catch e finally. O C# adota um estilo relativamente comum em outras linguagens, que o de tratar erros como objetos que encapsulam todas as informaes que necessitamos para resolv-lo. Essa ideia vlida para todo ambiente .NET e foi batizada como SEH (Structured Exception Handling). 12

A ideia bsica mais ou menos a seguinte: todo objeto que representa uma exceo derivado de System.Exception. Essa classe possui os seguintes membros:
Propriedade HelpLink Message Source Significado
Retorna uma URL para um arquivo de Help descrevendo o erro em detalhes. Esta propriedade somente leitura e descreve o erro. Retorna o nome do objeto ou aplicao que gerou o erro. Esta propriedade somente leitura e contm uma string que identifica

StackTrace a seqncia de chamadas que disparou o erro. InnerExcepti Pode ser usada para preservar os detalhes do erro ao longo de uma srie de excees. on

Para tratar as excees definimos um bloco do cdigo que o runtime ir "tentar" (try) executar, se algo der errado ele vai executar o que estiver num bloco especifico (catch) que contem o que fazer numa situao dessas. Nesse bloco normalmente disparamos alguma mensagem. Tambm possvel criar um bloco que ser sempre executado dando erro ou no (finally).

O try
O try o bloco de cdigo para escopo normal. As linhas de cdigo que voc simplesmente colocaria dentro do mtodo, passam a ficar dentro do bloco de try onde ser executado uma tentativa normal.
//Sem o uso do bloco try public void TesteMetodo1(string teste) { Console.Write((Convert.ToInt32(teste))+1); } //Com o uso do bloco try public void TesteMetodo2(string teste) { try { Console.Write((Convert.ToInt32(teste))+1); } catch{} }

No exemplo acima estamos convertendo um tipo string para inteiro. Isso s possvel se o valor contido na varivel teste seja um nmero inteiro. Assim runtime converte o valor de string para inteiro. Caso contrrio ser gerada uma exceo e o escopo do programa direcionado para o bloco catch ao qual iremos falar mais abaixo.

O catch
O catch o bloco que trata o erro gerado. Dentro deste bloco pode ser vista a mensagem do erro e feita a devida manipulao que o desenvolvedor quiser, como fechar o programa, retornar algo que identifique o erro ou simplesmente mostrar a mensagem de erro que foi gerada.
//Com o uso do bloco catch public void TesteMetodo(string teste) { try

13

Console.Write((Convert.ToInt32(teste))+1); } catch ( FormatException e) { Console.Write(e.Message.ToString()); }

No bloco catch anteriormente mostrado, apenas ser exiba a mensagem de erro a qual a exceo gerada mostra. O bloco catch pode ser repetido vrias vezes para serem tratados vrios tipos de exceo.
public void TesteMetodo(string teste) { try { Console.Write((Convert.ToInt32(teste))+1); } catch (FormatException e) { Console.Write(e.Message.ToString()); } catch (InvalidCastException e) { Console.Write(e.Message.ToString()); } }

Existe ainda um tipo de exceo padro para todos os erros. Este tipo de exceo chamado apenas de Exception e usada da seguinte forma.
public void TesteMetodo(string teste) { try { Console.Write((Convert.ToInt32(teste))+1); } catch (Exception e) { Console.Write(e.Message.ToString()); } }

O finally
O finally como nome j diz o bloco de finalizao. Este bloco executado em qualquer circunstncia. Mesmo que o programa gere uma exceo o bloco finally ser executado. A ideia que existe um escopo rodando mesmo que o erro faa o programa parar, assim possvel fazer com que voc possa matar conexes ou coisas do tipo, para que essas coisas no consumam carga de processamento e memria.
public void testeMetodo(string teste) { string Resp = ""; try { Console.Write((Convert.ToInt32(teste))+1); Resp = "Funcionou"; } catch (Exception e) { Console.Write(e.Message.ToString()); Resp = "Erro"; } finally {

14

} }

Console.Write(Resp);

No cdigo mostrado acima, se o escopo normal for realizado dentro do bloco try, quando ele for executar o finally ir mostrar a mensagem Funcionou. Caso contrrio, quando for executado o catch ir mudar o valor para Erro e assim quando for executado finally ir ser mostrada esta mensagem na tela.

O throw
O throw um complemento aos blocos de cdigo. Ele tem como funo explodir uma exceo que pode ou no ser criada pelo usurio.
public static void { string Resp = int saida; try { if (teste { throw } TesteMetodo(string teste) "";

== null) new ArgumentNullException();

if (!Int32.TryParse(teste, out saida)) { throw new Exception("Valor invlido."); } Console.Write(saida + 1); Resp = "Funcionou";

} catch (ArgumentNullException e) { Console.Write(e.Message.ToString()); Resp = "Informe um parmetro."; } catch (Exception e) { Console.Write(e.Message.ToString()); } finally { Console.Write(Resp); } }

No exemplo mostrado checado se a varivel teste nula. Caso a mesma esteja nula estourada uma exceo de valor NULL, fazendo com que o escopo do programa seja direcionado para o bloco catch. tambm testado se o valor um inteiro, se no estourada outra exceo.

Arrays e classes de colees (listas)


De forma simples um array um conjunto de elementos de um mesmo tipo de dado onde cada elemento desse conjunto acessado atravs de um ndice. Um array tambm conhecido como vetor (quando unidimensional) ou matriz (quando bidimensional).

15

Trabalhando com Arrays


Alm das variveis normais, o C# ainda possui suporte a criao de arrays. Os arrays so declarados de forma semelhante s variveis convencionas, mas possuem um modificador [ ] que indica que a varivel um array, conforme exemplo.
// Apenas um inteiro int valor; // Um array de inteiros int[] valores;

Quando declaramos um array no C#, este array encontra-se em um estado no inicializado. Para inicializar um array devemos utilizar o comando new indicando o tamanho a ser alocado para o array. O tamanho do array informado dentro dos colchetes, conforme exemplo a seguir.
// Array com 5 inteiros int[] valores = new int[5]; //Array com 10 nomes, de 0 9 string[] nomes = new string[10];

possvel ainda inicializar o array no seu dimensionamento, bastando para isto informar os itens do array logo aps o comando new entre chaves, conforme o exemplo a seguir.
// Array com 5 inteiros int[] valores = new int[5] { 1, 2, 3, 4, 5 }; // Sem informar a dimenso string[] nomes = new string[] { "Nome1", "Nome2", "Nome3" };

Acessando elementos do array


Para acessarmos elementos dos arrays, devemos informar entre colchetes o ndice do array a ser acessado. Os arrays sempre iniciam pelo ndice 0, conforme o exemplo a seguir.
nomes[0] = "Nome1"; nomes[1] = "Nome2"; string var = nomes[3];

Redimensionando arrays
Para redimensionarmos um array no C# devemos utilizar uma funo da namespace System.Array, a funo Resize. Esta funo possibilita o redimensionamento do array.
string[] nomes = new string[2]; nomes[0] = "Nome1"; nomes[1] = "Nome2"; System.Array.Resize(ref nomes, 3); nomes[2] = "Nome3";

16

Arrays bidimensionais (matrizes)


Vamos declarar um array de duas dimenses utilizando o modificar [,], veja:
int[,] matriz = new int[2, 2];

Na sintaxe acima declaramos um array bidimensional com duas linhas e duas colunas, ou seja, temos um array com 4 posies:
matriz matriz matriz matriz [0, [0, [1, [1, 0] 1] 0] 1] = = = = 1; 2; 3; 4;

A ordem de acesso sempre coluna x linha.

Classes de colees (listas)


Apesar de suportar array, as operaes com este tipo de estrutura em geral so complexas de se implementar. O mais comum utilizarmos as classes de coleo. Estas classes abstraem a complexidade dos array, tornando o redimensionamento e a obteno de itens automtica. As classes de coleo fazem parte do namespace System.Collections. A seguir temos um exemplo da utilizao da classe ArrayList.
System.Collections.ArrayList lista = new System.Collections.ArrayList(); lista.Add("Nome1"); lista.Add("Nome2"); lista.Add("Nome3"); lista.Remove("Nome2"); lista.RemoveAt(0);

possvel observar que utilizando o ArrayList no h necessidade de redimensionamento quando inserimos ou removemos um item. Analogamente a classe ArrayList, a classe List do namespace System.Collections.Generic permite a criao de uma coleo para armazenamento de um conjunto de dados quaisquer. A diferena entre as duas bibliotecas que a biblioteca genrica nos permite informar o tipo de dados o que queremos armazenar na coleo. Esta informao indicada na declarao da coleo pelo parmetro T, onde devemos informar o tipo de dados a ser utilizado. O exemplo a seguir cria uma lista de nmeros inteiros e outra lista de uma classe definida pelo usurio.
//Lista de valors inteiros List<int> listaInteiros = new List<int>(); listaInteiros.Add(10); int valor = listaInteiros[0]; //Lista de instncia de uma classe definida pelo usurio

17

List<MinhaClasse> listaMinhaClasse = new List<MinhaClasse>(); listaMinhaClasse.Add(new MinhaClasse());

Passando arrays como parmetro


Ao se passar um array como parmetro por valor (in), os seus elementos se comportam como se fossem passados por referncia. Isso significa que se alterarmos o valor de um elemento do vetor dentro do mtodo, essa alterao vai ocorrer tambm no elemento do vetor passado como parmetro.

Formatando valores em C#
Existem situaes em que necessitamos formatar valores do tipo Data, Dinheiro, Inteiros ou Decimais. No C# temos dois grupos de formatadores, formatador padro formatador customizado.

Formatador padro
A sintaxe a seguinte: [Formato][Qtde. Casas Decimais]. O caracter que vem aps os dois pontos o formato em que o valor ser exibido. Voc tambm poder optar por definir a quantidade de casas decimais da seguinte forma: C2. A seguir uma lista com os valores possveis:
Formatador Padro
C D E F G N P X Exibe Exibe Exibe Exibe Exibe Exibe Exibe Exibe o o o o o o o o valor valor valor valor valor valor valor valor no no no no no no no no formato formato formato formato formato formato formato formato

Descrio
de moeda. decimal. cientfico (exponencial). fixo. geral. numrico. de porcentagem. hexadecimal.

Os caracteres acima que especificam o formato a ser exibido, no so casesensitive, exceto para o X, pois se ele for minsculo os valores sero apresentados em minsculo, do contrrio, sero exibidos em maisculo.

Formatador customizado
Usado para formatar data e hora.
Formatador Customizado
MM/dd/yyyy dd/MM/yyyy HH:mm HH:mm:ss dd/MM/yyyy hh:mm:ss Formato Formato Formato Formato

Descrio
Ms/Dia/Ano. Dia/Ms/Ano. Hora:Minuto. Hora:Minuto:Segundo.

Formato Dia/Ms/Ano Hora:Minuto:Segundo.

Devemos nos atentar para o MM e para o mm, pois o maisculo significa Ms, j o minsculo significa Minutos. Pode-se tambm ao invs de barras "/" utilizar o hfen "-" 18

como separador para as Datas, ficando a string de formatao da seguinte forma: {0:dd-MM-yyyy hh:mm:ss}. Tambm existe diferena para o formatador que representa a hora. HH representa o formato 24 horas enquanto, hh representa o formato 12 horas.

Criando um arquivo texto


Para manipulao de arquivos devemos importar o namespace System.IO, vamos agora criar um arquivo texto onde escreveremos algumas informaes como exemplo. Existem vrias maneiras de se abrir um arquivo texto no C#. Uma maneira muito simples utilizando as classes StreamReader e StreamWriter. Estas classes permitem a gravao e a leitura de arquivos de uma maneira simples, fornecendo ainda mtodos para a gravao e leitura de Strings nestes arquivos. Para utilizarmos estas classes, basta criarmos uma instancia das mesmas informando em seu construtor o nome do arquivo a ser aberto. Atravs dos mtodos WriteLine e ReadLine, podemos gravar e ler informaes dos arquivos texto de uma maneira bem simples. No exemplo abaixo, iremos abrir um arquivo texto para gravao e gravar algumas informaes dentro dele.
StreamWriter file = new StreamWriter(@"C:\teste.txt"); file.WriteLine("TESTE file.WriteLine("TESTE file.WriteLine("TESTE file.WriteLine("TESTE file.Close(); Linha Linha Linha Linha 1"); 2"); 3"); 4");

Se executarmos o exemplo de gravao de arquivos apresentado acima mais de uma vez, veremos que o arquivo sobrescrito a cada execuo. Para criarmos um StreamWriter capaz de realizar uma operao de insero ao final de um arquivo (Append) basta informarmos um parmetro adicional no construtor do mesmo. No exemplo abaixo, estamos passando o valor de True para o parmetro de append, permitindo que as informaes sejam adicionadas no arquivo.

StreamWriter file = new StreamWriter(@"C:\teste.txt", true); file.WriteLine("TESTE file.WriteLine("TESTE file.WriteLine("TESTE file.WriteLine("TESTE file.Close(); Linha Linha Linha Linha 1"); 2"); 3"); 4");

Note que ao finalizarmos a gravao das informaes no arquivo, utilizamos o mtodo Close para fechar o Stream. importante fecharmos o arquivo sempre que terminamos de realizar qualquer operao com arquivos, do contrrio o arquivo ficar aberto. No exemplo abaixo, iremos criar uma instancia da classe StreamReader para ler o arquivo que acabamos de criar. Utilizaremos o mtodo ReadLine para ler as informaes do arquivo.
StreamReader fileRead = new StreamReader(@"C:\teste.txt");

19

string linha; while (fileRead.Peek() > -1) { linha = fileRead.ReadLine(); Console.WriteLine(linha); } fileRead.Close();

Notem que utilizamos o mtodo Peek da classe StreamReader. Este mtodo nos informa o nmero de caracteres restantes existentes no arquivo. Caso no existam mais caracteres a serem lidos, o mtodo Peek retorna o valor de -1.

Criando pastas no sistema de arquivos


Agora que j vimos como criar e ler arquivos, vamos criar uma nova pasta para colocar este arquivo que acabamos de criar com nosso programa de exemplo. No namespace System.IO existe uma classe chamada Directory. Esta classe possui mtodos para trabalharmos com pastas do sistema operacional. Para criarmos uma novo pasta basta chamarmos o mtodo CreateDirectory, conforme o exemplo abaixo.
Directory.CreateDirectory(@"C:\NovoDir");

Movendo e Copiando arquivos


A tarefa de mover arquivos e copiar arquivos tambm simples. Para isto, basta utilizar os mtodos compartilhados da classe File. O mtodo MoveFile utilizado para mover arquivos, enquanto o mtodo CopyFile utilizado para mover arquivos. No exemplo abaixo podemos ver um exemplo da utilizao dos dois comandos.
File.Copy(@"C:\teste.txt", @"C:\SubDir\Teste2.txt"); File.Move(@"C:\teste.txt", @"C:\SubDir\Teste.txt");

Definindo classe e criando objetos


Numa aplicao desenvolvida com uma linguagem orientada a objetos o trabalho pesado feito por classes. Mesmo aplicaes pequenas em C# necessitam da elaborao de uma ou mais classes, cada uma com suas propriedades e mtodos usados para executar as tarefas relativas ao objeto. Em C#, podemos ter dentro de uma classe os seguintes membros: atributos, construtores, destrutores, domnios, mtodos, propriedades, indexadores, delegates, eventos e nested classes. A criao de classe usa basicamente a sintaxe apresentada no listagem a seguir.
<using> <namespace1>; <using> <namespace2>; <public/private/protected> class <NomeDaClasse> { <public/private/protected> <tipo> <atributo1>; <public/private/protected> <tipo> <atributo2>; <public/private/protected> <tipo> <atributoN>;

20

<public/private/protected> <tipo retorno> <propriedade1>; <public/private/protected> <tipo retorno> < propriedade2>; <public/private/protected> <tipo retorno> < propriedadeN>; <public/private/protected> <tipo retorno> <mtodo1>; <public/private/protected> <tipo retorno> <mtodo2>; <public/private/protected> <tipo retorno> <mtodoN>; }

Vamos considerar uma aplicao de exemplo que defina uma classe Pessoa que armazene dados de uma pessoa como nome, sexo, idade, peso, altura, data de nascimento e salrio, e com estes atributos faa o clculo do ndice de massa corporal (IMC) e o aumente do salrio da pessoa. Nosso programa pode ser qualquer tipo de aplicao .NET (WindowsForms, ASP.NET, etc). E este far acesso a classe Pessoa. Dentro do projeto escolhido devemos criar uma classe chamada Pessoa. O listagem a seguir o cdigo de definio da classe Pessoa com seus atributos, propriedades, construtores, mtodos e destrutores.
/// <summary> /// Classe representando uma pessoa. /// </summary> public class Pessoa { private string _nome; /// <summary> /// Configura ou recupera o nome da pessoa. /// </summary> public string Nome { get { return _nome; } set { _nome = value; } } private EnumSexo _sexo; /// <summary> /// Configura ou recupera o sexo da pessoa. /// </summary> public EnumSexo Sexo { get { return _sexo; } set { _sexo = value; } } private int _idade; /// <summary> /// Recupera a idade da pessoa. /// </summary> public int Idade { get { return _idade; } } private double _peso; /// <summary> /// Configura ou recupera o peso da pessoa. /// </summary> public double Peso { get { return _peso; } set { _peso = value; } }

21

private double _altura; /// <summary> /// Configura ou recupera a altura da pessoa. /// </summary> public double Altura { get { return _altura; } set { _altura = value; } } private DateTime _dataNascto; /// <summary> /// Configura ou recupera a data de nascimento da pessoa. /// </summary> public DateTime DataNascto { get { return _dataNascto; } set { _dataNascto = value; _idade = CalcularIdade(DateTime.Now); } } private double _salario; /// <summary> /// Configura ou recupera o salrio da pessoa. /// </summary> public double Salario { get { return _salario; } set { _salario = value; } } /// /// /// /// /// /// /// /// /// { <summary> Construtor: Inicializa o objeto (Sobrecarregado) </summary> <param name="nome">Nome da pessoa</param> <param name="sexo">Sexo da pessoa</param> <param name="peso">Peso da pessoa</param> <param name="altura">Altura da pessoa</param> <param name="dataNascto">Data de nascimetno da pessoa</param> <param name="salario">Salrio da pessoa</param>///

public Pessoa(string nome, EnumSexo sexo, double peso, double altura, DateTime dataNascto, double salario)

_nome = nome; _sexo = sexo; _peso = peso; _altura = altura; _dataNascto = dataNascto; _idade = CalcularIdade(DateTime.Now); _salario = salario;

} /// <summary> /// Construtor padro (Sobrecarregado) /// </summary> public Pessoa() { _nome = ""; _sexo = EnumSexo.Masculino; _idade = 0; _peso = 0; _altura = 0; _dataNascto = DateTime.Now; _salario = 0; } /// <summary> /// Retorna o IMC da pessoa quando peso e altura so informados /// </summary> /// <returns>Valor do IMC</returns> public double IMC()

22

if ((Altura > 0) && (Peso > 0)) { return (Peso / System.Math.Pow(Altura, 2)); } return (0);

/// <summary> /// Retorna a classificao do peso da pessoa conforme o clculo do IMC. /// </summary> /// <returns></returns> public string IMCClassificacao() { double imc = IMC(); string retorno = "Seu IMC " + imc.ToString("N2") + ". "; if (imc < 18.5) retorno += "Voc est abaixo do peso ideal."; else if (imc <= 24.9) retorno += "Parabns. Voc est em seu peso normal!"; else if (imc <= 29.9) retorno += "Voc est acima de seu peso (sobrepeso)."; else if (imc <= 34.9) retorno += "Obesidade grau I."; else if (imc <= 39.9) retorno += "Obesidade grau II."; else retorno += "Obesidade grau III. Procure um mdico."; return (retorno); } /// <summary> /// Calcula a idade da pessoa. /// </summary> /// <param name="dataReferencia">Data em que se quer saber a idade da pessoa.</param> /// <returns></returns> protected int CalcularIdade(DateTime dataReferencia) { int idade = dataReferencia.Year - this._dataNascto.Year; return (idade); } /// <summary> /// Aumenta o salrio conforme o percentual informado. /// </summary> /// <param name="percentualAumento">Percentual de aumento do salrio.</param> /// <param name="novoSalario">Retorna o novo salrio aps o aumento.</param> public void AumentarSalario(double percentualAumento, out double novoSalario) { novoSalario = this._salario + (this._salario * (percentualAumento / 100)); this.Salario = novoSalario; } /// <summary> /// Aumenta o salrio da pessoa conforme o valor informado. /// </summary>
/// <param name="valorGratificacao">Entrada: valor do aumento de salrio; Sada: novo salrio com aumento</param>

public void AumentarSalario(ref double valorGratificacao) { valorGratificacao = this._salario + valorGratificacao; this.Salario = valorGratificacao; } /// <summary> /// Destrutor /// </summary> ~Pessoa()

23

{ } }

Classe Pessoa.

Aps implementao da classe Pessoa possvel instanci-la. Dentro do projeto utilize algum recurso de interface de usurio para instanciar. Uma classe instanciada por meio da palavra reservada new. A sintaxe bsica para criar um objeto a partir de uma classe Classe objeto = new Classe(); A classe Pessoa tem dois construtores, o primeiro o construtor padro que no recebe parmetros, enquanto o segundo permite inicializar o objeto com alguns parmetros. Vejamos os exemplos a seguir.
Pessoa pessoa = new Pessoa();

Classe Pessoa instanciada com seu construtor padro.


Pessoa pessoa = new Pessoa("Andr", EnumSexo.Masculino, 72, 1.82, 09/09/1981, 10000.00);

Classe Pessoa instanciada com construtor sobrecarregado.

Utilizando Construtores
As classes podem apresentar mtodos especiais chamados de construtores. Os construtores so mtodos especiais capazes de inicializar a classe com algum valor. O mtodo construtor pode ser identificado por um mtodo com o mesmo nome da classe. O construtor chamado sempre que instanciamos uma classe utilizando o comando new. Uma classe pode ter diversos construtores, cada um com uma assinatura diferente. Na classe Pessoa temos dois construtores, um construtor padro que no possui parmetros (assinatura 1), e um segundo com parmetros que inicializam os atributos da classe (assinatura 2). Vejamos o trecho de cdigo a seguir retirado da classe Pessoa.
/// /// /// /// /// /// /// /// /// { <summary> Construtor: Inicializa o objeto (Sobrecarregado) </summary> <param name="nome">Nome da pessoa</param> <param name="sexo">Sexo da pessoa</param> <param name="peso">Peso da pessoa</param> <param name="altura">Altura da pessoa</param> <param name="dataNascto">Data de nascimetno da pessoa</param> <param name="salario">Salrio da pessoa</param>/// _nome = nome; _sexo = sexo; _peso = peso; _altura = altura; _dataNascto = dataNascto; _idade = CalcularIdade(DateTime.Now); _salario = salario;

public Pessoa(string nome, EnumSexo sexo, double peso, double altura, DateTime dataNascto, double salario)

/// <summary> /// Construtor padro (Sobrecarregado) /// </summary> public Pessoa() { _nome = "";

24

_sexo = EnumSexo.Masculino; _idade = 0; _peso = 0; _altura = 0; _dataNascto = DateTime.Now; _salario = 0; }

Utilizando Destrutores
Quando o garbage collector faz o processo de desalocao dos objetos, podemos fazer com que uma funo seja executada antes que o objeto seja eliminado. Estas funes so chamadas funes destrutoras. Em geral utilizamos estas funes para destruirmos instncias de objetos no gerenciveis, tendo em vista que o framework no tem controle sobre este tipo de objeto. A implementao de um destrutor semelhante a sintaxe utilizada para construirmos um construtor, com a diferena que devemos utilizar o smbolo ~ na frente da declarao. O exemplo a seguir mostra o destrutor da classe Pessoa, que neste caso est vazio, ou seja, sem implementao, pois no houve necessidade.
/// <summary> /// Destrutor /// </summary> ~Pessoa() { }

Poderamos ter uma classe que faz uso de um objeto COM (componente VB6). Este objeto aloca uma srie de recursos no gerenciveis que so utilizados durante a execuo de mtodos da classe. Para garantirmos que os recursos deste objeto COM sejam liberados devemos implementar um destrutor para a classe, de forma a liberar qualquer recurso alocado pela classe COM.

Propriedades
Propriedades so mtodos que protegem (encapsulam) o acesso a membros da classe, ou seja, separa os elementos visveis de um objeto dos invisveis. Todos os atributos da classe Pessoa exemplificada anteriormente foram encapsulados, ou seja, protegidos por meio das suas respectivas propriedades. O cdigo a seguir foi retirado da classe Pessoa que declara o atributo _nome como privado, ou seja, somente acessado diretamente pela classe. Externamente (fora da classe) o atributo pode ser acessado pela propriedade Nome. As palavras reservadas get, e set indicam que a propriedade pode recuperar (get) o valor do atributo _nome e receber (set) um novo valor.
private string _nome; /// <summary> /// Configura ou recupera o nome da pessoa. /// </summary> public string Nome { get { return _nome; } set { _nome = value; } }

25

Modificadores de acesso
Os modificadores de acesso dizem ao compilador a forma como classe e seus membros podem ser acessados externamente. Veja na tabela a seguir os modificadores:
Modificadores de Acesso - CLASSES Tipo de Acesso
Permite que a classe seja acessada por qualquer assemblie. No permite que a classe seja herdada. Permite que a classe tenha seu escopo dividido em vrios arquivos. Especifica que a classe somente tem membros estticos. No pode ser instanciada. Define moldes para classes filhas. No pode ser instanciada.

Modificador
Public Selead Partial Static Abstract

Modificadores de Acesso MEMBROS DA CLASSE Modificador Tipo de Acesso


Public Protected Private Internal Static Abstract Virtual Readonly Permite que os membros das classes sejam acessados por qualquer outro escopo Permite que membros sejam usados apenas pela classe que o contm e permite que estes sejam herdados para classes derivadas da original. O membro de uso exclusivo da classe onde declarado. Permite acesso somente por classes do mesmo assemblie. Permite acesso, sem necessidade do objeto ser instanciado. So mtodos de classes Abstract que no possuem implementao (sem codificao). Permite que os mtodos sejam sobrescritos por classes filhas. Limita acesso a somente leitura aos atributos da classe

Quando o modificador de acesso no especificado para atributos, o compilador assume o modificador private como padro. Para classes o modificador padro public.

Mtodos e passagem de parmetros


No C# os mtodos so anlogos a funes e procedimentos em outras linguagens de programao como C e Pascal. Um mtodo pode ter variveis locais, que so variveis declaradas dentro do mtodo e s podem ser utilizadas (escopo) apenas dentro do mtodo onde foram declaradas. Os parmetros do mtodo tambm so locais a ele. Inicialmente preciso informar o tipo de visibilidade do mtodo por meio dos modificadores de acesso a membros (visto anteriormente). Logo aps necessrio informar o seu tipo de retorno. Caso o mtodo no tenha nenhum retorno (o que equivalente as sub-rotinas em outras linguagens) dever ser utilizada a palavra reservada void. Em seguida dado um nome ao mtodo, e entre parnteses, o conjunto de parmetros aceitos pelo mtodo, se necessrio. Os parmetros so declarados da mesma forma que as variveis (tipo de dado seguido do nome do parmetro) e devem ser separados por vrgula. Aps a declarao dos parmetros devemos ento informar o corpo do mtodo entre chaves. Para mtodos que retornam algum valor obrigatrio informar a clusula return com o valor de retorno dentro do corpo do mtodo. 26

Vejamos alguns exemplos.


//Mtodo simples, sem retorno e sem parmetros (Equivalente a procedimentos em outras linguagens) protected void NomeDoMetodo() { } //Mtodo sem retorno e com parmetros (Equivalente a procedimentos com parmetros em outras linguagens). protected void NomeDoMetodo(string param1, int param2) { } //Mtodo que retorna uma string e com parmetros. (Equivalente a funo em outras linguagens). protected string NomeDoMetodo(string param1, int param2) { } return(string de retorno);

O cdigo cima apresenta trs mtodos, o primeiro sem retorno e sem parmetros, o segundo sem retorno e com parmetros e o ltimo com retorno e parmetros. A classe Pessoa usada como exemplo apresenta 3 mtodos, IMC, IMCClassificacao e AumentarSalario, sendo este ltimo sobrecarregado duas vezes. O primeiro retorna o valor do IMC, o segundo retorna a classificao do IMC da pessoa, e o ltimo aumenta o salrio da pessoa conforme os parmetros da assinatura do mtodo. Tambm apresenta um quarto mtodo protegido, CalcularIdade, recebendo como parmetro uma data de referncia para o clculo da idade da pessoa.
/// <summary> /// Retorna o IMC da pessoa quando peso e altura so informados /// </summary> /// <returns>Valor do IMC</returns> public double IMC() { if ((Altura > 0) && (Peso > 0)) { return (Peso / System.Math.Pow(Altura, 2)); } return (0); } /// <summary> /// Retorna a classificao do peso da pessoa conforme o clculo do IMC. /// </summary> /// <returns></returns> public string IMCClassificacao() { double imc = IMC(); string retorno = "Seu IMC " + imc.ToString("N2") + ". "; if (imc < 18.5) retorno += "Voc est abaixo do peso ideal."; else if (imc <= 24.9) retorno += "Parabns. Voc est em seu peso normal!"; else if (imc <= 29.9) retorno += "Voc est acima de seu peso (sobrepeso)."; else if (imc <= 34.9) retorno += "Obesidade grau I."; else if (imc <= 39.9)

27

retorno += "Obesidade grau II."; else retorno += "Obesidade grau III. Procure um mdico."; return (retorno); } /// <summary> /// Calcula a idade da pessoa. /// </summary> /// <param name="dataReferencia">Data em que se quer saber a idade da pessoa.</param> /// <returns></returns> protected int CalcularIdade(DateTime dataReferencia) { int idade = dataReferencia.Year - this._dataNascto.Year; } return (idade);

/// <summary> /// Aumenta o salrio conforme o percentual informado. /// </summary> /// <param name="percentualAumento">Percentual de aumento do salrio.</param> /// <param name="novoSalario">Retorna o novo salrio aps o aumento.</param> public void AumentarSalario(double percentualAumento, out double novoSalario) { novoSalario = this._salario + (this._salario * (percentualAumento / 100)); this.Salario = novoSalario; } /// <summary> /// Aumenta o salrio da pessoa conforme o valor informado. /// </summary> public void AumentarSalario(ref double valorGratificacao) { valorGratificacao = this._salario + valorGratificacao; this.Salario = valorGratificacao; }

/// <param name="valorGratificacao">Entrada: valor do aumento de salrio; Sada: novo salrio com aumento</param>

Os modificadores in/out/ref
Quando criamos parmetros em mtodos do C#, estes parmetros so passados por padro como valores (in), ou seja, se estes valores forem alterados durante a execuo do mtodo, a mudana destes valores no ser refletida na varivel passada por parmetro. Este comportamento atribudo ao modificador de parmetro in, que implcito e no precisa ser informado. O exemplo abaixo extrado da classe Pessoa utiliza passagem de parmetros por valor.
/// <summary> /// Calcula a idade da pessoa. /// </summary> /// <param name="dataReferencia">Data em que se quer saber a idade da pessoa.</param> /// <returns></returns> protected int CalcularIdade(DateTime dataReferencia) { int idade = dataReferencia.Year - this._dataNascto.Year; } return (idade);

No exemplo acima, mesmo que o parmetro dataReferencia fosse alterado dentro do mtodo seu valor externamente no seria modificado. Este comportamento pode ser alterado utilizado os moficadores ref e out. 28

O modificador ref
O parmetro ref permite a passagem de valores por referncia. Utilizando a passagem de valores por referncia, os valores modificados dentro da funo refletem suas alteraes para a funo chamadora. Para utilizarmos o operador ref, devemos inform-lo tanto na declarao do parmetro como tambm na chamada do mtodo. Necessariamente o uso do ref requer que a varivel a ser passada como parmetro seja inicializada antes de passar sua referncia. Vejamos um exemplo.
... double gratificacao = 1000.00; pessoa.AumentarSalario(ref gratificacao); ... /// <summary> /// Aumenta o salrio da pessoa conforme o valor informado. /// </summary> public void AumentarSalario(ref double valorGratificacao) { valorGratificacao = this._salario + valorGratificacao; this.Salario = valorGratificacao; }

/// <param name="valorGratificacao">Entrada: valor do aumento de salrio; Sada: novo salrio com aumento</param>

O modificador out
A diferena entre o modificador out e o ref que o out permite a passagem de uma varivel no inicializada por parmetro, o que no permitido em parmetros ref. Veja o exemplo a seguir.
... double novoSalario; pessoa.AumentarSalario(double.Parse(20, out novoSalario); ... /// <summary> /// Aumenta o salrio conforme o percentual informado. /// </summary> /// <param name="percentualAumento">Percentual de aumento do salrio.</param> /// <param name="novoSalario">Retorna o novo salrio aps o aumento.</param> public void AumentarSalario(double percentualAumento, out double novoSalario) { novoSalario = this._salario + (this._salario * (percentualAumento / 100)); this.Salario = novoSalario; }

Quando utilizamos o modificador out, a varivel deve obrigatoriamente ser inicializada dentro da funo que contem o parmetro out.

Herana
A herana um conceito extremamente utilizado dentro do .NET Framework. Este conceito utilizado quando precisamos que uma determinada classe tenha todas as caractersticas de outra classe com algumas modificaes em seu comportamento, ou mesmo algumas funcionalidades adicionais. 29

No C# possvel uma classe suportar somente uma herana. Portanto, podemos especificar somente uma classe base numa classe filha. A herana mltipla conquistada atravs do uso de interfaces.
using System; public class ClassePai { public ClassePai() { Console.WriteLine("Construtor da Classe Pai."); } public void Imprimir () { Console.WriteLine("Eu sou a Classe Pai."); } } using System; public class ClasseFilha : ClassePai { public ClasseFilha() { Console.WriteLine("Construtor da Classe Filha."); } }

public class Program { public static void Main() { ClasseFilha classeFilha = new ClasseFilha(); classeFilha. Imprimir(); Console.ReadKey(); } }

Listagem 1: Herana em C#.

A Listagem 1 mostra duas classes. A primeira classe chamada ClassePai (base), a segunda a ClasseFilha que herda a ClassePai. Veja que na assinatura da classe ClasseFilha estabelecida a herana com a ClassePai atravs do :.
public class ClasseFilha : ClassePai

O exemplo da Listagem 1 representado graficamente fica assim:


ClassePai
Class

Methods ClassePai Imprimir

ClasseFilha
Class ClassePai

Methods ClasseFilha

Depois de estabelecida a herana, a classe derivada tem exatamente as mesmas capacidades da classe base. Portanto, pode-se dizer, a ClasseFilha "" uma ClassePai. 30

Isso demonstrado no mtodo Main da classe Program. A ClasseFilha no tem o seu prprio mtodo Imprimir, por isso usa o mtodo Imprimir da ClassePai. A classe base automaticamente instanciada antes de suas classes derivadas. Isso pode ser constatado observando o resultado da sada do exemplo da Listagem 1, onde o construtor da ClassePai o primeiro a ser executado, e depois o construtor da ClasseFilha. Pode haver a necessidade de se criar uma nova implementao de um mtodo existente na classe base, o que totalmente possvel de se fazer. Na Listagem 2 a classe ClasseFilha declara seu prprio mtodo Imprimir e ainda faz uma chamada ao mtodo Imprimir da classe base atravs da palavra reservada base. Observe uma pequena mudana na assinatura do mtodo Imprimir da ClasseFilha, agora temos a palavra reservada new indicando uma nova implementao do mtodo Imprimir da ClassePai.
using System; public class ClassePai { public ClassePai() { Console.WriteLine("Construtor da Classe Pai."); } public void Imprimir() { Console.WriteLine("Eu sou a Classe Pai."); } } using System; public class ClasseFilha : ClassePai { public ClasseFilha() { Console.WriteLine("Construtor da Classe Filha."); } public new void Imprimir() { base. Imprimir(); //Invoca o mtodo Imprimir da classe base Console.WriteLine("Eu sou a Classe Filha."); } }

public class Program { public static void Main() { ClasseFilha classeFilha = new ClasseFilha(); classeFilha. Imprimir(); Console.ReadKey(); } }

Listagem 2: Invocando mtodo da classe base.

As classes que herdam caractersticas de outras classes podem precisar alterar propriedades ou mesmo chamar mtodos que esto disponveis na classe base, como ocorreu no exemplo da Listagem 2. Isto perfeitamente possvel caso tenhamos estes mtodos ou propriedades com visibilidade public ou protected. Porm se estes mtodos possurem visibilidade private, podero ser vistos apenas na classe base e a classe filha no poder ter acesso a estes valores. 31

Polimorfismo
Polimorfismo o princpio pelo qual duas ou mais classes derivadas de uma mesma classe base podem invocar mtodos que tenham a mesma identificao (assinatura) mas comportamentos diferentes, especializados para cada classe derivada, usando para tanto uma referncia a um objeto do tipo da classe base. Antes de verificarmos como o polimorfismo funciona sob o ponto de vista do usurio da classe, vamos ver como podemos implementar comportamentos diferentes para um mesmo mtodos na classe base e na classe filha.
using System; public class ClassePai { public ClassePai() { Console.WriteLine("Construtor da Classe Pai."); } public virtual void Imprimir() { Console.WriteLine("Eu sou a Classe Pai."); } } using System; public class ClasseFilha1 : ClassePai { public ClasseFilha1() { Console.WriteLine("Construtor da Classe Filha."); } public override void Imprimir() { base.Imprimir(); Console.WriteLine("Eu sou a Classe Filha."); } } using System; public class ClasseFilha2 : ClassePai { public ClasseFilha2() { Console.WriteLine("Construtor da Classe Filha 2."); } public override void Imprimir() { base.Imprimir(); Console.WriteLine("Eu sou a Classe Filha 2."); } } using System; public class Program { public static void Imprimir(ClassePai classePai) { classePai.Imprimir(); } public static void Main() { Console.WriteLine("ClasseFilha 1"); ClasseFilha1 classeFilha1 = new ClasseFilha1(); Imprimir(classeFilha1);

32

Console.WriteLine(""); Console.WriteLine("ClasseFilha 2"); ClasseFilha2 classeFilha2 = new ClasseFilha2(); Imprimir(classeFilha2); Console.ReadKey(); } }

Listagem 3: Implementao do Polimorfismo.

O exemplo da Listagem 3 representado graficamente fica assim:


ClassePai
Class

Methods ClassePai Imprimir

ClasseFilha1
Class ClassePai

ClasseFilha2
Class ClassePai

Methods ClasseFilha1 Imprimir

Methods ClasseFilha2 Imprimir

Na Listagem 3, temos a classe base ClassePai, e as classes derivadas (filhas) ClasseFilha1 e ClasseFilha2. Observe que ambas as classes derivadas reimplementaram o mtodo Imprimir, ou seja, o mtodo Imprimir ter comportamento diferente conforme a classe instanciada (ClasseFilha e/ou ClasseFilha2). Para permitirmos que as classes filhas possam alterar o comportamento do mtodo Imprimir da ClassePai utilizamos o modificador virtual em sua assinatura na classe ClassePai. At aqui nenhuma novidade, pois na Listagem 2 conseguimos reimplementar o mtodo Imprimir sem usar o conceito de polimorfismo. Para sobrepormos um mtodo usando o conceito de polimorfismo, na assinatura do mtodo da classe derivada deve-se usar o modificador override como na Listagem 3. A grande novidade est do mtodo esttico Imprimir da classe principal Program. Ele recebe como parmetro a um objeto da ClassePai, mas em sua chamada dentro do mtodo Main passado um das classes filhas (ClasseFilha e ClasseFilha2). E no momento de execuo do cdigo, o run-time se encarrega de selecionar o mtodo Imprimir conforme a classe filha do parmetro. Utilize o Visual Studio em modo Debug e veja na prtica o que acontece com o mtodo Imprimir. Nada impede de utilizamos diretamente o mtodo Imprimir das classes filhas sem passar pela classe base.

Converso entre as classes


Agora que j vimos como funcionam os mtodos polimrficos, vamos ver algumas regras relativas a converso de dados de classes base para classes filhas e como esta implementao leva ao conceito de polimorfismo. 33

Quando construmos uma instncia de uma classe especializada (ex. ClasseFilha1) podemos atribuir esta instncia a uma objeto o tipo da classe base (ClassePai). Isto porque a classe especializada (ClasseFilha1) suporta todas as caractersticas da classe base, e portanto pode ser armazenada em um objeto deste tipo, conforme o exemplo a seguir.
ClassePai classePai = new ClassePai(); ClasseFilha1 classeFilha1 = new ClasseFilha1(); classePai = classeFilha1;

Classes Abstratas
Pode acontecer que ao escrever um mtodo para uma classe base no saibamos como ele ser implementado. Neste caso, a implementao ser feita pela classe que herdar o mtodo (a classe filha). Pode acontecer tambm que um determinado mtodo ser sobreposto com certeza na classe filha, ento, no h a necessidade de sua implementao na classe base. Nestes casos definimos apenas a assinatura do mtodo e a definio fica por conta da classe que ir herdar a classe base. Estas classes so chamadas classes abstratas, e o mtodo no implementado chamado de mtodo abstrato. As classes abstratas no podem ser instanciadas atravs da palavra chave new, considerada uma classe genrica. Contm mtodos abstratos que devem ser implementados nas classes que derivam dela, e ainda pode conter mtodos virtuais e no-abstratos (implementados). Um mtodo abstrato no apresenta implementao na classe base. O exemplo a seguir implementa uma classe abstrata com membros abstratos e no-abstratos.
Using System; public abstract class Pessoa { public abstract string Nome { get; set; } public abstract int Id { get; } public abstract void Cadastrar(); public virtual void Viajar() { /* Ao */ } }

O exemplo a seguir deriva a classe abstrata Pessoa do exemplo anterior, implementando os membros abstratos.
using System; public class Diretor : Pessoa { public override string Nome { get { /* Implementao get */ } set { /* Implementao set */ } } public override int Id

34

get { /* Implementao get */ } } public override void Cadastrar() { /* Aes */ }

O que pode se perceber que a construo de classes abstratas deve ser muito bem planejada durante o projeto do sistema.

Interfaces
Uma interface parecida com uma classe abstrata, a diferena que uma classe abstrata pode possuir mtodos que no estejam implementados e pode possuir mtodos que estejam implementados. Uma interface possui somente mtodos que no esto implementados e que devem ser implementados pela classe que usar a interface. Como o C# no suporta herana mltipla as interfaces permitem que uma classe estenda mltiplas interfaces contornando o problema. Uma interface no C# no pode conter atributos, somente pode ter mtodos, propriedades e eventos. Todos os membros de uma interface so pblicos e no podem usar um modificador de acesso. A classe que implementa a interface deve possuir a definio de todos mtodos existentes na interface. Esta definio deve possuir o mesmo nome e a mesma assinatura, retorno e parmetros, do mtodo na interface. O nome da classe e o nome da interface so separados por dois pontos(:). Os exemplos utilizados na sesso sobre classes abstratas foram adaptados para interface. O exemplo a seguir implementa a interface IPessoa.
using System; public interface IPessoa { int Id { get; } string Nome { get; set; } void Cadastrar(); }

O exemplo a seguir implementa o uso da interface IPessoa.


public class Pessoa : IPessoa { private int _id; public int Id { get { return _id; } } private string _nome; public string Nome { get { return _nome; } set { _nome = value; } }

35

public void Cadastrar() { /* Implementao */ }

Os exemplos anteriores representados graficamente ficam assim:


IPessoa IPessoa
Interface

Pessoa
Class

Properties
Id Nome

Fields _id _nome Properties Id Nome Methods Cadastrar

Methods
Cadastrar

O I no incio do nome da Interface uma conveno e uma boa prtica.

36