Introdução à # Linguagem C Prof.Dr. Antonio Geraldo da Rocha Vidal EAD-5881 - Tecnologia de Informática FEA/USP Hello World using System; class Hello { static void Main( ) { Console.WriteLine(“Olá Mundo!"); Console.ReadLine(); // Enter para finalizar } } Metas de projeto do C# Orientação para componentes Tudo é objeto Construção de software robusto e durável Integração ao software já existente, preservando investimentos. Metas de projeto do C# Orientação para Componentes C# pode ser considerada uma linguagem orientada para objetos e componentes da família do C/C++ O que é um componente? Um módulo independente quanto a desenvolvimento e reutilização Menos granulares que objetos Os objetos são construções ao nível da linguagem Os componentes são construções ao nível da aplicação Inclui múltiplas classes Freqüentemente independentes da linguagem Em geral, o desenvolvedor e o usuário de componentes não se conhecem, não trabalham para a mesma empresa e não utilizam a mesma linguagem de programação Metas de projeto do C# Orientação para Componentes Conceitos de componentes: Propriedades, métodos, eventos Atributos de projeto (design-time) e de execução (run-time) Documentação integrada usando XML Permitem “one-stop programming” Sem arquivos de cabeçalho, IDL, etc. Podem ser embutidos nas páginas ASP Metas de projeto do C# Tudo é Objeto Visões tradicionais: C++, Java™: os tipos primitivos são “mágicos” e não interoperam com objetos Smalltalk, Lisp: os tipos primitivos são objetos, mas com um grande custo de desempenho C# unifica estas visões com bom desempenho Grande simplicidade ao longo de todo sistema Extensibilidade e reusabilidade aprimorados: Novos tipos primitivos: Decimal, SQL… Coleções, etc., trabalham com todos os tipos Metas de projeto do C# Software Robusto e Durável Coletor de lixo Nenhum vazamento de memória e ponteiros perdidos A manipulação de exceções é padronizada Estrutura “tipada” e segura Nenhuma variável sem inicialização, nenhum conteúdo inseguro Versionamento Evita erros comuns Por exemplo: if (x = y) ... Programação “sem escalas” (one-stop programming) Menos “partes móveis” Metas de projeto do C# Preservar Investimentos Heranças do C++: Namespaces, pointers (em código inseguro), unsigned types, etc. Algumas mudanças, mas nenhum sacrifício desnecessário Interoperabilidade Todo software precisa estar integrado C# fala com XML, SOAP, COM, DLLs, e qualquer linguagem compatível com o .NET Framework Produtividade aumentada Curva aprendizado pequena Há milhões de linhas de código C# na plataforma .NET Tipos de Objetos Visão Um programa C# é uma coleção de tipos de objetos: Classes, structs, enums, interfaces, delegates C# fornece um conjunto de tipos predefinidos Isto é: int, byte, char, string, object Você pode criar seus próprios tipos Todos os dados e códigos são definidos dentro de um tipo de objeto: Nenhuma variável global, nenhuma função global Tipos de Objetos Visão Os tipos de objeto podem conter: Dados Funções Campos, constantes, arrays Eventos Métodos, operadores, construtores, destruidores Propriedades, indexadores Outros tipos Classes, structs, enums, interfaces, delegates Tipos de Objetos Visão Os tipos de objetos podem ser instanciados: …e então usados: chamar métodos, obter e configurar propriedades, etc. Pode-se converter de um tipo de objeto para outro: Implicitamente e explicitamente Os tipos de objetos são organizados fisicamente em arquivos: Namespaces, files, assemblies Os tipos são organizados logicamente em uma hierarquia Existem duas categorias de tipos: valor e referência Tipos de Objetos Sistema Unificado de Tipos Tipos de valor Contém dados Não podem ser nulos Tipos de referência Contém referências a objetos Podem ser nulos int i = 123; string s = “Olá pessoa!"; i s 123 “Olá pessoal!" Tipos de Objetos Sistema Unificado de Tipos Tipos de valor Primitivos int i; float x; Enumerações enum State { Off, On } Estruturas struct Point {int x,y;} Tipos de referência Root String Classes Interfaces Arrays Delegates object string class Foo: Bar, IFoo {...} interface IFoo: IBar {...} string[] a = new string[10]; delegate void Empty(); Tipos de Objetos Sistema Unificado de Tipos Variável armazena Alocou Conteúdo Valor padrão Alias = Significa Pode herdar Valor (Struct) Referência (Class) Valor real Alocação na memória Pilha, membro “Ponteiro” Sempre tem um valor Pode ser nulo 0 null Não Sim Cópia do valor Cópia da referência Não Sim Tipos de Objetos Sistema Unificado de Tipos Benefícios de tipos de valor: Nenhuma alocação volumosa Uso mais eficiente da memória Menos referência indireta Sistema de tipo unificado Sem a dicotomia PRIMITIVO X OBJETO Tipos de Objetos Conversões Conversões implícitas Ocorrem automaticamente Garantia de sucesso Nenhuma perda na precisão das informações Conversões explícitas Exige um elenco Podem não ter sucesso Informações (precisão) podem ser perdidas Ambas conversões implícitas e explícitas podem ser definidas pelo usuário Tipos de Objetos Conversões int x = 123456; long y = x; short z = (short)x; // implícita // explícita double d = 1.2345678901234; float f = (float)d; long l = (long)d; // explícita // explícita Tipos de Objetos Sistema Unificado de Tipos Tudo é objeto: Em última instância, todos os tipos são herdados de objetos. Qualquer pedaço de dados pode ser armazenado, transportado, e manipulado sem trabalho extra. object Stream MemoryStream Hashtable FileStream int double Tipos de Objetos Sistema Unificado de Tipos Polimorfismo A habilidade de usar ou armazenar um objeto sem saber seu tipo preciso void Poli(object o) { Console.WriteLine(o.ToString()); } Poli(42); Poli(“abcd”); Poli(12.345678901234m); Poli(new Point(23,45)); Tipos de Objetos Sistema Unificado de Tipos Observação: os tipos de valor e de referência têm semântica muito diferentes Pergunta: como podemos tratar os tipos de valor e de referência polimorficamente? Como um int (tipo valor) pode ser convertido em um objeto (tipo referência)? Como podemos unificar tipos de valor e de referência? Solução: Boxing! Tipos de Objetos Sistema Unificado de Tipos Boxing copia um tipo valor para um tipo referência Unboxing faz a cópia inversa int i = 123; i object o = i; o int j = (int)o; 123 System.Int32 123 j 123 Tipos de Objetos Sistema Unificado de Tipos Boxing Copia um tipo valor para um tipo referência (objeto) Cada tipo valor tem o correspondente (“hidden”) tipo referência Note que uma cópia de valor referência é feita pelo tipo valor. Os tipos de valor nunca são aliased O tipo valor é convertido implicitamente para objeto, um tipo referência Essencialmente um “up cast” Tipos de Objetos Sistema Unificado de Tipos Unboxing Operação inversa de boxing Copia o valor para fora do box Cópia do tipo referência para o tipo valor Exige uma conversão de explícita Pode não ser bem-sucedido Essencialmente um “down cast” Tipos de Objetos Sistema Unificado de Tipos Benefícios Habilita polimorfismo através de todos os tipos Classes de coleção trabalham com todos os tipos Elimina a necessidade de classes para conversão Substitui o OLE Automation's Variant Muitos exemplos na .NET Framework Hashtable t = new Hashtable(); t.Add(0, "zero"); t.Add(1, "one"); string s = string.Format( t.Add(2, "two"); “Sua nota foi {0} em um total de {1}", date); Tipos de Objetos Pré-definidos Valor Integral types Floating point types decimal bool char Referência object string Tipos predefinidos Tipos Valor Todos são estruturas (structs) predefinidas Com sinal sbyte, short, int, long Sem sinal byte, ushort, uint, ulong Caractere char Ponto flutuante Lógico float, double, decimal bool Tipos predefinidos Tipos Inteiros Tipo C# Tipo System Tamanho (bytes) Sinal? sbyte System.Sbyte 1 Sim Short System.Int16 2 Sim Int System.Int32 4 Sim Long System.Int64 8 Sim Byte System.Byte 1 Não Ushort System.UInt16 2 Não Uint System.UInt32 4 Não Ulong System.UInt64 8 Não Tipos predefinidos Tipos Ponto Flutuante Segue a especificação IEEE 754 Suporta ± 0, ± Infinito, NaN Tipo C# Tipo System Tamanho (bytes) float System.Single 4 double System.Double 8 Tipos predefinidos decimal 128 bits Essencialmente um valor 96 bit elevado à uma potência de 10 Valores decimais são representados precisamente Não suporta zeros com sinais, infinito ou NaN Tipo C# Tipo System Tamanho (bytes) decimal System.Decimal 16 Tipos predefinidos decimal Todos os tipos inteiro podem ser implicitamente convertidos para um tipo decimal As conversões entre decimal e tipos flutuantes exigem conversão explícita devido à possibilidade de perda de precisão e s * m * 10 s = 1 or –1 96 0m2 -28 e 0 Tipos predefinidos Inteiros Literais Integer literals podem ser expressos como decimal ou hexadecimal U ou u: uint ou ulong L ou l: long ou ulong UL ou ul: ulong 123 0x7B 123U 123ul 123L // // // // // Decimal Hexadecimal Unsigned Unsigned long Long Tipos predefinidos Reais Literais F ou f: float D ou d: double M ou m: decimal 123f 123D 123.456m 1.23e2f 12.3E1M // // // // // Float Double Decimal Float Decimal Tipos predefinidos booleano Representa valores lógicos Os valores literais são true e false Não se pode usar 1 e 0 como valores booleanos Nenhuma conversão padrão entre outros tipos e booleano Tipo C# Tipo System Tamanho (bytes) bool System.Boolean 1 (2 for arrays) Tipos predefinidos char Representa um caractere Unicode Literais ‘A’ ‘\u0041’ ‘\x0041’ ‘\n’ // Caractere simples // Unicode // Hexadecimal pequeno sem sinal // Caractere ecape Tipo C# Tipo System Tamanho (bytes) Char System.Char 2 Tipos predefinidos char Caracteres de seqüência de fuga (lista parcial) Char Significado Valor \’ Aspa simples 0x0027 \” Aspa dupla 0x0022 \\ Barra invertida 0x005C \0 Nulo 0x0000 \n Mudança de linha 0x000A \r Retorno do carro 0x000D \t Tabulação 0x0009 Tipos predefinidos Tipos Referência Tipo raiz (primitivo) object Cadeia de caracteres string Tipos predefinidos object Raiz da hierarquia de objetos Armazenamento (book keeping) 0 bytes para tipos valor 8 bytes para tipos referência Uma referência real (não um objeto) usa 4 bytes Tipo C# Tipo System Tamanho (bytes) object System.Object 0/8 overhead Tipos predefinidos object Métodos Públicos public bool Equals(object) public bool ReferenceEquals(object) protected void Finalize() public int GetHashCode() public System.Type GetType() protected object MemberwiseClone() public void Object() public string ToString() Tipos predefinidos string Uma seqüência de caracteres Unicode (“imutável”) Tipo referência Sintaxe especial para literais string s = “Eu sou uma string”; Tipo C# Tipo System Tamanho (bytes) String System.String 20 mínimo Tipos predefinidos string Normalmente precisam ser utilizados caracteres de fuga: string s1= “\\\\server\\fileshare\\filename.cs”; Strings literais: A maioria de seqüências fuga são ignoradas Com exceção de “” Literais podem ter múltiplas linhas string s2 = @“\\server\fileshare\filename.cs”; Tipos de Objetos Tipos Definidos pelo Usuário Tipos definidos pelo usuário Enumerations Arrays Interface enum int[], string[] interface Reference type class Value type struct Function pointer delegate Tipos de Objetos Enums Um enum define um tipo para um grupo relacionado de constantes simbólicas As escolhas devem ser conhecidas em tempo de compilação Fortemente tipado: Nenhuma conversão implícita de/para int Pode ser explicitamente convertido Operadores: +, -, ++, --, &, |, ^, ~, … Pode especificar um tipo subjacente byte, sbyte, short, ushort, int, uint, long, ulong Tipos de Objetos Enums enum Color: byte { Red = 1, Green = 2, Blue = 4, Black = 0, White = Red | Green | Blue } Color c = Color.Black; Console.WriteLine(c); Console.WriteLine(c.Format()); // 0 // Black Tipos de Objetos Enums Todos enums derivam de System.Enum Fornece métodos para: Determinar o tipo subjacente O testar se um valor é suportado Inicializar a partir de uma constante string Recuperar todos os valores em enum … Tipos de Objetos Arrays Os arrays (vetores) permitem que um grupo de elementos de um tipo específico sejam armazenados em um bloco contíguo de memória Os vetores são tipos de referência Derivados de System.Array Baseados em Zero Podem ser multidimensionais Os vetores sabem seu comprimento(s) n e grau Permite verificação de limites de dimensões Tipos de Objetos Arrays Declaração int[] primes; Alocação int[] primes = new int[9]; Inicialização int[] prime = new int[] {1,2,3,5,7,11,13,17,19}; int[] prime = {1,2,3,5,7,11,13,17,19}; Atribuição e acesso prime2[i] = prime[i]; Enumeração foreach (int i in prime) Console.WriteLine(i); Tipos de Objetos Arrays Arrays Multidimensionais Retangular int[,] matR = new int[2,3]; Pode ser inicializado declarativamente int[,] matR = new int[2,3] { {1,2,3}, {4,5,6} }; Dentado Um array de arrays int[][] matJ = new int[2][]; Deve ser inicializado proceduralmente Tipos de Objetos Interfaces Uma interface define um contrato Inclui métodos, propriedades, indexadores, eventos Qualquer classe ou estrutura implementando uma interface deve suportar todas as cláusulas do contrato Interfaces fornecem polimorfismo Muitas classes e estruturas podem implementar uma particular interface Não contém nenhuma implementação Devem ser implementadas por uma classe ou estrutura Tipos de Objetos Classes Um tipo de referência definida pelo usuário Similar às classes do C++ e Java Aceitam herança simples de uma única super classe Aceitam herança múltipla de várias interfaces Tipos de Objetos Classes Membros Constantes, dados, métodos, operadores, construtores e destrutores Propriedades, indexadores e eventos Membros estáticos e instanciados Acesso aos membros public, protected, private, internal, protected internal O padrão é private Instanciadas através do operador new Tipos de Objetos Estruturas (Structs) Similar às classes, mas: Tipo de valor definido pelo usuário Herança sempre a partir de um ValueType Ideal para objetos “leves” ou “primitivos” int, float, double, etc., são todos structs Tipos primitivos definidos pelo usuário Complex, point, rectangle, color, rational Herança múltipla de interfaces Possuem os mesmos membros de uma classe Acesso aos membros public, internal, private Instanciadas através do operador new Tipos de Objetos Classes e Structs struct SPoint { int x, y; ... } class CPoint { int x, y; ... } SPoint sp = new SPoint(10, 20); CPoint cp = new CPoint(10, 20); sp 10 20 cp CPoint 10 20 Tipos de Objetos Delegates Um delegate é um tipo de referência que define uma assinatura a um método Quando instanciada, uma delegate contém um ou mais métodos Essencialmente um apontador de funções orientado para objetos. Base fundamental para tratamento de eventos Estrutura de Programação Introdução Organizando Tipos Namespaces References O Método Main Sintaxe Estrutura de Programação Organizando Tipos Organização física: Os tipos de objetos (type) são definidos em arquivos (file). Os arquivos são compilados em módulos (module). Os módulos são agrupados em montagens (assembly). Assembly Module File Type Estrutura de Programação Organizando Tipos Os tipos são definidos em arquivos: Um arquivo pode conter múltiplos tipos Cada tipo é definido em um único arquivo Os arquivos são compilados em módulos: Um módulo é uma DLL ou um EXE Um módulo pode conter múltiplos arquivos Os módulos são agrupados em assemblys: Um assembly pode conter múltiplos módulos Os assemblys e os módulos são sempre 1:1 Estrutura de Programação Organizando Tipos Os tipos são definidos em UM lugar: “One-stop programming” Nenhum arquivo de cabeçalho (header) ou arquivo de código-fonte para sincronizar. O código é escrito “in-line” A declaração e a definição são uma mesma e única instrução. Um tipo deve estar completamente definido em um arquivo. Não se pode por métodos individuais em arquivos diferentes Nenhuma declaração exige dependência Nenhuma referência futura é exigida Estrutura de Programação Namespaces Namespaces fornecem um modo para identificar um tipo de forma exclusiva. Fornece organização lógica de tipos: Namespaces podem estar em vários assemblies Namespaces podem ser aninhados Não existe nenhuma relação entre namespaces e estruturas de arquivo (diferentemente do que ocorre em Java). Um nome de tipo completamente qualificado inclui todos os namespaces. Estrutura de Programação Namespaces namespace N1 { class C1 { class C2 { } } namespace N2 { class C2 { } } namespace N3.N4 { class C2 { } } } // N1 // N1.C1 // N1.C1.C2 // N1.N2 // N1.N2.C2 // N1.N3.N4 // N1.N3.N4.C2 Estrutura de Programação Namespaces A diretiva using permite que você utilize tipos de objetos diferentes sem precisar digitar toda a qualificação do nome de um objeto. Porém, sempre que quiser, você pode usar um nome completamente qualificado. using N1; C1 a; N1.C1 b; // O N1. está implícito // Nome qualificado C2 c; N1.N2.C2 d; C1.C2 e; // Erro! C2 está indefinido // Um objeto da classe C2 // Um outro Estrutura de Programação Namespaces A diretiva using também permite que você crie nomes alternativos (aliases). using MeuC1 = N1.N2.C1; using MeuN2 = N1.N2; MeuC1 a; MeuN2.C1 b; // Refere-se a N1.N2.C1 // Refere-se a N1.N2.C1 Estrutura de Programação Namespaces Melhor prática: ponha todos os seus tipos em um único namespace. Tenha um namespace específico para sua empresa, projeto, produto, etc. Estude como as classes do .NET Framework são organizadas e se inspire nelas para criar a organização de classes da sua empresa, projeto, produto, etc. Estrutura de Programação Referências No Visual Studio você especifica referências para um projeto. Cada referência identifica um específico assembly. Passada como referência (/r ou /reference) para o compilador do C#. csc HelloWorld.cs /reference:System.WinForms.dll Estrutura de Programação Namespaces vs. Referências Namespaces fornecem a capacidade de utilizar abreviações de nomenclaturas a nível de linguagem. Para que você não tenha que digitar um nome longo, completamente qualificado, repetidas vezes. As referências especificam que assembly deve ser utilizado. Estrutura de Programação O Método Main A execução começa com o método estático Main(). Normalmente, pode haver só um método com uma das seguintes assinaturas em um assembly: static static static static void Main() int Main() void Main(string[] args) int Main(string[] args) Porém, você pode ter múltiplas classes, cada com uma com um método Main, se você usar o comando /main para especificar a classe a usar. Estrutura de Programação Sintaxe Identificadores: Nomes para tipos, métodos, dados, etc. Deve ser uma palavra inteira – sem nenhum espaço em branco. Caracteres Unicode Começa com uma letra ou com o sublinhado (_Teste) Sensível a letras maiúsculas e minúsculas (case sensitive). Não devem ser utilizadas palavras-chave reservadas A menos que prefixadas com @ Comandos Introdução Alta fidelidade ao C++ if, while, do requerem uma condição bool goto não pode saltar para blocos Comando switch Não permite falha Comando foreach Comandos checked e unchecked Conjuntos de void Foo() i == 1; comandos devem } fazer o trabalho. { // erro Comandos Introdução Seqüências de comandos Blocos de comandos Comandos rotulados Declarações: Constantes Variáveis Expressões de comandos: checked, unchecked lock using Comandos para condições: if switch Comandos para repetições: while do for foreach Comandos para desvios: break continue goto return throw Tratamento de exceções: try throw Comandos Sintaxe Linhas de comandos são finalizadas com um ponto-e-vírgula (;) Da mesma forma que C, C++ e Java Blocos de comandos { ... } não precisam de um ponto-e-vírgula. Comandos Sintaxe Comentários: // Comenta uma só linha, estilo C++ /* Comenta múltiplas linhas, estilo C */ Comandos Seqüências & Blocos de Comandos Seqüência de comandos: um ou mais comandos em seqüência. Bloco de comandos: uma seqüência de comandos delimitados por chaves { ... } static void Main() { F(); G(); { // Início do bloco H(); ; // Comando vazio I(); } // Fim do bloco } Comandos Variáveis e Constantes static void Main() { const float pi = 3.14; const int r = 123; Console.WriteLine(pi * r * r); int a; int b = 2, c = 3; a = 1; Console.WriteLine(a + b + c); } Comandos Variáveis e Constantes O escopo de uma variável ou constante é válido do ponto da sua declaração até o fim do bloco onde foi declarada. Dentro deste escopo, será gerado um erro se for declarada outra variável ou constante com o mesmo nome. { int x; { int x; } } // Erro: não é possível // redefinir a variável x Comandos Variáveis Um valor deve ser atribuído às variáveis antes delas poderem ser usadas. Explicitamente ou automaticamente Camada definição de atribuição (definite assignment) Atribuição automática ocorre apenas para dados estáticos, classes, instâncias de classes e elementos de arrays. void Foo() { string s; Console.WriteLine(s); } // Erro Comandos Comandos Rotulados & goto O comando goto pode ser usado para transferir o controle para dentro ou para fora de um bloco, mas não em um bloco aninhado. static void Acha(int valor, int[,] valores, out int linha, out int coluna) { int i, j; for (i = 0; i < valores.GetLength(0); i++) for (j = 0; j < valores.GetLength(1); j++) if (valores[i, j] == valor) goto Achei; throw new InvalidOperationException(“Não achado"); Achei: linha = i; coluna = j; } Comandos Expressões em Comandos Comandos devem executar trabalhos Atribuição de valores, chamadas de métodos, ++, --, new etc. static void Main() { int a, b = 2, c = 3; a = b + c; a++; MinhaClass.Foo(a,b,c); Console.WriteLine(a + b + c); a == 2; // ERRO! } Comandos Comando if Exige uma expressão lógica (bool): int Teste(int a, int b) { if (a > b) return 1; else if (a < b) return -1; else return 0; } Comandos Comando switch Pode ramificar sobre qualquer tipo predefinido (inclusive string) ou enum Os tipos definidos pelo usuário podem fornecer conversão implícita para estes tipos. Deve definir explicitamente como finalizar um caso ou ramificação: Com break, goto case, goto label, return, throw ou continue Elimina falhas e bugs Não necessita if nenhum código é provido depois do rótulo. Comandos Comando switch int Teste(string rotulo) { int resultado; switch(rotulo) { case null: goto case “ausente”; case “mais rápido”: case “vencedor”: resultado = 1; break; case “ausente”: resultado = 2; break; default: resultado = 0; } return resultado; } Comandos Comando while Exige uma expressão lógica (boleana) int i = 0; while (i < 5) { ... i++; int i = 0; } do { ... i++; } while (i < 5); while (true) { ... } Comandos Comando for Exatamente como em C, C++ e Java for (int i=0; i < 5; i++) { ... } for (;;) { ... } Comandos Comando foreach Fornece simplicidade para manipulação de vetores e matrizes (arrays). public static void Main(string[] args) { foreach (string s in args) Console.WriteLine(s); } Comandos Comando foreach Manipulação de coleções definidas pelo usuário. Criadas através da implementação de IEnumerable foreach (Cliente c in Clientes.OrderBy("nome")) { if (c.Pedidos.Count != 0) { ... } } Comandos Comandos de Desvio break Saída da repetição (loop) mais interna continue Finaliza a repetição (loop) mais interna goto <label> Transfere a execução para o comando rotulado return [<expression>] Saída de um método throw Manipulação de exceção Comandos Tratamento de Exceções As exceções constituem o mecanismo do C# para o tratamento de condições de erro inesperadas. Mais aperfeiçoadas por retornar valores de estado: Não podem ser ignoradas Não precisam ser tratadas no ponto em que ocorrem Podem ser usadas até onde valores estado não são retornados (p.ex. atribuindo uma propriedade) Exceções padrão são fornecidas pelo C# Comandos Tratamento de Exceções Comando try...catch...finally O bloco try contém código que pode causar uma exceção. O bloco catch trata a exceção: Pode haver múltiplos blocos catch para tratar diferentes tipos de exceção. O bloco finally contém código que sempre será executado: Não é permitido usar comandos de desvio (p.ex. goto) para sair de um bloco finally. Comandos Tratamento de Exceções O comando throw gera uma exceção Uma exceção é representada como uma instância de System.Exception ou classe derivada: Contém informações sobre a exceção Propriedades: Message StackTrace InnerException Você pode gerar novamente (rethrow) uma exceção, ou tratar (catch) uma exceção e gerar (throw) uma outra. Comandos Tratamento de Exceções try { Console.WriteLine(“Tente executar"); throw new Exception(“Gere um erro!”); } catch (ArgumentNullException e) { Console.WriteLine(“Peguei um erro!"); } catch { Console.WriteLine(“Te peguei novamente!"); } finally { Console.WriteLine(“Finalmente saí, ufa!"); } Comandos Sincronização Aplicativos com múltiplas camadas precisam se proteger contra acesso simultâneo a dados: Devem prevenir corrupção de dados O comando lock (bloqueio) usa uma instância para fornecer exclusão mútua: Só um comando lock pode ter acesso à uma mesma instância Na verdade ele usa a classe System.Threading.Monitor do .NET Framework para fornecer exclusão mútua. Comandos Sincronização public class AtualizaConta { decimal saldo; public void Deposito(decimal valor) { lock (this) { saldo += valor; } } public void Saque(decimal valor) { lock (this) { saldo -= valor; } } } Comandos using Não se trata da diretiva using, mas sim do comando. O C# gerencia automaticamente o uso da memória implementando um “coletor de lixo” (garbage collection) Isso elimina a maioria de problemas de administração de memória. Porém, resulta em finalização não determinística: Não há garantia quando e se um “objeto destruidor ou coletor de lixo” é chamado. Comandos using Os objetos que precisam ser limpos depois de usados devem implementar a interface System.IDisposable Um método: Dispose() O comando using permite que você crie uma instância, use-a, e então se assegure que o método Dispose é chamado quando você não precisar mais dela. Dispose sempre é chamado, como se ele estivesse em um bloco finally. Não confunda com a diretiva using. Comandos using public class MeuRecurso : IDisposable { public void MeuRecurso() { // Aquisição do recurso } public void Dispose() { // Descarte do recurso } public void FaçaAlgo() { ... } using (MeuRecurso r = new MeuRecurso()) { } r.FaçaAlgo(); } // r.Dispose() é chamado Comandos checked e unchecked Os comandos checked e unchecked permitem que você controle a verificação de overflow em operações aritméticas e conversões. checked força a verificação de overflow unchecked força a não verificação de overflow Você pode usar ambos como bloco de instruções ou como uma expressão. O padrão é unchecked Use a opção /checked do compilador para fazer checked o padrão. Comandos Entrada e Saída Básicas Aplicativos de console (janela DOS): System.Console.WriteLine(); System.Console.ReadLine(); Aplicativos Windows: System.Windows.Forms.MessageBox.Show(); string v1 = “Algum dado”; MeuObjeto v2 = new AlgumObjeto(); Console.WriteLine(“O primeiro é {0}, o segundo é {1}”, v1, v2); Operadores Introdução O C# fornece um conjunto fixo de operadores, cujo significado é definido para os tipos predefinidos. Alguns operadores podem ser sobrecarregados (por exemplo +) A tabela a seguir resume os operadores do C# por categoria: As categorias estão em ordem de precedência decrescente Os operadores em cada categoria têm a mesma precedência Operadores Precedência Categoria Primário Operadores Agrupamento: (x) Acesso a membros: x.y Chamada de métodos: f(x) Indexação: a[x] Incremento posterior: x++ Decremento posterior: x— Chamada a construtor: new Recuperação de tipo: typeof Liga verificação aritmética: checked Desliga verificação aritmética: unchecked Operadores Precedência Categoria Unário Multiplicativo Operadores Valor positivo de: + Valor negativo de: Negação: ! Complemento Bitwise: ~ Pré-incremento: ++x Pré-decremento: --x Verifica tipo: (T)x Multiplicação: * Divisão: / Resto da divisão: % Operadores Precedência Categoria Aditivo Operadores Adição: + Subtração: - Shift Shift bits para esquerda: << Shift bits para a direita: >> Relacional Menor que: < Maior que: > Menor ou igual a: <= Maior ou igual a: >= Compatibilidade de tipo: is Conversão de tipo: as Operadores Precedência Categoria Igualdade Operadores Igual: == Diferente: != Bitwise AND & Bitwise XOR ^ Bitwise OR | Lógico AND && Lógico OR || Operadores Precedência Categoria Ternário condicional Atribuição Operadores ?: =, *=, /=, %=, +=, -=, <<=, >>=, &=, ^=, |= Operadores Associatividade Operadores de atribuição e ternários condicionais são associativos à direita: As operações são executadas da direita para a esquerda x = y = z é avaliada como x = (y = z) Todos outros operadores binários são associativos à esquerda: As operações são executadas da esquerda para a direita x + y + z é avaliada como (x + y) + z Use parênteses para controlar a ordem Usando o Visual Studio.NET Tipos de projetos: Aplicativo de Console (janela DOS) Aplicativo Windows Aplicativo Web Web Service Windows Service Biblioteca de Classes ... Usando o Visual Studio.NET Janelas de trabalho: Solution Explorer: componentes da solução Class View: classes em uso Properties: propriedades de objetos Output: saídas do compilador Task List: lista de tarefas a executar Object Browser: navegação por objetos Server Explorer: acesso a servidores conectados Toolbox: componentes e ferramentas Usando o Visual Studio.NET Construindo: compilando o aplicativo Depurando: debugando erros Pontos de parada (break points) Referências: referenciando componentes Salvando: gravando a aplicação Usando o Visual Studio.NET Demonstração: O Visual Studio.NET Referências http://msdn.microsoft.com http://windows.oreilly.com/news/hejlsberg_0800.html http://www.csharphelp.com/ http://www.csharp-station.com/ http://www.csharpindex.com/ http://msdn.microsoft.com/msdnmag/issues/0900/csharp/cs harp.asp http://www.hitmill.com/programming/dotNET/csharp.html http://www.c-sharpcorner.com/ http://msdn.microsoft.com/library/default.asp?URL=/libr ary/dotnet/csspec/vclrfcsharpspec_Start.htm Livro: Beginning C# Programado, Karli Watson et all, Makron Books – Pearson Education do Brasil, São Paulo - 2002