Sie sind auf Seite 1von 96

.

NET com C#

Como definir uma classe e seus atributos


public class Cliente { private int clienteId; private string nome; private decimal limiteCredito; private int quantidadeProdutos; }

Como criar uma instncia de uma classe


Cliente novoCliente = new Cliente();

So utilizados para definir nveis de acesso aos membros da classe

Declarao
public private internal

Definio
Acesso ilimitado Acesso limitado classe e seus membros Acesso limitado ao programa (assembly) Acesso limitado classe, seus membros e seus derivados Acesso limitado classe, classes derivadas ou membros deste programa (assembly)

protected
protected internal

Um mtodo um comando que representa uma ao


class Cliente { private int produtosAdquiridos; public bool EClienteEspecial() { if (produtosAdquiridos < 250) return false; return true; } public void ComprarEspecial() { /* AO */ } } Cliente proximoCliente = new Cliente();

bool clienteEspecial = proximoCliente.EClienteEspecial();


if (clienteEspecial) proximoCliente.ComprarEspecial();

Passando parmetros por valor


class Cliente { private int produtosAdquiridos; public void DefineProdutosAdquiridos(int quantidade) { produtosAdquiridos = quantidade; } } ... Cliente novoCliente = new Cliente(); int produtos = 255; novoCliente.DefineProdutosAdquiridos(produtos); //OR novoCliente.DefineProdutosAdquiridos(200);

Passando parmetros por referncia (usando ref)


public void RetornaEndereco(ref int numero, ref string rua) { numero = this.numero; rua = this.rua; } int numeroLocal = 0; string ruaLocal = ; // Note que numeroLocal e ruaLocal devem ser instanciados novoCliente.RetornaEndereco(ref numeroLocal, ref ruaLocal); // numeroLocal e ruaLocal recebem novos valores

Passando parmetros por referncia (usando out)


public Endereco getEndereco(out Rua rua, string nomeRua) { rua = new Rua(nomeRua); Endereco end = new Endereco(rua); return end; } Rua rua; string nomeRua; // Note que numeroLocal e ruaLocal no precisam ser instanciados Endereco en = novoCliente.getEndereco(out rua, nomeRua); // Objeto Rua inicializado dentro do mtodo

Utilizando sobrecarga de mtodos

public void DefineProdutosAdquiridos(int novoNumero) { this.produtosAdquiridos = novoNumero; } public void DefineProdutosAdquiridos(int novoNumero, bool clienteModificado) { if (clienteModificado) this.produtosAdquiridos = novoNumero; } public void DefineProdutosAdquiridos() { this.produtosAdquiridos = RecuperaProdutos(this.ClienteID); }

Construtores so mtodos especiais responsveis pela implementao de aes necessrias para a existncia de um objeto
public class Cliente { public int produtosAdquiridos; public readonly bool clienteEspecial; //Construtor default public Cliente() { if (this.produtosAdquiridos > 250) this.clienteEspecial = true; else this.clienteEspecial = false; }

Sobrecarga de Construtores
public class Cliente { public string nomeCliente; public int clienteId; public Cliente(): this (desconhecido, 0) { } public Cliente(string nome, int identificacao) { this.nomeCliente = nome; this.clienteId = identificacao; }
}

A herana est relacionada as hierarquias e as relaes entre os objetos. o mecanismo em que uma classe filha compartilha automaticamente todos os mtodos e atributos de sua classe pai. A herana permite implementar classes descendentes implementando os mtodos e atributos que se diferenciam da classe pai.

Simples
Quando uma classe herda as propriedades de uma nica classe pai.

Mltipla
Ocorre quando uma classe tem mais de um pai.

Criando uma classe derivada


public class Pessoa { public string nome; protected int id; public void Cadastrar() { /* rotina para cadastrar */ } } public class Cliente : Pessoa { public void Comprar(int idProduto) { /* ao */ } } ... Cliente proximoCliente = new Cliente(Rodrigo); proximoCliente.Cadastrar(); proximoCliente.Comprar(100);

Invocando um construtor da classe base na classe derivada


public class Pessoa { public Pessoa(string nome) { Console.WriteLine(Construindo Pessoa de Nome {0},nome); } } public class Cliente : Pessoa { public Cliente(string nome) : base(nome) { Console.WriteLine(Construindo Cliente); } } ... Cliente proximoCliente = new Cliente(Rodrigo); ... Construindo Pessoa de Nome Rodrigo Construindo Cliente

Classes Seladas so classes que no podem ser extendidas ou sobrescritas, ou seja, no podemos ter classes derivadas de classes seladas
public sealed class Pessoa { // Membros da Classe Pessoa }

Polimorfismo significa: Muitas Formas e representa o fato de uma determinada caracterstica ser diferente para cada filho. Partimos de um objeto mais simples e que vai evoluindo. Os conceitos do objeto pai continuam a existir, mesmo que tenham sofrido modificaes ou assumido novas formas.

Objetos

Mtodo Invocado

Comportamento

Diretor

Viajar()

Parcerias

Vendedor

Viajar()

Vendas

Funcionario

Viajar()

Frias

Utilizando mtodos virtuais


public class Pessoa { public virtual void Viajar() { /* Ao */ } } public class Diretor : Pessoa { public override void Viajar() base.Viajar(); /* Aes Particulares da } } public class Vendedor : Pessoa { public override void Viajar() /* Aes Particulares da } }

{ Classe Diretor */

{ Classe Vendedor */

Encapsulamento o ato de esconder do usurio informaes que no so de seu interesse. O objeto atua como uma caixa preta, que realiza determinadas operaes mas o usurio no sabe e no precisa saber exatamente como. Basicamente o encapsulamento separa os elementos visveis de um objeto dos invisveis.

So mtodos que protegem acesso aos membros da classe


public string Nome { get { return nomeCliente; } set { nomeCliente = value; } }

Como acessar as propriedades


string nomeCliente = novoCliente.Nome; novoCliente.Nome = Rodrigo Andrade;

Pode acontecer que ao escrever um mtodo para uma classe voc no saiba como ele vai ser implementado. Neste caso, a implementao ser feita pela classe que herdar o mtodo (a classe filha). Pode acontecer tambm que voc saiba que um determinado mtodo ser sobreposto com certeza na classe filha; ento, por que definir sua implementao se ela no ser usada ?

Nestes casos voc apenas define a assinatura do mtodo e deixa a definio por conta da classe que ir herdar a classe pai. Estas classes so ento chamadas classes abstratas, o mtodo que voc no implementou chamado de mtodo abstrato. As classes abstratas no podem ser instanciadas atravs da palavra chave New.

Uma classe abstrata uma classe base genrica


Contm mtodos abstratos que devem ser implementados nas classes que derivam dela

Um mtodo abstrato no apresenta implementao na classe base


public abstract class Pessoa { public abstract void Cadastrar(); public abstract string Nome { get; set; } public abstract int Id { get; } public virtual void Viajar() { /* Ao */ } }

Pode conter membros no-abstratos

Derivando a classe abstrata e implementando os membros abstratos


public class Diretor : Pessoa { public override void Cadastrar() { /* Aes */ } public override string Nome { get { /* Implementao get */ } set { /* Implementao set */ } } public override int Id { get { /* Implementao get */ } } }

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(:).

Uma interface define a mesma funcionalidade e comportamento classes no relacionadas diretamente Declarando a interface
public interface IProduto { bool EPerecivel { get; } Fornecedor RecuperarFornecedor(); void RegistrarVenda(Cliente cliente); }

Implementando a interface
public class Computador : IProduto { private bool ePerecivel; public bool EPerecivel { get { return ePerecivel; } } public Fornecedor RecuperarFornecedor() { return new Fornecedor(); } public void RegistrarVenda(Cliente cliente) { // Rotina para registrar vendas } }

IS e AS
if (computador is IProduto) { // aes } IProduto produto = computador as IProduto; if (produto != null) { Fornecedor fornecedor = produto.RecuperarFornecedor(); }

Pode tornar o comportamento de seus objetos semelhante ao comportamento dos objetos da .NET Framework Exemplos:
ICollection IComparer IDictionary
public class Cliente : Pessoa, IComparable { ... }

Declarando um namespace
namespace NomeEmpresa { public class Cliente {} }

Namespaces em cadeia
namespace NomeEmpresa { namespace Vendas { public class Cliente {} } } //OR namespace NomeEmpresa.Vendas { public class Cliente {} }

Instruo Using
using using using using System; System.Data; NomeEmpresa.Vendas; Pessoa = ClassLibrary.Person;

// Faz comentrio de uma linha apenas /* */


Faz comentrio de mltiplas linhas ou blocos de cdigo

#region Area public int Calcula(int x, int y){ } #endregion

Documentao XML

/// <summary> /// Define a quantidade de produtos adquiridos /// </summary> /// <param name=novoNumero>Nmero de produtos adquiridos</param> /// <param name=clienteModificado>Indica se o cliente pode ser modificado /// depois de criado</param> public void DefineProdutosAdquiridos(int novoNumero, bool clienteModificado) { if (clienteModificado) this.produtosAdquiridos = novoNumero; }

byte sbyte int uint long ulong short ushort decimal double float bool char string

Inteiro de 8 bits sem sinal


Inteiro com sinal de 8 bits Inteiro de 32 bits com sinal

Inteiro de 32 bits sem sinal


Inteiro com sinal de 64 bits Inteiro sem sinal de 64 bits

Inteiro com sinal de 16 bits


Inteiro sem sinal de 16 bits Ponto flutuante decimal Este tipo tem uma preciso de 28 casas decimais. Ponto flutuante binrio.Este tipo tem uma preciso de 15 casas decimais. Ponto flutuante binrio. Este tipo tem uma preciso de 7 casas decimais. Tipo de dados booleano, pode ser apenas true ou false. Um nico caractere unicode de 16 bits. Unicode com at 1 gigabyte de caracteres.

Valor (Value Types)


Referncia (Reference Types)

Contm dados diretos Armazenado na memria Stack Precisa ser inicializado No pode ser nulo Exemplo: um inteiro

Contm uma referncia a um dado Armazenado na memria Heap Declarado usando a palavra new .NET Garbage Collection gerencia a liberao da memria Exemplo: uma classe

int i; i = 42;

Object c = new Object(); c = i;

42

42

int i = 123; object O; O = i; string S; S = O.ToString() int x; x = (int) O; Stack x O i


123

// Tipo por valor // Tipo por referncia // Causa boxing // Chama via O // Faz unboxing Heap
123

123

Aritmticos

Atribuio

Concatenao

Criao de Objetos

Igualdade Diferena

+, -, *, /, %

=, +=, -=, *=, /=, <<=, >>=, &=, ^=, |=

New

==, !=

Incremento

Decremento

Lgicos

Primrios

Relacionais

++, --

&, ^, |, &&, ||, ~, !

typeof, sizeof, checked, unchecked

<, >, <=, >=, is

if ... else if ... else,

A clusula if ocorre apenas uma vez A clusula else if pode ocorrer nenhuma ou vrias vezes A clusula else opcional.
if (condio1) { instrues1; } else if (condio2) { instrues2; } else { instrues3; }

switch case
Estruturas de deciso caracterizadas pela possibilidade de uma varivel possuir vrios valores. A clusula switch ocorre uma vez A clusula case pode ocorrer de uma a vrias vezes, e default opcional.
switch (varivel) { case 1 valor que a varivel pode case 2 valor que a varivel pode case 3 valor que a varivel pode default: instrues para condies } assumir: instrues1; break; assumir: instrues2; break; assumir: instrues3; break; no previstas explicitamente;

for
Estrutura de repetio caracterizada pela existncia de trs parmetros:
Valor inicial, Condio para parada das iteraes, Quantidade de incrementos/decrementos a cada iterao.
for (int i=0; i>valor; i++) { instrues; }

while
Estrutura de repetio que realiza as operaes desejadas enquanto a condio especificada for verdadeira.
while (condio) { instrues; }

foreach
Esta estrutura de repetio uma variao do for. Sua diferena est no fato de ser necessrio apenas especificar uma varivel e a coleo (array) cujos registros sero percorridos.
foreach (int i in vetor) { instrues; }

do ... while
Estrutura de repetio semelhante anterior, com o diferencial de que as condies so verificadas no final da execuo, permitindo as operaes especificadas sejam executadas pelo menos uma vez.
do { instrues; } while (condio);

Sintaxe do tratamento de excees


// cdigo factvel de erro

try {

} catch (NullReferenceException ex) { // trata excees de referncia nula } catch { // trata outras excees } finally { // executa sempre }

Estrutura de dados que contm um nmero certo de variveis (elementos do array) Todos os elementos do array tem que ser do mesmo tipo Arrays so indexados a partir de zero (0) Arrays so objetos Arrays podem ser:
Unidimensionais: um array de ordem um Multidimensionais: um array de ordem maior que um Jagged: um array cujos elementos so arrays

Arrays possuem mtodos especficos para manipulao dos seus itens

Para declarar um Array, basta adicionar um par de colchetes logo aps a declarao do tipo dos elementos individuais
private int[] meuVetorDeInteiros; public string[] meuVetorDeStrings;

Devem ser instanciados


int[] codigos = new int[5]; string[] nomes = new string[100];

Podemos criar um Array de Objetos


object[] produtos = new object[50];

Inicializando um array
int[] pedidos = {1, 4, 6, 8, 10, 68, 90, 98, 182, 500};

Acessando membros do array


Cliente[] clientes = { new Cliente(Rodrigo), new Cliente(Eduardo) }; clientes[0].Idade = 20; clientes[1] = new Cliente(Marcelo); Console.WriteLine({0} e {1}, clientes[0].Nome, clientes[1].Nome);

Utilizando a instruo foreach para percorrer todos os itens de um Array Cliente[] clientes = {
new Cliente(Rodrigo), new Cliente(Eduardo), new Cliente(Marcelo) }; foreach (Cliente clienteDaVez in clientes) { Console.WriteLine(Cliente {0}, clienteAtual.Nome); } ... Cliente Rodrigo Cliente Eduardo Cliente Marcelo

Passando um array como parmetro para um Mtodo Utilizar a palavra params para passar um nmero varivel de parmetros
public void ContagemProdutos (params int[] list) { int total = 0; foreach (int i in list) { total += i; // total = total + i; } this.produtosAdiquiridos = total; } ... Cliente novoCliente = new Cliente(); novoCliente.ContagemProdutos(22, 25, 27, 19); Console.WriteLine(novoCliente.ProdutosAdquiridos); ... 93

ArrayLists no tem tamanho definido Use o mtodo Add(object) para adicionar um elemento ao fim do ArrayList Use os colchetes para acessar os elementos do ArrayList Est localizado no Namespace System.Collections Use o mtodo Clear() para remover todos os elementos do array Uso recomendado para manipulao de objetos em Programao Orientada a Objetos

Transformando um Array em um ArrayList Transformando um ArrayList em um Array


Cliente[] clientes = empresa.RecuperaClientes(); //Convertendo o Array em ArrayList ArrayList clientesAux = new ArrayList(clientes); clientesAux.Add(new Cliente(Rodrigo, 11)); //Convertendo o ArrayList em Array clientes = new Clientes[clientesAux.Count]; clientesAux.CopyTo(clientes); ... Console.WriteLine(clientes[3].Nome); ... Rodrigo

Para criar indexadores utilize a palavra-chave this e as instrues get e set


public class CarroCompras { private Produto[] produtosSelecionados; public CarroCompras() { produtosSelecionados = new Produto[10]; } public Produto this[int i] { get { return produtosSelecionados[i]; } set { produtosSelecionados[i] = value; } } }

Consumindo indexadores
CarroCompras carro = new CarroCompras(); carro[0] carro[1] carro[2] carro[3] = = = = new new new new Produto(Televisor); Produto(Geladeira); Produto(Computador); Produto(Microondas);

Conceitos:
Evento: ao que pode ser gerenciada/manipulada atravs de cdigo
Delegate: membro da classe responsvel por delegar as aes correspondentes a ocorrncia de um evento ao(s) manipulador(es) de eventos correspondentes Manipulador de Evento: mtodo responsvel pela execuo de aes em reao a ocorrncia de um evento

Cinco passos para se trabalhar com eventos


Passo 1: declarar o delegate contendo a assinatura do manipulador de evento correspondente ao evento
public class Cliente { public delegate void delegateProdutos(int produtos); }

Passo 2: declarar o evento (deve ser do mesmo tipo do delegate correspondente)


public class Cliente { public delegate void delegateProdutos(int produtos); public event delegateProdutos EventoProdutos; }

Passo 3: disparar o evento na chamada de algum mtodo da classe


public class Cliente { ... public void MetodoEvento(int produtosAdquiridos) { this.EventoProdutos(produtosAdquiridos); } }

Passo 4: assinar o evento indicando o manipulador de eventos do mesmo atravs de uma instncia de delegate
cliente.EventoProdutos += new Cliente.delegateProdutos(ManipuladorEvento);

Passo 5: implementar o manipulador de evento (deve respeitar a mesma assinatura definida pelo delegate do evento)
public void ManipuladorEvento(int produtos) { label1.Text = produtos.ToString(); }

Definindo Tipos Enumeradores


enum TipoDiretor { Marketing, RH, Comercial, Financeiro }

Usando Tipos Enumeradores


TipoDiretor tpDiretor = TipoDiretor.Comercial;

Mostrando Variveis
Console.WriteLine({0}, tpDiretor); //Mostra Comercial

Tipos por valor que podem conter construtores, constantes, atributos, mtodos, propriedades, indexadores e eventos Uso recomendado para representar objetos leves e/ou que eventualmente podem constituir arrays de grande dimenso Podem ser inicializadas sem o uso do operador new No h suporte a herana

Definindo estruturas
public struct ProdutoS { public int identificacao; public string nome; public ProdutoS (int identificacao, string nome) { this.identificacao = identificacao; this.nome = nome; } }

Consumindo estruturas
ProdutoS produtoSimples; produtoSimples.identificacao = 1131; ProdutoSimples.nome = Televisor;

Mtodo esttico que serve para implementar um certo operador (+, -, *, /, ==, >=, &, ...)
class Conta { public double saldo; public Conta(double saldo) { this.saldo = saldo; } public static Conta operator + (Conta a, Conta b) { return new Conta(a.saldo + b.saldo); } } Conta c1 = new Conta(5); Conta c2 = new Conta(10); Conta c3 = c1 + c2; // Retornar uma conta com saldo 15

Converso implcita
Sempre possvel, sem perda de preciso Ex.: long = int

Converso explcita
necessria uma verificao em tempo de execuo (cast) Ex.: int = (int) long;

public static implicit operator Conta (int x) { return new Conta(x); } public static explicit operator int (Conta c) { return c.saldo; }

Conta c = 3; //converso implcita int x = (int) c; //converso explcita

Recurso da verso 2.0 do .NET Framework Permitem parametrizar classes, estruturas, interfaces e mtodos Permitem a criao de classes tipadas Localizados no namespace System.Collections.Generic

Classes genricas podem usar restries para suportar somente determinados tipos de dados

Declarando uma lista utilizando a classe List<Tipo>


//Criando uma lista de clientes List<Cliente> meusClientes = new List<Cliente>();

Trabalhando com a lista genrica


Cliente novoCliente = new Cliente(Rodrigo, 3); Vendedor novoVendedor = new Vendedor(Eduardo, 4); //Mesmas funcionalidades do ArrayList meusClientes.Add(novoCliente); meusClientes.Remove(novoCliente); //Gera erros em tempo de compilao meusClientes.Add(novoVendedor);

Vantagens:
Soluo de uma limitao existente nas verses anteriores, onde a generalizao era feita atravs de Casts (boxing e unboxing). Permitem um ganho de performance ao armazenar ou recuperar dados, pois no necessria converso de tipos. Prov uma maneira mais elegante de implementao, verificando os erros em tempo de compilao. Traz classes genricas muito teis (List, Queue, Stack, LinkedList).

Declarando uma pilha utilizando a classe Stack<Tipo>


//Criando uma pilha de vendedores Stack<Vendedor> pilhaVendedores = new Stack<Vendedor>();

Trabalhando com a pilha genrica


Cliente novoCliente = new Cliente(Rodrigo, 3); Vendedor novoVendedor = new Vendedor(Eduardo, 4); //Mesmas funcionalidades da pilha no-genrica pilhaVendedores.Push(novoVendedor); pilhaVendedores.Pop(); //Gera erros em tempo de compilao pilhaVendedores.Push(novoCliente);

Declarando uma fila utilizando a classe Queue<Tipo>


//Criando uma fila de clientes Queue<Cliente> filaClientes = new Queue<Cliente>();

Trabalhando com a fila genrica


Cliente novoCliente = new Cliente(Rodrigo, 3); Vendedor novoVendedor = new Vendedor(Eduardo, 4); //Mesmas funcionalidades da fila no-genrica filaClientes.Enqueue(novoCliente); filaClientes.Dequeue(); //Gera erros em tempo de compilao filaClientes.Enqueue(novoVendedor);

Declarando uma lista encadeada com a classe LinkedList<Tipo>


//Criando uma lista encadeada de clientes LinkedList<Cliente> listaCli = new LinkedList<Cliente>();

Trabalhando com a lista encadeada


Cliente novoCliente = new Cliente(Rodrigo, 3); Cliente novoCliente2 = new Cliente(Carlos, 7); Vendedor novoVendedor = new Vendedor(Eduardo, 4); //Trabalhando com a lista encadeada listaCli.AddHead(novoCliente); listaCli.AddTail(novoCliente2); //Remove o novoCliente da lista listaCli.RemoveFirst(); //Adiciona o novoCliente aps o novoCliente2 listaCli.AddBefore(novoCliente2, novoCliente); //Gera erros em tempo de compilao listaCli.AddTail(novoVendedor);

public class Funcionario<T> { private int idFunc; static List<T> listaFuncionarios = new List<T>(); public void Adicionar(T func) { ... } public void Remover(T func) { ... } }

Declarando uma classe genrica

// Declarando uma instncia da classe genrica Funcionario<Diretor> listaDiretores = new Funcionario<Diretor>(); Funcionario<Vendedor> listaVendedores = new Funcionario<Vendedor>(); //Trabalhando com as instncias da classe genrica listaDiretores.Adicionar(novoDiretor); listaVendedores.Adicionar(novoVendedor);

Utilizadas quando necessrio restringir os tipos que podero ser usados como parmetros, quando a classe genrica for instanciada. Caso o programador tente instanciar a classe com um tipo no permitido pela restrio aplicada, ocorrer um erro em tempo de compilao. Definidas atravs do termo where associado ao parmetro genrico e seguido de uma lista de tipos aplicveis ao parmetro genrico.

Tipos de Restries
Constraint
where<T>: estrutura

Descrio
O tipo do argumento deve ser um valor. Qualquer tipo de valor pode ser especificado, exceto Nullable<T>. O tipo do argumento deve ser um tipo por referncia, incluindo qualquer tipo classe, interface, delegate e array. O tipo do argumento deve conter um construtor pblico e sem parmetros. Quando utilizada com outras restries, a constraint new deve ser a ltima. O tipo do argumento deve ser ou derivar da classe base. O tipo do argumento deve ser ou implementar a interface especificada. Podem ser espeficada mltiplas constraints de interface.

where<T>: classe

where<T>: new() where<T>: <nome da classe base> where<T>: <nome da interface>

Utilizando restries na classe Funcionrio


public class Funcionario<T> where T: Vendedor, new() { private int idFunc; static List<T> listaFuncionarios = new List<T>(); public void Adicionar(T elemento) { ... } public void Remover(T elemento){ ... } }

A restrio criada s permite que seja recebido um parmetro do tipo Vendedor


// Utilizao correta Funcionario<Vendedor> listaVend = new Funcionario<Vendedor>();
// Gera erro em tempo de compilao Funcionario<Diretor> listaDiretores = new Funcionario<Diretor>();

Restries com Interfaces


interface IProduto { void Mostrar(); } public class Produto<T> { public void P(T aux) { // erro: nao existe forma de saber que T implementa este mtodo aux.Mostrar(); } }

Adicionando a restrio
interface IProduto { void Mostrar(); } public class Produto<T> where T: IProduto { public void P(T aux) { aux.Mostrar(); } }

Mltiplas restries podem ser aplicadas para o mesmo tipo de parmetro, e as prprias constraints podem utilizar generics.
public class Funcionario<T> where T: Diretor, IComparable<T>, new() { }

Uma restrio no pode utilizar mais de uma classe ou estrutura para o mesmo tipo de parmetro. O nico tipo que pode ser utilizado vrias vezes na restrio so as interfaces.
public class Funcionario<T> where T: Diretor, Vendedor {} // Erro! public class Funcionario<T> where T: Diretor, IComparable<T>, IEnumerable<T>, new() { ... } // Ok!

Alm do uso em classes, podemos utilizar generics em mtodos, interfaces e delegates. Vrias interfaces utilizam generics (IEnumerable<T>, IEnumerator<T>, IComparable<T>, etc). Declarando uma interface genrica
// Interface utilizando generics interface IProduto<T> { int CodigoPro { get; set; } string NomePro { get; set; } }

Ao trabalhar com uma classe genrica que implemente uma interface, prefervel que a interface tambm seja genrica, para evitar boxing e unboxing.
public class Produto<T> : IProduto<T> { ... }

Declarando um mtodo genrico


public void Troca<T>(ref T a, ref T b) { T temp; temp = a; a = b; b = temp; }

Chamando um mtodo genrico


Cliente novoCliente = new Cliente(Joao,7); Cliente novoCliente2 = new Cliente(Pedro,8); ... Troca<Cliente>(ref novoCliente,ref novoCliente2);

possvel tambm omitir o tipo do argumento


// O compilador saber inferir o tipo Troca(ref novoCliente,ref novoCliente2);

Em uma classe genrica, mtodos no-genricos podem acessar o tipo do parmetro genrico
public class Funcionario<T> where T: Vendedor, new() { private int idFunc; public void Adiciona(T func) { ... }; public void Remove(T func) { ... }; }

Definir um mtodo genrico com o mesmo tipo da classe genrica intil e gerar um warning
public class Funcionario<T> { private int idFunc; public void Adiciona<T>(T func) {...} public void Remove<T>(T func) {...} }

Utilizando a palavra-chave default, quando necessrio atribuir um valor um tipo parametrizado e ainda no se sabe qual o tipo do parmetro
public class Lista<T> { ... public T ProximoItem() { T temp = default(T); if (current != null) { temp = current.Data; current = current.Next; } return temp; } }

Recurso da verso 2.0 Permite dividir a implementao de um determinado tipo em diversos arquivos. Disponvel para classes, estruturas e interfaces. Definidos pela palavra-chave partial.

Quando podem ser utilizados:


Quando trabalhamos com cdigo gerado automaticamente, cdigo pode ser adicionado classe sem ter que recriar o arquivo fonte. Partial Types permitem que dois ou mais desenvolvedores trabalhem no mesmo tipo, enquanto ambos tm seus arquivos checados para edio, sem interferir um no outro.

ClienteP1.cs Declarando uma classe parcial


public partial class Cliente { public int codigo; public bool EClienteEspecial() { } }

ClienteP2.cs
public partial class Cliente { int produtosAdquiridos; public int ProdutosAdquiridos { get { } set { } } }

Recurso da verso 2.0. Variveis continuam a representar todos os valores do seu tipo, e mais um valor adicional null. Permite uma integrao melhor com bancos de dados, que podem conter valores null em seus campos. Declaradas atravs da classe Nullable, ou atravs do operador ? adicionado ao tipo ser utilizado.

Podem ser declaradas de duas formas:


System.Nullable<T> variavel; <T>? variavel;

Onde T o tipo da varivel Ambas notaes funcionam de maneira equivalente int? clienteId; e usando uma varivel inteira e anulvel Declarando
clienteId = 10; //Ok clienteId = null; //Ok, clienteId anulvel

Qualquer tipo por valor pode ser usado como Nullable Type
int? i = 10; double? x = 3.14; bool? flag = null; char? letra = 'a'; int?[] MeuArray = new int?[10];

Os exemplos seguintes no so tipos por valor, portanto no so aceitveis como Nullable Types
string? variavel = tipos anulaveis; Cliente? umCliente = new Cliente?();

Utilizando as propriedades de um tipo anulvel


int? clienteId = 10; if (clienteId.HasValue) Console.WriteLine(clienteId.Value); else Console.WriteLine(Identificao do Cliente Indefinida!);

Converses explcitas
// Exemplos int? clienteId = null; // No compila int y = clienteId; // Compila, mas ser gerada uma exception se x for null int y = (int)clienteId; // Compila, mas ser gerada uma exception se x for null int y = clienteId.Value;

Converses implcitas
A converso de um tipo anulvel para um tipo regular implcita.
int? produtosAdquiridos = null; // Converso implcita int produtosAdquiridos = 10;

Operadores
Quaisquer operadores existentes para tipos por valor podem ser utilizados com Nullable Types. O operador produzir null se os operandos forem nulos, caso contrrio, usar o valor contido para calcular o resultado.
int? x = 10; x++; x = x * 10; int? y = null; x = x + y; // x agora 11 // x agora 110 // x agora null

Das könnte Ihnen auch gefallen