Vous êtes sur la page 1sur 47

Os alunos do Curso de Engenharia da Computao da Universidade Estadual do Maranho

UEMA Perodo 2012.2, na matria Paradigmas da Programao, misistrada pelo professor


Digenes Aquino foram incentivados a criar uma apostila referente Linguagem de
programao escolhida para ser estudada por eles. No nosso caso, a linguagem escolhida
foi C#. Esperamos que voc tire suas dvidas e se empolgue com essa linguagem que
tambm nos empolgou. :D

Obrigado.

O que a linguagem

Tipos de dados

Vetores

Input/Output

Comentrios e sua importncia

Condicionais, Operadores Lgicos, Matemticos e Ternrio.

Laos de Repetio.

Funes

Parmetros

Ponteiros

Recursividade

Using e Namespace

Converso de Dados

Programao orientada a objeto

Operador New

Modificadores de acesso C#.

Tratamento de Erros

Framework.Net
C# (L-se C Sharp) uma linguagem de programao multi-paradigma, assim como C++ e
Object Pascal. Uma linguagem multi-paradigma pode ser puramente procedural,
puramente orientada a objetos ou pode conter elementos de ambos paradigmas, como
nessa linguagem.

O nome C Sharp foi inspirado em notao musical, onde um sustenido indica que a nota
escrita deve ser feita um semitom mais agudo. Este semelhante ao nome da lngua de
C++, onde "++" indica que a varivel deve ser incrementado por 1.

Na notao de cifras, C# significa a nota D Sustenido.

Devido a limitaes tcnicas do display (fontes padro, navegadores, etc) e o fato de que o
smbolo sustenido (U+266F SMBOLO MUSICAL (HTML: &9839;)) no est presente no
teclado padro, o sinal de nmero (U+0023 # JOGO DA VELHA (HTML: #)) foi escolhido para
representar o smbolo do sustenido no nome escrito da linguagem de programao [8] Esta
conveno refletida no ECMA-334 C # Language Specification [6] no entanto, quando ele
.. prtica para faz-lo (por exemplo, na publicidade ou na caixa de arte [9]), a Microsoft
usa o smbolo musical pretendido.

Essa linguagem foi desenvolvida pela Microsoft no mbito da sua iniciativa .NET e
posteriormente aprovada como padro pela Ecma (ECMA-334) e ISO (ISO/IEC 23270:2006).
C# uma das linguagens de programao projetadas para a Common Language
Infrastructure (CLI).

CLI uma especificao aberta desenvolvido pela Microsoft e padronizada pela ISO e ECMA
que descreve o cdigo executvel e ambiente de execuo runtime que formam o ncleo
da Microsoft .NET Framework e implementaes Mono e Portable .NET, que so se cdigo
livre e aberto. A especificao define um ambiente que permite que vrias linguagens de
alto nvel possam ser usadas em diferentes plataformas de computador sem ser reescrito
para arquiteturas especficas.

Desde 2002, C# vem melhorando ao decorrer do tempo, hoje essa linguagem j est na sua
verso 5.0 e a Microsoft no v ainda razo para descontinu-la.

Os principios de design de padronizao da ECMA para C# foram:

A linguagem C# destinada a ser uma linguagem simples, moderna, de uso geral e


com programao orientada a objetos.
A linguagem e suas implementaes, devem fornecer suporte para os princpios de
engenharia de software, tais como verificao de tipo forte, verificao de limites
de matriz, deteco de tentativas de utilizao de variveis no inicializadas, e
coleta de lixo automtica. Software de robustez, durabilidade e produtividade do
programador so importantes.
A linguagem deve ser utilizada no desenvolvimento de componentes de software
adequados para a implantao em ambientes distribudos.
Portabilidade do cdigo fonte muito importante, assim como a portabilidade do
programador, especialmente para os programadores j familiarizados com C e C +
+.
Apoio internacionalizao muito importante.
C# pretende ser adequada para a criao de aplicativos para ambos os sistemas:
hospedados e incorporados, que vo desde o muito grande, que usa sistemas
operacionais sofisticados, at os muito pequenos com funes dedicadas.
Embora as aplicaes C# pretendem ser econmicas em relao aos requisitos de
energia, memria e processamento, a lngua no tem a inteno de competir
diretamente no desempenho e tamanho, com C ou linguagem de montagem.

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#, qualquer varivel tem de fazer parte
de uma classe;
Fortemente tipada: isso ajudar a evitar erros por manipulao imprpria de tipos
e atribuies incorretas;
Gera cdigo gerenciado: assim como o ambiente .NET gerenciado, assim tambm
o C#;
Tudo um objeto: System.Object a classe base de todo o sistema de tipos de C#;
Controle de verses: cada assembly 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).

C# pode ser usada para todos os tipos de aplicaes que vo desde jogos de computador,
servios pblicos, sistemas operacionais e compiladores. H tambm aplicativos baseados
na web que rodam na plataforma asp.net.
Em C#, assim como em e Java, os principais tipos de dados so: inteiro, real, caractere,
logico e string (Um vetor de caracteres). Esses tipos de dados naturais da linguagem, so
utilizados quando se quer armazenar um valor qualquer. A linguagem C# (diferentemente
do ANSI C), aceita a declarao de varveis em qualquer parte do cdigo.

Para se declarar uma varivel, basta que declaremos o tipo dela e o nome que deve
comear com uma letra ou com um _, o nome da varivel somente pode conter letras,
nmeros ou _.

Exemplo:

int inteiro; string nome;

float real; bool logico;

char caractere;

H ainda outros tipos de dados, como podemos ver na seguinte tabela:

Referencia: site da Microsoft studio (http://msdn.microsoft.com/pt-br/library/ms228360(v=vs.80).aspx).


Vetores podem ser divididos nas quatro seguintes categorias.

Vetor de uma dimenso


Vetor de multi-dimenso (Matriz)
Vetor irregular
Vetor mixto

Em C#, o ndice comea em zero. Isso significa que o primeiro item de um vetor
comea na posio 0. A posio do ltimo item em um vetor ter um total de nmero
de itens - 1. Ento, se um vetor tem 10 itens, o 10 item est na 9 Posio.

Em C#, vetores podem ser declarados em tamanho fixo ou dinmico.

Um vetor de comprimento fixo pode armazenar um nmero predeterminado de itens.

Um vetor dinmico no tem um tamanho predefinido. O tamanho de um vetor


dinmico aumenta medida que voc adiciona novos itens ao vetor. Voc pode
declarar um vetor de comprimento fixo ou dinmico. Voc pode mesmo mudar um
dinmico para um esttico depois que ele definido.

Vamos dar uma olhada em simples declaraes de vetores em C#. O seguinte trecho
de cdigo define um simples vetor dinmico de tipos inteiros que no tem um
tamanho fixo.

int[] intArray;

Como voc pode ver a partir do trecho de cdigo acima, a declarao de um vetor
comea com um tipo de vetor seguido de um colchete ([]) eo nome do vetor.

O seguinte trecho de cdigo declara um vetor que pode armazenar 5 itens somente a
partir de ndice de 0 a 4.

int[] intArray;
intArray = new int[5];

O seguinte trecho de cdigo declara um vetor que pode armazenar 100 itens a partir
de ndice de 0 a 99.

int[] intArray;
intArray = new int[100];
No trecho de cdigo anterior, vimos como definir um vetor simples do tipo inteiro. Da
mesma forma, podemos definir vetores de qualquer tipo, tais como double, char e
string.

Em C#, vetores so objetos. Isso significa que declarar um vetor no cria um vetor.
Depois de declarar um vetor, voc precisa instanciar um vetor usando o operador
"new".

O seguinte trecho de cdigo define vetores de tipos de dados double, char, bool e
string.

double[] doubleArray = new double[5];


char[] charArray = new char[5];
bool[] boolArray = new bool[2];
string[] stringArray = new string[10];

Uma vez que o vetor declarado, o prximo passo inicializar um vetor. O processo
de inicializao de um vetor inclui a adio de dados reais para o mesmo.

O seguinte trecho de cdigo cria um vetor de 3 itens e os valores desses itens so


adicionados quando o vetor inicializado.

// Inicializando um vetor esttico


int[] staticIntArray = new int[3] {1, 3, 5};

Como alternativa, tambm possvel adicionar itens do vetor um de cada vez,


conforme listado na seguinte trecho de cdigo.

// Inicializando um vetor esttico um item por vez


int[] staticIntArray = new int[3];
staticIntArray[0] = 1;
staticIntArray[1] = 3;
staticIntArray[2] = 5;

O seguinte trecho de cdigo declara um vetor dinmico com valores de string.

// Inicializando um vetor dinmico com items durante a declarao


string[] strArray = new string[] { "Mahesh Chand", "Mike Gold", "Raj
Beniwal", "Praveen Kumar", "Dinesh Beniwal" };
Podemos acessar um item do vetor, passando o ndice do item pelo vetor. O seguinte
trecho de cdigo cria um vetor de trs itens e exibe os itens no console.

// Inicializando um vetor esttico um item por vez


int[] staticIntArray = new int[3];
staticIntArray[0] = 1;
staticIntArray[1] = 3;
staticIntArray[2] = 5;

// Lendo itens do vetor um item por vez


Console.WriteLine(staticIntArray[0]);
Console.WriteLine(staticIntArray[1]);
Console.WriteLine(staticIntArray[2]);

Este mtodo til quando voc sabe o item que voc deseja acessar a partir de um
vetor. Se voc tentar passar um item de ndice maior do que os itens de srie, voc
receber um alerta de erro.

A declarao de controle foreach (lao) usado para percorrer os itens de um vetor.


Por exemplo, o cdigo a seguir usa o lao foreach para ler todos os itens de um vetor
de strings.

// Initialize a dynamic array items during declaration


string[] strArray = new string[] { "Mahesh Chand", "Mike Gold", "Raj
Beniwal", "Praveen Kumar", "Dinesh Beniwal" };

// Read array items using foreach loop


foreach (string str in strArray)
{
Console.WriteLine(str);
}

Esta abordagem usada quando voc no sabe o ndice exato de um item em um


vetor e precisa percorrer todos os itens.
Um vetor de multi-dimenso declarado da seguinte forma:

string[,] mutliDimStringArray;

Um vetor multi-dimensional pode ser de tamanho fixo ou dinmico.

O seguinte trecho de cdigo um exemplo de matrizes de tamanho fixo que definem 2


matrizes de 3x2 e 2x2. A primeira matriz pode armazenar seis itens e segunda pode
armazenar quatro. Ambas as matrizes so inicializadas durante a declarao.

int[,] numbers = new int[3, 2] { { 1, 2 }, { 3, 4 }, { 5, 6 } };


string[,] names = new string[2, 2] { { "Rosy", "Amy" },
{ "Peter", "Albert" } };

Agora vamos ver exemplos de matrizes dinmicas, onde voc no tem certeza do
nmero de itens da matriz. O seguinte trecho de cdigo cria duas matrizes sem limite.

int[,] numbers = new int[,] { { 1, 2 }, { 3, 4 }, { 5, 6 } };


string[,] names = new string[,] { { "Rosy", "Amy" },
{ "Peter", "Albert" } };

Voc tambm pode omitir o operador new como fizemos em vetores unidimensionais.
Voc pode atribuir esses valores diretamente sem usar o novo operador. Por exemplo:

int[,] numbers = { { 1, 2 }, { 3, 4 }, { 5, 6 } };
string[,] names = { { "Rosy", "Amy" }, { "Peter", "Albert" } };

Tambm possvel inicializar os itens da matriz um item de cada vez. O seguinte


trecho de cdigo um exemplo de inicializar os itens do array um de cada vez.

int[,] numbers = new int[3, 2];


numbers[0, 0] = 1;
numbers[1, 0] = 2;
numbers[2, 0] = 3;
numbers[0, 1] = 4;
numbers[1, 1] = 5;
numbers[2, 1] = 6;
Os itens da matriz so representados em um formato de matriz e para acess-los,
preciso especificar a dimenso da matriz. Por exemplo, o item (1,2) representa um
item vetor na matriz, na segunda linha e terceira coluna.

O seguinte trecho de cdigo mostra como acessar varios nmeros definidos no cdigo
acima.

Console.WriteLine(numbers[0,0]);
Console.WriteLine(numbers[0, 1]);
Console.WriteLine(numbers[1, 0]);
Console.WriteLine(numbers[1, 1]);
Console.WriteLine(numbers[2, 0]);
Console.WriteLine(numbers[2, 2]);

Para se entrar com um dado, necessrio que se crie uma varivel, onde o
dado ser armazenado, e se use das funes Read() ou ReadKey ou ReadLine(). Cada
uma tem uma utilizao distinta e esto no namespace System.IO (ser explicado mais
sobre classes no decorrer da apostila).

Essa funo serve para ler o prximo caractere de fluxo de entrada padro. Sua
sintaxe :

public override int Read()

Seus valores de retorno so do tipo System.Int32 (um inteiro).

O prximo caractere de fluxo de entrada representado como um objeto de


Int32 -1, ou se nenhum caractere mais est disponvel.

Essa funo aguarda at que o usurio pressione uma tecla. Esta funo
muito utilizada quando utilizamos aplicaes console queremos fazer com que o
programa pare em um determinado ponto para que possamos analisar os dados que
esto sendo impressos. Sua sintaxe :
public static ConsoleKeyInfo ReadKey(bool intercept)

O parmetro intercept, utilizado para dizer se ou no para ser impresso na


tela a tecla pressionado, basta colocar true para imprimir e false para no imprimir.
O valor de retorno dessa funo um System.ConsoleKeyInfo que uma
serie de definies de constantes que permitem o programador identificar qual tecla
foi pressionada. Para ler a lista, basta acessar:
http://msdn.microsoft.com/pt-br/library/system.consolekey(v=vs.80).aspx

A funo ler uma linha que o usurio digitar (uma sequencia de caracteres) e
retorna para uma varivel que esteja sendo igualada a ela. Por exemplo:

string nome = ReadLine();

Sua sintaxe :

public override string ReadLine ();

Seu retorno uma string com todos os caracteres digitados pelo usurio
antes de pressionar ENTER.

Pode ter surgido agora a duvida: Como que eu leio um inteiro? ou at


mesmo, Como que eu leio um caractere?. Muito simples, utilizamos converso de
tipos.
>>Para se ler um inteiro, se utilizaria o seguinte formato:
/* Lendo um numero inteiro*/
int number;
number = Convert.ToInt32(Console.ReadLine());

>>Para se ler um real, se utilizaria o seguinte formato:


/* Lendo um numero real*/
double number;
number = Convert.ToDouble(Console.ReadLine());

E assim para todos os outros tipos de dados.

A sada padro do C# o monitor do computador. As funes utilizadas com


tal finalidade (em projetos Console), so: System.Console.Write() e
System.Console.Writeline().
A diferena entre as funes a quebra de linha, que ocorre na segunda e na
primeira no ocorre. Vejamos o exemplo abaixo:
Usando em ambos: System.Console.Write()

Usando no Ol Mundo!: System.Console.WriteLine()

Ambos os mtodos so mtodos sobrecarregados (caracterstica da


orientao a objeto). Metodos sobrecarregados, so aqueles que possuem mais de
uma sintaxe padro e o compilador interpreta qual a melhor opo que se encaixa com
determinada utilizao. Perceba que pode-se declarar duas variveis de tipos distintos
e passa-las como parmetro para qualquer uma dessas funes.

public static void WriteLine();


public static void Write();

Para analisar todas as sobrecargas do mtodo WriteLine acesse:


http://msdn.microsoft.com/pt-br/library/system.console.writeline(v=VS.80).aspx

Para imprimir um numero ou uma varivel, basta fazer uma das sintaxes
abaixo:
//Declarando variveis.
string nome = "Usuario";
int idade = 10;
/*
Imprimindo variveis e testando sobrecarga do mtodo
Console.Write();
*/
Console.WriteLine(nome);
Console.WriteLine(idade);
Console.WriteLine("Meu nome : {0}",nome);
Console.WriteLine("Meu nome : "+nome);
Comentrios tem a funo de deixar seu cdigo mais legvel. Quando se escreve
um algoritmo hoje, a probabilidade de voc no se lembrar, daqui h um ms, o que
um trecho do seu cdigo faz muito grande. H tambm o fato de tornar seu cdigo
mais legvel para as pessoas que iram l-lo, seu chefe ou mesmo um outro
programador que esteja trabalhando na mesma equipe que voc. Sem comentrios,
poderia ser necessrio ler todo o cdigo para que se entenda somente uma linha e
mesmo assim, pode ser que o prprio desenvolvedor no entenda-a. Para prevenir
tais incmodos, utiliza-se comentrios.

Existem 2 mtodos para se comentar algo:

//Utilizado para se fazer comentrios de somente uma linha


ou
/*
Utilizado para comentrios de mais de uma linha
*/
ou
/**
Utilizado para comentrios no .NET
*/

Os condicionais em C# so utilizados para delimitar uma certa condio para


que se execute um trecho de cdigo ou no. Os condicionais em C#, so os mesmos do
C++ e do Java.

Estruturalmente, se tem:

if (condicao)
{
/*
trecho de codigo
*/
}
Podem ser comparaes ou ate mesmo variveis do tipo bool (varivel logica).
Veja os exemplos:
bool condicao = true;
int numero = 10;

if (condicao)
{
Console.WriteLine("Primeira Condicao");
if (numero == 2)
Console.Write("Segunda Condicao");
}
Os operadores lgicos do C# so: == (igual), != (diference), >(maior que), <
(menor que), >= (maior ou igual que) e <=(menor ou igual que).
Pode-se ainda conjugar duas condies. Fica assim:

bool condicao = true;


int numero = 10;

if (condio && numero == 10)


Console.WriteLine("Primeira Condicao");

Perceba que para condicionais que s utilizam-se de uma linha de comando,


no necessrio o uso das chaves {}.

Os principais operadores que permitem unir duas conjunes so o &&


(Conjuno), o || (Disjuno) e o ! (Negao).

A conjuno serve como o E na lngua portuguesa, ele serve para unir duas
conjunes e somente torna toda a expresso verdadeira se ambos os termos da
expresso forem verdadeiros.

A disjuno se assemelha ao OU da lngua portuguesa. Serve para unir duas


conjunes e torna-a verdadeira se qualquer um dos dois forem verdadeiros.

A negao, como o prprio nome sugere, serve para negar uma conjuno. Se
ele era falsa, se torna verdadeira e se verdadeira se torna falsa.
Os operadores matemticos, so + (soma), - (subtracao), / (diviso), * (multiplicao) e
% (resto) e Podem ser utilizados em qualquer situao.

O operador resto, retorna o resto da diviso de um numero por outro. 5 % 3 = 2.

H ainda os operadores do tipo ++, --, += e -=. Estes operadores funcionam da seguinte
forma:

a++; a mesma coisa de a = a + 1;

a += b; a mesma coisa de a = a + b;
O operador ternrio serve para realizar uma comparao e uma atribuio,
dependendo do resultado da comparao. Sua estrutura a seguinte:

a = (condicao) ? retornoVerdadeiro : retornoFalso;

Exemplo:

//declarao de variveis
int maioridade = 0;
int idade1 = 20;
int idade2 = 30;
//operador ternario para atribuio
maiorIdade = (idade1 > idade2) ? idade1 : idade2;

Laos de repetio servem para realizar um mesmo trecho de cdigo enquanto uma
condio for valida.

Este lao, realiza uma repetio num bloco de comandos (um trecho de cdigo, entre
chaves) enquanto uma condio for verdadeira. Sua sintaxe a seguinte:

while(condio){}

Veja o exemplo:

/*
*
* Este algoritmo vai imprimir todos os
* valores pares entre 0 e 10
*
*/
//declarao de variveis
int i = 0;

//lao de repetio
while (i <= 10)
{
if (i % 2 == 0)
{/*
* se o resto da diviso por 2 for igual a 0, ou seja, se o
* numero for par, ento imprima o nmero.
*/
Console.WriteLine(i);
}
i++;
}
O do-while funciona semelhantemente ao while. A nica diferena que no while a
comparao feita logo no incio e no do-while a comparao feita somente no final. O que
isso significa? Simplesmente significa que no while no feito nenhum lao caso a condio
no seja satisfeita e j no do-while feito no mnimo um lao antes que a condio seja
satisfeita. Faa dois programas com condies falsa, um com while e um com do-while e
verifique os resultados.

Sintaxe:

do{}while(condicao);

Este lao mais utilizado quando se sabe o numero de interaes que se pretende
fazer. Por exemplo para contar de 0 at 10, mais aconselhvel usar este lao do que o while
ou o do-while.

Sintaxe:

for (inicializao; condio; incremento)

Exemplo:

int i;

for (i = 0; i < 10; i++)


{
Console.WriteLine(i);
}
Lao derivado do for, que serve para percorrer todos os elementos de uma matriz ou
coleo de objetos. Utiliza-se da seguinte forma:

int[,] matriz = new int[3, 2] { { 1, 2 }, { 3, 4 }, { 5, 6 } };


int elemento;

foreach (int element in matriz)


{
Console.WriteLine(element);
}

Saida no console:

Funes so blocos de cdigos que servem para fazer uma coisa especfica. Por
exemplo, a funo System.Console.Write() serve para escrever algo na tela.

Funes tem duas utilidades:

1- Facilitar a leitura do cdigo.


2- Facilitar a escrita do cdigo.

Uma Funo pode receber como parmetros dados de outra funo ou at


mesmo de outros programas, dependendo do caso. Um mtodo (sinnimo) s bem
implementado se for chamado no mnimo 3 vezes, caso contrrio, certamente o
programador s deu mais trabalho para si mesmo.

Implementar uma funo significa fazer um trecho de cdigo que faa uma
determinada ao.

Segue abaixo o modelo de funo


modificador tipo_retorno nome (parmetros)
{

//cdigo

return retorno;

Vejamos a implementao de uma funo soma:

public int soma (int numero1, int numero2)


{
//declarao de vriaveis
int resultado;
//somando os dois numeros passados por parmetro
resultado = numero1 + numero2;

//retorno da funo
return resultado;
}

Serve para dizer quais classes podem acessar ou no a funo. Isso ser
explanado com mais detalhes mais h frente. O importante agora saber que esse
modificador d ou no visibilidade dentro de um objeto ou uma classe sobre a funo.

o tipo da varivel que a funo ir retornar para quem a chamou. No caso


anterior o tipo da funo era inteiro por que o retorno foi a varivel resultado que
tambm um inteiro.

Os tipos de retorno podem ser qualquer tipo de varivel, nativa ou no da


linguagem. Um tipo de retorno que merece destaque aqui, o void. Este tipo de
retorno o que declara que a funo no retorna nenhuma varivel, funes com esse
tipo de retorno so chamadas procedimentos. Geralmente a impresso dos dados
feita na prpria funo.
o nome pelo qual a funo ir ser chamada, dentro dos outros mtodos
(outro nome para funo).

o algoritmo que ser executado toda vez que a funo for chamada.

So valores que so passados para a funo que chamada. So as variveis


que ficam dentro do parnteses. Existem dois tipos de parmetros (por valor e por
referncia). Passar um valor por valor significa passar o seu valor e passar um
parmetro por referncia significa passar o endereo de memoria da varivel.

Isso implica que passando um parmetro por valor, ele quando alterado
alterado somente dentro da funo que o utiliza. J na passagem por referncia ele
altera os valores dentro da funo e em todo o programa.

Quando passados por valor, as variveis da funo recebem uma cpia idntica
do parmetro. Caso passado um vetor, o vetor copiado exatamente do mesmo jeito,
todos os valores do vetor que esto na funo chamadora sero os mesmos que
estavam na chamada. A grande diferena que mesmo que a funo chamada
modifique o valor de uma varivel, o no ser modificado na funo chamadora.

Vejamos o exemplo:

class ParametroValor
{
/**
* Definio: Funo soma que retorna o resultado da soma de dois
* nmeros inteiros.
*
* @parmetros: dois nmeros que sero somados.
* @retorno: a soma dos dois nmeros passados por parmetro.
*
*/
public static int soma(int numero1, int numero2)
{
//varivel que armazenar o resultado
int resultado = 0;
//operando a soma dos dois nmeros inteiros
resultado = numero1 + numero2;
//retorno da funo (varivel local)
return resultado;
}

//funo principal que ser a chamadora da funo int soma(int


int);
static void Main(string[] args)
{

//Declarao das variveis


int numero1;
int numero2;
int resultado;

//Entrada de dados
Console.WriteLine("Entre com o primeiro numero: ");
numero1 = Convert.ToInt32(Console.ReadLine());
Console.WriteLine("Entre com o segundo numero: ");
numero2 = Convert.ToInt32(Console.ReadLine());

//Processamento
resultado = soma(numero1, numero2);

//Sada
Console.WriteLine("{0} + {1} = {2}.", numero1, numero2,
resultado);
Console.ReadKey();

}
}

Quando passados por referncia, as variveis da funo recebem o endereo de


memria que a varivel na funo chamadora tem. Quando modificado o valor de uma
varivel na funo chamada ele tambm modificado na funo chamadora. Para passar um
parmetro como referncia, necessrio que se adicione somente o ref na frente do parmetro.
Veja:
class Programa
{
/**
* Definio: Funo soma que por referencia armazena o resultado de
* soma.
*
* @parmetros: dois nmeros que sero somados passados por valor e
* parmetro pro referencia que um inteiro que armazena
* o resultado.
* @retorno: a soma dos dois nmeros passados por parmetro.
*
*/

public static void soma(int numero1, int numero2,ref int resultado)


{
//operando a soma dos dois nmeros inteiros
resultado = numero1 + numero2;
}

/*
* funo principal que ser a chamadora
* da funo void soma(int int, ref int);
*/
static void Main(string[] args)
{
//Declarao das variveis
int numero1;
int numero2;
int resultado = 0;

//Entrada de dados
Console.WriteLine("Entre com o primeiro numero: ");
numero1 = Convert.ToInt32(Console.ReadLine());
Console.WriteLine("Entre com o segundo numero: ");
numero2 = Convert.ToInt32(Console.ReadLine());

//Processamento
soma(numero1, numero2,ref resultado);

//Sada
Console.WriteLine("{0} + {1} = {2}.", numero1, numero2,
resultado);
Console.ReadKey();
}
}
Rode os dois programas e perceba a diferena.

Nos dias em C que era a principal linguagem de programao, os ponteiros


significavam programao e vice-versa. Agora, em linguagens mais sofisticadas como
C#, os ponteiros so apenas um recurso fornecido, mas no realmente incentivado.

Em uma linguagem moderna, o argumento que voc nunca precisar descer ao nvel
de ponteiros, porque isto simplesmente mostra que voc est pensando em um nvel
muito primitivo e pode por em perigo a unio com o hardware. Embora isto seja
verdade, ainda h momentos quando em que voc tem que interagir com o hardware
de uma forma que s pode ser alcanada usando ponteiros. Alm disso, h todos
aqueles programas em C/C++ que usam ponteiros e precisam ser convertido para algo
mais polido e seguro. Em resumo, voc certamente deve saber sobre ponteiros mesmo
esperando que voc nunca ir realmente usa-los em um programa real. Se voc acha
que os ponteiros so essenciais para algo de baixo nvel que voc est tentando
implementar, em seguida, tambm importante que voc saiba como implement-los
em um possvel mtodo seguro.

Primeiro precisamos esclarecer algumas confuses que existe entre os trs termos
Referncia, ponteiro e endereo. Comeando como o mais bsico endereo: o
nmero do endereo de algo que est armazenado. A maioria dos hardwares do
computador atribui endereos usando um esquema simples de incremento a partir de
algum valor e continuam at outro valor, por exemplo, 0-1000, e cada endereo
correspondem a uma posio de memria capaz de armazenar alguns dados com um
determinado nmero de bits. Esta ideia simples tornou-se cada vez mais complicada
com a evoluo do hardware e a introduo do mapeamento de memria de
hardware. Agora o endereo que os dados so armazenados mudado sem que eles
sejam movidos, devido utilizao de hardware de converso de endereos. Mesmo
que o hardware no possa mudar o endereo, ele pode ser mudado quando o
aplicativo for executado, pelo sistema operacional ou o sistema de coleta de lixo, que
normalmente efetua algumas mudanas para o sistema ficar mais eficiente. O ponto
que embora uma vez que o endereo de memria era uma forma fixa e confivel de
acesso, hoje cercado por uma serie de problemas.

O ponteiro a abstrao de um endereo. Na sua forma mais bsica, um ponteiro


simplesmente uma varivel que pode ser usada para armazenar o endereo de alguma
coisa. Voc pode usar um ponteiro para acessar o ndice do dado que ele est
apontando um processo chamado desreferenciamento. Voc tambm pode utilizar o
ponteiro para fazer operaes aritmticas, que podem mudar sua localizao no
armazenamento ou memria. Ou seja, se na memria os objetos so armazenados um
aps o outro, voc pode executar a aritmtica de ponteiro para alterar o objeto que
est sendo apontado. Aritmticas de ponteiro a razo pela qual, muitos
programadores gostam de ponteiros, mas tambm a razo pela qual os ponteiros so
perigosos. Um erro no clculo pode resultar em que o ponteiro aponte para um lugar
onde ele no deve estar apontando e todo o sistema pode falhar com o resultado. No
h realmente nenhuma razo para que um ponteiro no deva ser basicamente a
abstrao de um endereo, mas na maioria dos casos, os ponteiros so apenas
invlucros para endereos da mquina e isto tambm levanta a questo sobre o que
acontece se o sistema fizer algo que mude o endereo de um objeto. Veremos mais
sobre isso posteriormente.
Finalmente chegamos ao ponto mais alto da abstrao de endereo na forma de uma
referncia: uma referncia apenas isso uma referncia a um item de dados ou um
objeto. Se isso soa como um ponteiro, h um sentindo, j que isto verdade, mas a
ideia fundamental que voc no pode manipular uma referncia diretamente. Ou
seja, enquanto h certamente uma aritmtica de ponteiros, no pode haver uma
aritmtica de referncia. Tudo o que voc pode fazer com uma referncia pass-la
para outro usurio ou referenci-lo e acessar os dados que ele faz referncia. Como no
caso dos ponteiros, no h razo para que uma referncia, no deve ser uma
abstrao do endereo da mquina subjacente, mas na maioria dos casos, e em C#, em
particular, a referncia apenas um invlucro para um endereo. Em futuras
implementaes, contudo, uma referencia pode ser implementada como um
identificador para uma tabela, em outra tabela, a um ndice de recursos e assim por
diante, at que finalmente o hardware converta a referncia em um endereo de
objeto dados reais. O ponto que, enquanto sabemos que uma referncia, e para
que serve um ponteiro, em C#, eles so simplesmente um invlucro para um endereo
e este um detalhe de implementao, e no algo que voc deva se apegar.

Em C# podemos fazer uso de referncias o tempo todo, sob a forma de variveis que
so atribudas qualquer tipo de referncia. Por exemplo, se voc criar uma instncia de
uma classe, a varivel de instncia no um objeto, mas uma referncia a um objeto.
Isto :

MyClass MyObject = new MyClass();

Ento MyObject uma referncia a uma instncia de MyClass. Na prtica, contm o


endereo da ocorrncia, mas como j foi explicado, voc no deve contar com essa
forma de execuo. Este armazenamento de uma referencia no MyObjeto invs de um
valor mais evidente se voc criar uma outra varivel que referencia o mesmo objeto
de MyObject:

MyClass MyObject2 = MyObject;

Naturalmente, agora ns no temos outra cpia completa e independente do objeto


referenciado por MyObject, ao invs de referncia, temos a varivel na mesma
instncia. Se voc fizer uma alterao na instncia usando MyObject2, as mesmas
alteraes sero encontradas atravs de MyObject. A diferena entre uma referncia e
um valor, basicamente se resume a esta semntica, a referencia no cria uma copia
dos dados/objetos originais. Se isso acontecer, ento temos um valor semntico, se
no temos semntica de referncia.

Os ponteiros so uma generalizao de um modelo de referncia para incluir a


aritmtica de ponteiro. Ponteiros so to perigosos que devem ser colocados em
quarentena dentro do seu cdigo. Primeiro, o projeto tem que ser marcado como no
seguro (usafe) usando as propriedades do projeto para definir o Build como, Allow
Usafe Code. Ento, qualquer uso de ponteiros tem que ser includo no bloco usafe{}
para marca-lo ainda mais claramente. Ainda mais restritivo o fato de que voc no
pode usar a memria para fazer uso do ponteiro menos complicado. Essencialmente,
voc s pode criar um ponteiro para qualquer tipo de valor simples, por exemplo, int,
fload, char, enum, para outro ponteiro ou struct que no contenha outros tipos
gerenciados. Ento voc no pode ter um ponteiro para um objeto, ou um delegate ou
uma referncia. Isto bastante restritivo e basicamente, no permite que se criem
ponteiros para qualquer coisa criada no heap (pilha de memria) ou algum objeto que
usa uma gesto dinmica de memria. No entanto, voc pode ter um ponteiro para
uma struct que contm tipo de valores simples e voc pode criar ponteiros para arrays
de tipos de valores simples. Voc tambm pode ter um ponteiro do tipo void, ou seja,
um ponteiro para um tipo desconhecido, mas para ser de alguma utilidade, por
exemplo, para usar a aritmtica de ponteiros, voc precisa converter um ponteiro do
tipo void para um ponteiro de um determinado tipo.

Para declarar um ponteiro em C#, usa-se a mesma sintaxe do C++:

tipo * variavel;

O asterisco (*) o operador de referncia ou operador indireto, e geralmente usado


em conjunto com o endereo do operador e que como o prprio nome sugere, retorna
o endereo de uma varivel (sua referncia). Por exemplo:

unsafe

int* pMyInt;

int MyInt;

pMyInt = &MyInt;

O cdigo acima cria um ponteiro de inteiro, ou seja, pMyInt armazena no ponteiro o


endereo do inteiro MyInt. A primeira coisa importante, que um ponteiro no herda
de um objeto e assim no h mtodos associados a ele ou boxing e unboxing. Por
exemplo, voc no pode usar um mtodo toString() para mostrar o valor do
ponteiro.O que voc pode fazer, converter o ponteiro para um tipo simples e assim
usar os mtodos associados a este tipo, como no exemplo abaixo:

MessageBox.Show(((int)pMyInt).ToString());
Claro que isto pressupe que no int caber o ponteiro, ou seja, um endereo de
memria.

O operador de referencia, tambm retorna os valores armazenados no endereo que o


ponteiro est apontando. Por exemplo:

MessageBox.Show((*pMyInt).ToString());

O cdigo acima mostra o contedo de MyInt. Um ponteiro pode ser nulo e se neste caso for
aplicado o operador de referencia (*), gera uma exceo. Obviamente no faz sentido querer
exibir o contedo de um ponteiro nulo, mas voc sempre pode converter um ponteiro void e
ento evitar o engano. Em alguns casos, voc pode produzir um erro de converter
incorretamente um ponteiro. Por exemplo:

void* pMyData = &MyInt;

MessageBox.Show((*(double*)pMyData).ToString());

No cdigo acima definido um ponteiro nulo para apontar para um inteiro, ou seja,
um nmero inteiro de 32 bits, em seguida, ele convertido para um ponteiro de
double, ou seja, double *, e finalmente aplicado o operador de referncia para
retornar o valor apontado. Se voc tentar fazer isso, ver que ele funciona, mas gera
um resultado inesperado, porque o int original era de apenas 4 bytes de
armazenamento e do double de 8 bytes. De onde que ser adicionado os 4 bytes? A
resposta de um local de memria vizinho, um que voc no seria capaz de acessar s
apontando para o inteiro. Ler uma posio de memria que voc no conhecida at
pode ser seguro, mas quem sabe que efeitos isto pode trazer para o seu cdigo ou
sistema operacional. Por exemplo:

int MyInt2 = 0;

int MyInt=1234;

void* pMyData = &MyInt;

*(double*)pMyData = 123456.789;

MessageBox.Show(MyInt2.ToString());

Voc pode se surpreender ao descobrir que o valor de MyInt2 mudou e j no mais


zero, embora no seja atribudo um novo valor para ela dentro do programa. A
explicao simples, o armazenamento do MyInt2 alocado ao lado de MyInt e
quando vamos atribuir um valor de 8 bytes para MyInt os 4bytes extras substituem de
MyInt2. Isto claramente perigoso, inesperado e indesejado, geralmente por este tipo
de comportamento que o cdigo considerado inseguro.
Um uso muito comum de ponteiros para manipular a estrutura de um tipo de dado.
Por exemplo, suponha que voc deseje recuperar os quatro bytes que compem um
nmero inteiro de 32 bits:

int MyInt = 123456789;

Sempre podemos usar um ponteiro nulo para obter o endereo de qualquer varivel:

void* MyPointer;

MyPointer = &MyInt;

Ento podemos atribu-lo a qualquer ponteiro de qualquer um dos tipos padro e usar
aritmtica de ponteiro, como no exemplo abaixo, onde um byte, convertido para um
char:

byte* pMyByte = (byte*)MyPointer;

char MyChar = (char)*(pMyByte + 3);

MessageBox.Show(MyChar.ToString());

A razo porque no atribumos diretamente para um ponteiro de char que um char


tem dois bytes de tamanho e estamos convertendo um inteiro ASCII de 4 bytes para
caracteres Unicode.

Na maioria dos casos, so existem maneiras de ter acesso estrutura interna dos tipos
de dados comuns usando as classes Converter ou BitConvertor. No caso do
BitConvertor o mtodo GetBytes pode ser usado para converter o int para um array de
bytes e ento qualquer um dos bytes pode ser convertida para um caractere usando a
classe Convert:

Byte[] Bytes = BitConverter.GetBytes(MyInt);

MyChar = Convert.ToChar(Bytes[3]);

Se voc entender como funciona um ponteiro, vai entender como lidar com ponteiro
de ponteiro, e ponteiro de ponteiro de ponteiro, e assim por diante. Em teoria, isto
fcil, na prtica no to complicada como voc deve pensar. Por exemplo:

int** ppMyInt;

int* pMyInt;

int MyInt=1234;

pMyInt = &MyInt;
ppMyInt = &pMyInt;

MessageBox.Show((**ppMyInt).ToString());

No cdigo acima, declaramos um ponteiro de ponteiro, ou seja, ppMyInt e usamos ele


para apontar para pMyInt. Para exibir o valor apontado por pMyInt, ou seja, o valor de
MyInt, usamos dois nveis de referncia, **ppMyInt. Neste caso a referncia dupla
fcil de entender, mas em casos reais, ela pode se tornar difcil de trabalhar, quando
voc precisar de um ponteiro de ponteiro de ponteiro e assim por diante.

Bem como trabalhar com tipo de valor que voc pode criar seus prprios tipos de
dados primitivos usando a pilha. A declarao stackalloc tipo[n] aloca n bytes para o
tipo e retorna um ponteiro. Voc no precisa se preocupar com o armazenamento, a
pilha no modificada, ou a coleta de lixo, enquanto as variveis esto no escopo de
execuo. Voc tambm no precisa se lembrar de desalocar a memria, porque a
pilha automaticamente limpa quando as variveis saem do mbito da aplicao,
geralmente quando o mtodo que as declarou retorna.

Por exemplo:

int* pMyArray = stackalloc int[100];

pMyArray[10] = 34;

MessageBox.Show(pMyArray[10].ToString());

Aloca 100 nmeros inteiros, ou seja, 400 bytes, na pilha e usa o ponteiro para
armazenar 34 em 4 bytes comeando no byte 40 e exibe este valor.

Observe que usamos a indexao do array, para fazer a atribuio e para exibir o valor,
exatamente com em um array padro. No entanto, o bloco de memria apenas um
bloco de memria que voc pode fazer o que quiser com ele. Por exemplo:

public struct MyStructType

public int x;

public int y;

};
MyStructType* pMyDataBlock = stackalloc MyStructType[1];

pMyDataBlock->x = 34;

Aloca uma strutc na pilha, mas isso , aloca o tamanho do struct que possui dois
nmeros inteiros, ou seja, 8 bytes.

Podemos usar o ponteiro para a struct de forma habitual para definir e acessar um
campo. Ou seja, podemos usar o bloco como se fosse uma estrutura, mas se quisermos
podemos simplesmente trat-lo como um bloco de 8 bytes e utiliz-lo como outras
estruturas de dados. Por exemplo, se voc quiser tratar os dados como um array de
int, voc pode:

*((int*)pMyDataBlock) = 36;

Indo por partes:

int* pMyArray = (int*)pMyDataBlock;

pMyArray[0] = 36;

Cria um ponteiro para inteiro, e usa indexao de array para acessar o primeiro
elemento do array que o mesmo do campo x da estrutura.

Observe que essa forma depende de como a estrutura organizada em memria e


atualmente, o compilador do C# armazena os campos na ordem em que eles so
declarados. Uma serie de atributos podem ser usados para pedir ao compilador para
usar layouts especiais de memria especial para uma struct.

Recursividade a tcnica de programao na qual uma funo chama a si


mesmo at chegar em uma soluo trivial. Pode-se utilizar recursividade para resolver
problemas de labirinto, calcular a sequencia de Fibonacci, fatorial, dizer se uma palavra
um palndromo ou no. Muitos problemas quando resolvidos com recursividade
podem se resumir a 10 linhas e de outra forma, se tornaria um cdigo imenso.

class Recursividade
{
/**
* Definio: funo recursiva que determina
* se uma palavra um palndromo ou no
*
* @parmetros: uma string contendo a palavra, um
* ndice para o final da palavra e um
* ndice para o inicio da palavra.
* @sem retorno
*/
static void palindromo(string palavra, int fim, int indiceInicio)
{
//soluo trivial, se a palavra tem uma s letra.
if (fim == 1)
Console.Write("Palavra um palndromo");
/*
* Checando se o primeiro e ultimo termo da palavra so iguais.
* Se sim, chamar recursivamente a funo seno imprimir uma
* mensagem.
*/
else if (palavra[fim - 1] == palavra[indiceInicio])
palindroma(palavra, fim - 1, indiceInicio + 1);
else
Console.WriteLine("Palavra no um palndromo");
}
static void Main(string[] args)
{
//Var
string palavra;
//input
Console.WriteLine("Entre com uma palavra: ");
palavra = Console.ReadLine();
//processing
palindromo(palavra, palavra.Length,0);
Console.ReadKey();
}
}

Um namespace um organizador. O namespace mais utilizado at agora foi o


System, que referencia a classe Console (utilizada em quase todos os mtodos at
agora). Namespaces servem como referencia para um conjunto de classes, este
artifcio nos permite chamar uma classe ou um mtodo de uma classe que esteja
dentro de um namespace em qualquer parte do nosso programa.
O using serve para chamar esse namespace, de modo que no precisemos
referenciar toda vez que uma funo de um determinado namespace. Por exemplo:
Se no utilizssemos o using System;, teramos que escrever toda vez:

System.Console.WriteLine();
System.Console.Write();
System.Console.Read();
Existe na teoria de converso de dados dois tipos: a implcita e a explicita.

Assim como o nome j diz, a converso feita de forma implcita, sem que seja
percebido. Converter um dado implicitamente significa, por exemplo atribuir um int para um
float.

namespace ConversaoImplicita
{
class Program
{
static void Main(string[] args)
{
/*
* convertendo implicitamente os
* dados logo na declarao.
*
*/
sbyte sb = 10;
short b = sb;
int i = b;
long l = i;
float f = l;
double d = f;

Console.Write(f);
Console.Read();
}
}
}
}
Existe uma tabela de converso implcita disponibilizada pela Microsoft, que contm
todas as formas implcitas possveis. Vale ressaltar que esse tipo de converso deve ser feita de
forma cuidadosa, pois a tipos como Int que possuem menos pontos de preciso nos valores
armazenados, o que pode acarretar em arredondamentos de valores de forma errnea.
Observe a tabela de converso abaixo e anlise as opes possveis:
Essa a converso que na qual o programador necessita utilizar o cast explcito
para converter um dado em outro. Para realizar esse tipo de converso, basta declarar
frente da varivel da direita e entre parnteses o tipo de dado que deseja
(chamamos isso de cast). Veja o exemplo:

namespace CoversaoExplicita
{
class Program
{
static void Main(string[] args)
{

// Convertendo os dados explititamente


sbyte a = 10;
short b = (short) a;
int c = (int) b;
long d = (long) c;
float e = (long) d;
double f = (float) e;

//imprimindo o valor de f
Console.Write(f);
Console.Read();
}
}
}
Perceba que o valor da varivel f ainda um double. Para a converso
explicita tambm h uma tabela de equivalncia.
H ainda a converso com o auxlio de classes. A classe que daremos destaque
nessa apostila Convert que esta no namespace System. Esta uma classe que possui
mais de 300 mtodos prprios para converso de dados. Os tipos da dados base
suportados, so: Boolean, Char, Sbyte, Byyte, Int16, Int32, Int64, Single, Double,
Decimal, DataTime (este tipo de dados da suporte para manipulao de datas e horas)
e String.
Uma converso que no pode produzir um resultado significativo, produz uma
exceo do tipo InvalidCastException (falaremos mais sobre tratamento de exceo
posteriormente). Por hora, basta saber que um erro ser produzido em
transformaes do tipo: Char para Boolean, Single, Double, Decimal ou DateTime.

A unidade de programao orientada a objetos no C# a classe, tendo seu principal


fundamento a herana.

Os objetos so eventualmente criados dessas classes, e as funes so encapsuladas


dentro dos limites das classes como mtodos. Definies de classe C# no necessitam
de arquivos de cabealho ou arquivos separados (IDL, Interface Definition Language).
Tambm permite interfaces, um meio de fazer um contrato com uma classe para
processos que a interface determina. No C#, uma classe pode herdar de apenas um
objeto pai (parent), mas uma classe pode implementar mltiplas interfaces. C#
proporciona tambm um suporte a structs (estruturas). C# proporciona suporte total
de delegates (delegados): para invocao de mtodos indiretamente. Delegates so
referncia de tipos seguros que encapsulam mtodos com assinaturas e tipos de
retorno especficos.

Objetos instanciados de uma determinada classe, passam a ter as caractersticas


definidas na classe.
- Membros da classe:
Dados (membros de armazenamento)

Constantes.
Campos.
Eventos.

Funes (membros que contm cdigo)

Construtores.
Destrutor.
Propriedades.
Mtodos.
Indexadores.
Operadores.
Tipo identificador = new Tipo(...);
// Declara um identificador do tipo DateTime,
// cria uma instncia de um objeto DateTime na pilha
// e o inicializa com 25 de Dezembro de 2005.

DateTime natal = new DateTime(2005, 12, 25);


// Declara trs identificadores do tipo int (n1, n2 e n3),
// cria trs instncias de objetos int na pilha
// e os inicializa com o valor 0 (zero).

Int32 n1 = new Int32();


int n2 = new int();
int n3 = 0;
// Declara um identificador do tipo int,
// mas nenhum objeto instanciado...
// n4 no est inicializado.

int n4;
// Declara um identificador do tipo Horario,
// cria uma instncia de um objeto no heap
// e o inicializa com 9 horas 10 minutos e 20 segundos.

Horario horario = new Horario(9, 10, 20);

Exemplo de uma implementao ideal:

public class Horario : object


{
byte hora, minuto, segundo;
public Horario(byte hora, byte minuto, byte segundo) : base()
{
this.hora = hora;
this.minuto = minuto;
this.segundo = segundo;
}
}

A ideia por trs das propriedades que um mtodo ou grupo de mtodos seja
revestido de tal forma que parea um campo, no que diz respeito a qualquer cdigo
cliente.

As propriedades podem ser:

-read-write Acessores
Acessores get (somente)
get -write-only
set Acessores
- read-only set (somente)
public class Horario : object
{
...
public byte Hora
{
get
{
return hora;
}
set
{
hora = value;
}
}
}

O compilador C# d nfase a segurana quando o assunto inicializao de


variveis, ou seja, toda varivel deve ser inicializada antes de ser trabalhada.
Variveis que so campos de uma classe ou estrutura so zeradas por padro
to logo uma instncia da classe ou estrutura seja criada.
Variveis locais a um mtodo devero ser explicitamente inicializadas antes de
qualquer instruo na qual elas apaream.
Escopo
Regio de cdigo onde a varivel de fato existe.
Uma varivel de classe (campo) existe dentro da classe.
Uma varivel local existe dentro do bloco no qual foi declarada.
Uma varivel declarada num lao for tem escopo somente dentro deste lao.

public class FusoHorario : Horario


{
string pais;
public FusoHorario(string pais, byte hora, byte minuto, byte segundo)
: base(hora, minuto, segundo)
{
this.pais = pais;
}
new public string ToHora12()
{
return pais + ", " + base.ToHora12();
}
new public string ToHora24()
{
return pais + ", " + base.ToHora24();
}
}
Em C#, podem ser passados argumentos aos parmetros por valor ou por referncia.
Passagem por referncia permite que membros da funo, mtodos, propriedades,
indexadores, operadores e construtores para alterar o valor dos parmetros e fazer
essa alterao persistirem no ambiente de chamada. Para passar um parmetro por
referncia usa-se o ref ou out palavra-chave, tudo passado por valor a no ser
quando ref ou out especificado.

static void Main(string[] args)


{
int i = 5;
GetNext(ref i);
Console.WriteLine(i);
int quociente, resto;
Divide(10, 3, out quociente, out resto);
Console.WriteLine(quociente);
Console.WriteLine(resto);
}
static void GetNext(ref int numero)
{
numero++;
}
static void Divide(int dividendo, int divisor, out int quociente, out
int resto)
{
quociente = dividendo / divisor;
resto = dividendo % divisor;
}

static void Main(string[] args)


{
MostraTotal("Livros", 2, 5, 7, 1);
}
static void MostraTotal(string mensagem, params int[] numeros)
{
int tot = 0;
foreach (int numero in numeros)
{
tot += numero;
}
Console.WriteLine("{0} = {1}", mensagem, tot);
}
Membros de instncia pertencem ao objeto instanciado.
Cada objeto instanciado possui seu prprio conjunto de dados.
Quando no especificamos a palavra chave static, definimos um membro de
instncia.

Membros estticos pertencem a classe, no importando se h ou no a existncia de


uma instncia da classe.
Cada classe possui um e apenas um conjunto de dados estticos.
Quando especificamos a palavra chave static, definimos um membro esttico,
ou seja, um membro de classe.
Um membro esttico deve processar somente dados estticos, a no ser
claro que uma referncia a um objeto seja passada durante a chamada.

Numero obj1 = new Numero(5);


Numero obj2 = new Numero(5);
if (obj1 != obj2) Console.WriteLine("obj1 != obj2"); // Exibe
Numero obj3 = obj1;
if (obj3 == obj1) Console.WriteLine("obj3 == obj1"); // Exibe
string x, y;
x = "C# Language";
y = "C# Language"; // H uma otimizao do compilador neste ponto
// para a string anterior.
if (x == y) Console.WriteLine("x == y"); // Exibe
// O operador == est sobrecarregado para comparar o contedo
// e no o endereo dos objetos.

O operador new, serve par instanciar um novo objeto. Com o operador new, o sistema
operacional interpreta que tem que liberar uma determinada quantidade de memria
pra o programa. Perceba que tambm usamos esse operador para trabalhar com
vetores, matrizes, filas, pilhas, arvores e com objetos.

Instanciar um objeto, significa criar um novo objeto. Exemplos bsicos de instanciao


de objetos so as declaraes de variveis pelo mtodo:

int numero = new int();


bool flag = new bool();
double real = new double ();
Automaticamente, essas variveis sero inicializadas com valores padro. Acesse o
link: http://msdn.microsoft.com/pt-br/library/vstudio/83fhsxwc.aspx para ver mais dos valores
padres.

Prtica: Compile e analise o cdigo abaixo:

using System;

class Program
{
static void Main(string[] args)
{
//declarao de variveis (instanciando novos objetos).
int myInt = new int();
bool myBool = new bool();
float myFloat = new float();
double myDouble = new double ();

//imprimindo os valores das variveis.


Console.WriteLine("Inteiro: {0}",myInt);
Console.WriteLine("Bool: {0}",myBool);
Console.WriteLine("Float: {0}",myFloat);
Console.WriteLine("Double: {0}",myDouble);
//Aguardar para finalizar o programa.
Console.ReadKey();
}
}

Declarao de vetor e matrizes: Perceba a utilizao do operador new para alocar


memoria para o vetor e a matriz.

using System;
class Program
{
static void Main(string[] args)
{
//Declarando um vetor
int [] vetor = new int[4] { 1, 2, 3, 4 };
//Declarando uma matriz.
int[,] matriz = new int[2, 4] { {1,2,3,4}, {4,5,6,7}};

//Imprimindo os valores do vetor.


Console.WriteLine("Elementos do vetor: ");
foreach (int elemento in vetor)
Console.Write(" {0} ", elemento);

//Quebrando duas linhas


Console.WriteLine();
Console.WriteLine();
//Imprimindo os valores da matriz.
Console.WriteLine("Elementos da matiriz: ");
foreach(int elemento in matriz)
Console.Write(" {0} ",elemento);

Console.ReadKey();
}
}

Instanciando objetos:

using System;

namespace ConsoleApplication1
{
/*
* Classe Relogio.
*/

public class Relogio


{
//declarando as variveis.
private int seg;
private int min;
private int hr;
private char tipo;
private static int quantidade = 0;

//Construtores
//Construtor Padro
public Relogio()
{
this.tipo = '0';
quantidade++;
}
public Relogio(int hr, int min, int seg)
{
this.seg = seg;
this.min = min;
this.hr = hr;
this.tipo = '1';
quantidade++;
}
public Relogio(int hr, int min)
{
this.min = min;
this.hr = hr;
this.tipo = '2';
quantidade++;
}
//metodos get e set
//varivel seg
public int getSeg()
{
return this.seg;
}
public void setSeg(int seg)
{
this.seg = seg;
}

//variavel min
public int getMin()
{
return this.min;
}
public void setMin(int min)
{
this.min = min;
}

//varivel hr
public int getHr()
{
return this.hr;
}
public void setHr(int hora)
{
this.hr = hora;
}

//tipo
public char getTipo()
{
return this.tipo;
}

//varivel estatica quantidade


public static int getQuantidade()
{
return quantidade;
}

//Funes que um relogio Possui:


public void incremetar_hr()
{
if (this.tipo != '0')
this.hr++;
if (hr >= 24)
{
this.hr = 0;
if (tipo == '1')
Console.WriteLine("Mudou o dia! ");
}
}
public void incrementar_min()
{
if (this.tipo != '0')
this.min++;
if (this.min >= 60)
{
this.min = 0;
this.incremetar_hr();
}
}
public void incrementar_seg()
{
if (this.tipo != '0')
this.seg++;
if (this.seg >= 60)
{
this.seg = 0;
this.incrementar_min();
}
}
public void verHora()
{
if (tipo == '0')
System.Console.WriteLine("Relogio molde padro);
else if (tipo == '1')
{
if (this.hr >= 10)
System.Console.Write(hr);
else
System.Console.Write("0{0}", this.hr);
System.Console.Write(':');
if (this.min >= 10)
System.Console.Write(min);
else
System.Console.Write("0{0}", this.min);
System.Console.Write(':');
if (this.seg >= 10)
System.Console.Write(seg);
else
System.Console.Write("0{0}", this.seg);
}
else if (tipo == '2')
{
if (this.hr >= 10)
System.Console.Write(hr);
else
System.Console.Write("0{0}", this.hr);
System.Console.Write(':');
if (this.min >= 10)
System.Console.Write(min);
else
System.Console.Write("0{0}", this.min);
}

//Destrutores
~Relogio()
{
this.seg = 0;
this.min = 0;
this.hr = 0;
quantidade--;
}
}

/*
* Classe Principal.
*/
class Teste
{
static void Main(string[] args)
{

//Instanciando os objetos.
Relogio relogio0 = new Relogio();
Relogio relogio1 = new Relogio(1,2);
Relogio relogio2 = new Relogio(1,2,3);

//Mtodos dos objetos.


relogio2.verHora();
Console.WriteLine();

Console.WriteLine();
relogio2.verHora();
Console.ReadKey();
}
}
}

Modificadores de acesso servem, na POO, para identificar o nvel de acesso de


uma varivel, um mtodo ou uma classe. Para que uma classe possa ser vista/chamada
por todas as outras classes, basta que determine-se esta classe como public, por
exemplo. Vejamos:

public: Permite que todas as classes vejam quem for declarado desta forma.
private: No permite que nenhuma outra classe, alm da atual, veja quem for
declarado desta forma.

protected: O acesso permitido somente classe e aos seus derivados


(herdeiros) da classe.

internal: O acesso restrito somente s classes que esto no mesmo projeto.


Em java, equivale ao package.

protected internal: O acesso restrito s classes do mesmo projeto e s classes


derivadas da atual.

Estes modificadores servem para alterar o estado, diferentemente dos anteriores que
serviam para alterar o acesso. Estes modificadores so aplicadas em funes e/ou
varireis.

static: Fixa em uma classe um termo. Podemos perceber que sempre que a funo
principal ( Main() ) declara, utiliza-se deste modificador, uma vez que s existe uma
funo principal em todo o programa.

abstract: O modificador abstract pode ser aplicado tanto em classes como em


mtodos. Em classes, ele as cria de modo que no podem ser instanciadas pois so,
como o nome diz, abstratas. So classes incompletas.
Mtodos abstratos so forados a no possurem cdigo. Servem apenas de prottipo,
uma definio que dever ser obrigatoriamente implementada na classe filha.

interface: Interfaces so regras para a criao de outras classes, so moldes. Se uma


classe implementa uma interface ela obrigatoriamente tem que ter implementao
para tudo o que a interface tem.

As interfaces no podem ter variveis, no podem ter implementaes bsicas e no


podemos definir modificadores de acesso nos mtodos dela, quem deve fazer isso a
classe que a implementa. O legal que uma classe pode implementar vrias interfaces.
Lembrando que no podemos definir modificadores de acesso nos mtodos de uma
interface. Vamos ver um exemplo abaixo:

//Molde (interface) das classes.


interface IObjeto
{
string formato();
}

interface IColorido
{
public string cor();
}
//Classe chamada 'BolaVermelha' herda as outras classes
public class BolaVermelha : IObjeto, IColorido
{
public string formato()
{
return "esfrico";
}

public string cor()


{
return "vermelho";
}
}
unsafe: Usado quando se usa ponteiros em C#. Toda funo que usar um ponteiro
deve possuir esse modificador.

override: O modificador override simplesmente diz que o mtodo que ele segue est
sobrescrevendo outro, ou seja, voc est apagando o mtodo antigo e colocando no
lugar este novo. Veremos exemplos mais abaixo.

volatile: O modificador volatile permite que a varivel/propriedade possa ser


modificada por fatores externos, como o sistema operacional ou outros processos.
Com o modificador volatile voc garante que, independente do processo que esteja
acessando a vriavel/propriedade, ele pegar o valor atual da vriavel/propriedade
O tratamento de erros algo muito utilizado nas linguagens orientadas a objeto. O
tratamento de erros, recorre para erros que podem ocorrer durante a execuo do programa.
Erros que ocorrem com frequncia uma converso de tipos errada, acesso de um ndice de
vetor invalido, acesso de memria invlido, entre vrios outros.

A estrutura do tratamento

try
{
//Comandos para serem testados.
}
catch (NomeErro)
{
//Comandos caso o erro seja encontrado.
}
finally
{
/*
* Comandos que so realizados, no
* importando o resultado do teste
*/
}

Ser executado um trecho de cdigo que esta dentro do try, caso ocorra algum
erro, o que normalmente o fecharia, o programa automaticamente passa para a
estrutura que captura o erro (catch) que recebe como parmetro, mas no
obrigatoriamente, um erro especifico que ser tratado. A estrutura finally serve para
executar comandos que sempre devem ser executados, no importando se ocorreu ou
no erro no programa. Toda estrutura try deve possuir um catch, contudo o finally
opcional.

Para no se tratar um erro, mas identificar que este conhecido, basta utilizar
a clausula throw.

Veja o exemplo tirado do prprio site da Microsoft: http://msdn.microsoft.com/pt-


br/library/0yd65esw(v=vs.80).aspx

using System;
class MainClass
{
static void ProcessString(string s)
{
if (s == null)
{
throw new ArgumentNullException();
}
}

static void Main()


{
try
{
string s = null;
ProcessString(s);
}
catch (Exception e)
{
Console.WriteLine("{0} Exception caught.", e);
}

Console.ReadKey();
}
}

.Net o nome da plataforma criada pela Microsoft com o objetivo de fornecer


ao desenvolvedor um mecanismo nico para a criao e execuo de aplicaes. Foi
criado em 2002 e, ao longo do tempo, j recebeu diversas atualizaes e novas
verses.

O .Net executado sobre um ambiente livre de linguagem (Common Language


Runtime - CLR). Isso significa que o programador pode usar qualquer uma das
linguagens suportadas e, depois, converter seu programa para esse ambiente. Cerca
de 30 linguagens so suportadas pelo .Net algumas so: C#, C++, Java, Visual Basic e
Pascal.

Vous aimerez peut-être aussi