370 likes | 529 Views
A linguagem C#. Paulo Marques Departamento de Eng. Informática Universidade de Coimbra (pmarques@dei.uc.pt). Background. Investigador em Sistemas Distribuídos (Dep. Eng. Informática -- U. Coimbra) Experiência em Java e C++ Activamente a aprender C# e .NET
E N D
A linguagem C# Paulo Marques Departamento de Eng. Informática Universidade de Coimbra (pmarques@dei.uc.pt)
Background • Investigador em Sistemas Distribuídos (Dep. Eng. Informática -- U. Coimbra) • Experiência em Java e C++ • Activamente a aprender C# e .NET • Não sou um perito!!! (nem sequer trabalho para a Microsoft!) • Tenho vindo a “experimentar” com o ambiente de desenvolvimento • Ofereço a perspectiva de quem tem vindo a aprender e a utilizar a linguagem
Sobre o que iremos falar... • A linguagem C# • Apenas as características mais interessantes • Alguma comparação c/ Java e C++ • Reflexão crítica (aspectos positivos e negativos)
“Hello World” (ou... onde é que já vi isto antes?) using System; public class HelloWorld { public static void Main(string[] args) { Console.WriteLine(“Hello World!”); } }
Familiar • Eu já sei Java/C++... Pessoa Cliente = new Pessoa(“Carlos”, 25); Cliente.MostraInfo(); public class Pessoa { private string Nome; private int Idade; public Pessoa(string nome, int idade) { this.Nome = nome; this.Idade = idade; } public void MostraInfo() { Console.WriteLine(“{0}, tem {1} anos”, Nome, Idade); } }
C# - Características • Muito semelhante ao C++/Java • É fácil começar a programar em C# • Sistema unificado de tipos • Tudo pode ser visto como um objecto • Suporte directo à Programação Baseada em Componentes • Propriedades, Eventos e Atributos • Assemblies
10 val obj System.Int32 } 10 “Boxing” ? } k 10 “Unboxing” Tudo é um objecto! int val = 10; object obj = val; int k = (int) obj; // k fica c/ valor 10
Tudo é um objecto (2) C# Hashtable ht = new Hashtable(); ht.Add(1, “Xpto”); ht.Add(2, “Xpti”); JAVA Hashtable ht = new Hashtable(); ht.put(new Integer(1), “Xpto”); ht.put(new Integer(2), “Xpti”); • O fim das “wrapper classes”!
C# 101 • Controlo de execução • if, for, foreach, do, while, switch, ... • Tipos • Valor: elementares, struct, enum • Referência: class,interface, delegate, tabelas • Ponteiros int[] tabela = {1, 2, 3}; foreach (int i in tabela) Console.WriteLine(“{0}”, i);
string Nome; int[] tabela; class Pessoa { ... } enum Estado { Ligado, Desligado} struct Ponto { int x; int y; } sbyte decimal bool byte char ushort short decimal conta; uint float int ulong double long Sistema de Tipos String Array Class Object Enum Struct ValueType
public class Pessoa { private string Nome; private int Idade; public Pessoa(string nome, int idade) { this.Nome = nome; this.Idade = idade; } public virtual void MostraInfo() { Console.WriteLine(“{0}, tem {1} anos”, Nome, Idade); } } • Por omissão, os métodos não são virtuais! C# 101 – Herança public class Pessoa { private string Nome; private int Idade; public Pessoa(string nome, int idade) { this.Nome = nome; this.Idade = idade; } public void MostraInfo() { Console.WriteLine(“{0}, tem {1} anos”, Nome, Idade); } } public class Empregado : Pessoa { private string Empresa; public Empregado(string nome, int idade, int empresa) : base(nome, idade) { this.Empresa = empresa; } public override void MostraInfo() { base.MostraInfo(); Console.WriteLine(“Empresa: {0}”, Empresa); } }
C# 101 – Static vs. Dinamic binding public class Base { void Xpto() { Console.WriteLine(“Base.Xpto()”); } virtual void Xpti() { Console.WriteLine(“Base.Xpto()”); } } public class Derivada : Base { new void Xpto() { Console.WriteLine(“Deriv.Xpto()”); } override void Xpti() { Console.WriteLine(“Deriv.Xpto()”); } } Derivada d = new Derivada(); d.Xpto(); // Resulta em “Deriv.Xpto()” d.Xpti(); // Resulta em “Deriv.Xpti()” Base dref = d; dref.Xpto(); // Resulta em “Base.Xpto()” dref.Xpti(); // resulta em “Deriv.Xpti()”
public class A // Segunda versão { private int total; public void f() { ... limpa(); } public void limpa() { total = 0; } } • Deixa de funcionar!(recursos=0, em vez de total=0) Porquê é que isto é importante? public class A { public void f() { ... } } public class B extends A { private int recursos; public void limpa() { recursos = 0; } } B objB = new B(); objB.f();
C# 101 – Diferentes versões de classes • Em C#, existe suporte para introdução de novas versões de classes. • O programador tem sempre de indicar explicitamente a sua intenção (virtual, new, override)! • O compilador gera warnings quando são detectadas novas versões. O programador tem de dizer explicitamente o que quer fazer. • É uma boa ajuda, mas não resolve tudo...(mas... uma aplicação que continua a correr, sem o bug, é melhor do que uma aplicação a correr com o bug!)
C# 101 – Gestão de versões public class A { public void f() { ... } } public class A // Segunda versão { private int total; public void f() { ... limpa(); } public void limpa() { total = 0; } } public class B : A { private int recursos; public void limpa() { recursos = 0; } } public class B : A { private int recursos; public new void limpa() { recursos = 0; } } B objB = new B(); objB.f(); • Ao compilar é gerado um warning, mas funciona correctamente (linking estático) • O programador tem de dizer explicitamente o que quer fazer!
Demo • Suporte a diferentes versões de classes ...que é como quem diz... “estou farto dos slides, mostrem-me o IDE!”
C# 101 - Interfaces • Muito semelhante ao Java interface ILeitorCD { void TocaCD(CD cd); } Aparelhagem sony = new Aparelhagem(); Computador pc = new Computador(); ILeitorCD leitor; leitor = sony; leitor.tocaCD(GreatestHits); leitor = pc; pc.tocaCD(GreatestHits); public class Aparelhagem : ILeitorCD { void TocaCD(CD cd) { ... } } public class Computador : ILeitorCD { void TocaCD(CD cd) { ... } }
C# 101 - Componentes • O C# suporta directamente programação baseada em componentes • Conceito de assembly na platforma .NET • Propriedades • Permitem usar campos como se de variáveis se tratassem Cliente.Nome = “Joao”; • Eventos • Permitem notificar outros de acontecimentos num certo objecto ... OnMouseClick ... • Atributos • Permitem realizar programação declarativa [IsThreadSafe] void xpto() { ... }
C# 101 - Propriedades public class Pessoa { private int IdadePessoa; public string Idade { get { return IdadePessoa; } set{ if (value > 0) IdadePessoa = value; else error(); } } ... } Pessoa p = new Pessoa(); p.Idade = 25; Console.WriteLine(“{0}”, p.Idade); p.Idade = -10; // error() chamado
C# 101 - Eventos • Os eventos são baseados no conceito de “delegate”. • Os “delegate” funcionam como ponteiros para funções, que são type safe. Funcao f; f = new Funcao(Xpto.Mostra); f(10); delegate void Funcao(int x); equivalente aproximado em C++ ... void (Funcao*)(int x); class Xpto { public static void Mostra(int val) { Console.WriteLine(“{0}”, val); } }
C# 101 – Eventos (2) • Funcionam usando multicast delegates Event Handler EventSubscriber Evento Event Handler EventSubscriber Event Delegate EventPublisher Evento Evento Event Handler EventSubscriber
delegate void Funcao(int x); class A { public static void Quadrado(int val) { Console.WriteLine(“{0}”, val*val); } } class B { public static void Raiz(int valor) { Console.WriteLine(“{0}”, Math.Sqrt(val)); } } C# 101 – Multicast Delegates Funcao f; f = new Funcao(Xpto.Quadrado); f+= new Funcao(Xpto.Raiz) f(10); // Chama ambos os métodos!
Demo • Multicast delegates • Window and event handling
C# 101 - Atributos • Os atributos marcam o código com informação útil para o compilador (e não só!) • Muito úteis quando associados ao mecanismo de introspecção • Programação declarativa vs. imperativa class DataBase { [Conditional(“DEBUG”)] public void dumpDatabaseDisk() { ... } }
C# 101 – Atributos (2) class Cracker { [DllImport(“crack_lib.dll”] public static extern solver(); [WebMethod] public byte[] CrackPassword(byte[] passFile) { ... } } • Posso indicar as características do código, sendo essa informação usada pelo compilador ou outras rotinas • Posso criar novos atributos para descrever declarativamente o código.
Pessoa p = new Pessoa(); try { p.Idade = -10; // Irá lançar uma excepção! ... // Este código não é executado } catch (IdadeInvalidaException e) { Console.WriteLine(“Nao pode introduzir essa idade!”); } Gestão de Erros • O C# suporta o conceito de excepções public class Pessoa { ... public string Idade { ... set { if (novaIdade > 0) IdadePessoa = value; else throw new IdadeInvalidaException(value); } } }
Gestão de Erros (2) • try/catch/finally: permitem apanhar e tratar as excepções no código • throw: permite lançar uma excepção • Infelizmente... • Em C# não é possível declarar as excepções que uma rotina pode lançar • Não é necessário apanhar as excepções que são lançadas pelas rotinas!
Problema c/ Excepções public class Logger { public static void log(string msg) { // Escreve em disco “msg” // Na documentação não consta nenhuma excepção } } public class BaseDados { public void AbreLigacao() { try { bd.EstablishConnection(); // Funciona bem! Logger.log(“Ok”); // Gera excepção } catch (Exception e) { Logger.log(“Não foi possível abrir a ligação”); // !!! } }
Redefinição de Operadores • Em C# é possível redefinir os operadores existentes. Lista A = new Lista(); Lista B = new Lista(); A.Add(1); A.Add(2); B.Add(3); B.Add(4); Lista C = A + B; // Junta ambas as listas
Redefinição de Operadores (2) Lista A = new Lista(); Lista B = new Lista(); ... Lista C = A + B; public class Lista { private object[] Elementos; ... public static Lista operator+(Lista a, Lista b) { Lista resultado = new Lista(); // Copia os elementos de <a> e <b> para // a lista <resultado> return resultado; } }
Redefinição de Operadores (3) • A redefinição de operadores deve de ser feita com cuidado • Sem problemas em casos simples • Complicada quando se utilizam features avançadas (ex: user-defined casts, implicit/explicit)
Unsafe Code • O C# suporta elementos avançados, como a utilização de ponteiros • Sempre que são utilizados estes elementos, o código tem de ser colocado dentro de um contexto “unsafe” int total = 0; unsafe { int* ptr = &total; *total = 10; } public unsafe void FastCopy(byte* dst, byte* src, int count) { for (int i=0; i<count; i++) *dst++ = *src++; }
C# 101 – Documentação em XML /// <summary> /// Este método calcula o ordenado de uma pessoa, /// baseado nos seus dias de trabalho. /// </summary> /// /// <param name=“diasTrabalho"> /// O número de dias que trabalhou. /// </param> /// /// <returns> O salário da pessoa. </returns> public int CalculaOrdenado(int diasTrabalho) { ... }
Conclusão (1) • C# -- Pontos Positivos • Orientada aos Componentes • Familiar aos programadores de Java/C++ • Resolve algumas das fraquezas do Java (e do C++) em termos de desenvolvimento de software (não resolve tudo)
Conclusão (2) • C# -- Pontos negativos • Gestão de Excepções • Herda uma certa idiomática do Pascal • Algumas features algo obscuras, outras perigosas