Ambientes Virtuais de Execução
Estrutura de Tipos
1
Cátia Vaz 2012
Instâncias de Tipos
Uma instância de um tipo é um objecto ou um valor.
}  Um objecto é uma instância de um tipo num garbage
collected heap.
}  As instâncias de um tipo valor não são objectos:
} 
} 
} 
2
Não têm cabeçalho do objecto.
Não estão alocados como entidades distintas no garbage
collected heap.
Cátia Vaz 2012
Membros dos Tipos
} 
Os tipos podem conter membros:
} 
} 
} 
De instância
De tipo (static)
Os membros de um tipo podem ser:
} 
} 
} 
} 
Constantes (membros estáticos)
Campos (Fields)
Métodos
Construtores
} 
} 
} 
} 
} 
3
de instância
de tipo
Propriedades
Nested Types (são sempre membros static)
Eventos
Cátia Vaz 2012
Diferentes tipos de membros - Exemplo
public sealed class SomeType { // Nested class
private class SomeNestedType { } // Constant, read-only, and static read/write field
private const Int32 c_SomeConstant = 1; private readonly String m_SomeReadOnlyField = "2"; private static Int32 s_SomeReadWriteField = 3; // Type constructor
static SomeType() { } // Instance constructors
public SomeType() { } public SomeType(Int32 x) { } //....
4
Cátia Vaz 2012
Diferentes tipos de membros - Continuação
// Static and instance methods
public static void Main() { } public String InstanceMethod() { return null; } // Instance property
public Int32 SomeProp { get { return 0; } set { } } // Instance parameterful property (indexer)
public Int32 this[String s] { get { return 0; } set { } } //
Instance event
public event EventHandler SomeEvent; } 5
Cátia Vaz 2012
Outros Membros dos Tipos
} 
Existem outros membros que não fazem parte do CLS
} 
} 
6
Sobrecarga de operadores
Operadores de conversão
Cátia Vaz 2012
Visibilidade de um tipo
IL Term
C# Term
private
internal
(por omissão)
public
7
public
Visual Basic Term
Descrição
Friend
Visível apenas dentro do
assembly
Public
Visível dentro e fora do
assembly
Cátia Vaz 2012
Acessibilidade dos membros de um tipo
IL Term
Private
C# Term
private
(default)
Visual Basic Term
Descrição
Private
Acessível apenas pelos métodos do tipo
Protected
Acessível apenas pelos métodos do tipo
e dele derivados, dentro ou fora do
assembly
Family and (não
Assembly suportada)
(não suportada)
Acessível apenas pelos métodos do tipo
e dele derivados dentro do assembly
assembly
Friend
Acessível apenas pelos métodos de tipos
definidos no assembly
Family
protected
internal
Family or
Assembly
protected
internal
Protected Friend
Acessível apenas pelos métodos do tipo
e dele derivados dentro ou fora do
assembly e pelos métodos de outros
tipos do assembly
public
public
Public
Acessível por métodos de qualquer tipo
8
Cátia Vaz 2012
Acessibilidade de um membro
Para qualquer membro ser acessível, tem de estar
definido num tipo que seja visível.
}  Ao derivar de uma classe base:
} 
} 
} 
9
CLR permite que a acessibilidade de um membro redefinido
(overriden) fique menos restritiva.
Em C# é necessário que a acessibilidade seja a mesma.
Cátia Vaz 2012
Herança
} 
} 
Um tipo não pode ter mais que uma classe base.
Um tipo pode implementar qualquer número de interfaces.
IL Term
abstract
final
} 
C# Term
Visual Basic Term
Description
abstract
MustInherit
Tipo abstracto
sealed
NotInheritable
Não pode ser
estendido.
Apenas um dos modificadores pode ser aplicado a um tipo.
10
Cátia Vaz 2012
Classes estáticas (C#)
} 
Não podem ser instanciadas;
} 
O compilador não produz nenhum construtor de instância.
Não podem implementar interfaces.
}  Só podem definir membros estáticos.
}  O compilador de C# torna este tipo de classes abstract e
sealed.
} 
11
Cátia Vaz 2012
Atributos pré definidos aplicáveis a métodos (1)
CLR Term
Static
Instance
Virtual
12
C# Term
static
(default)
virtual
Visual Basic
Term
Descrição
Shared
Método associado ao próprio tipo, não a
uma instância do tipo. Os membros
estáticos não podem aceder a campos
de instância ou métodos de instância.
(default)
Método associado a uma instância do
tipo. Pode aceder aos campos e métodos
de instância, assim como aos campos e
métodos estáticos.
Overridable
O método mais derivado é invocado
mesmo que o objecto seja convertido
para um tipo base. Aplica-se apenas a
métodos de instância.
Cátia Vaz 2012
Atributos pré-definidos aplicáveis a métodos (2)
CLR Term
NewSlot
Override
C# Term
new
(default)
override
Visual Basic
Term
Descrição
Shadows
O método não deve redefinir um método virtual
definido pelo seu tipo base; o método esconde o
método herdado. NewSlot aplica-se apenas a
métodos virtuais.
Overrides
Indica que o método está a redefinir um método
virtual definido pelo seu tipo base. Aplica-se
apenas a métodos virtuais.
Abstract
abstract
MustOverride
Indica que um tipo derivado tem de implementar
um método com uma assinatura que
corresponda a este método abstracto. Um tipo
com um método abstracto é um tipo abstracto.
Aplica-se apenas a métodos virtuais.
Final
sealed
NotOverridable
Um tipo derivado não pode redefinir este
método. Aplica-se apenas ao métodos virtuais.
13
Cátia Vaz 2012
Invocação de métodos em IL - call
} 
A instrução call é utilizada para invocar métodos
estáticos, de instância e virtuais
} 
} 
Quando é usado para invocar um método estático, tem que se
especificar o tipo que define o método que o CLR vai invocar.
Quando é usado para invocar um método de instância ou
virtual, é necessário especificar uma variável que se refere ao
objecto.
} 
} 
14
o tipo da variável indica que tipo define o método que o CLR deve
invocar
se o tipo da variável não define o método, os tipos base são
verificados para um método correspondente.
Cátia Vaz 2012
Invocação de métodos em IL - callvirt
} 
A instrução callvirt pode ser utilizada para invocar
métodos de instância ou virtuais.
} 
Quando é usado para invocar um método de instância virtual,
o CLR descobre o tipo ctual do objecto que está a invocar o
método.
} 
} 
} 
15
Invoca o método polimorficamente.
Quando é usado para invocar um método de instância não
virtual, o tipo da variável indica o tipo que define o método
que o CLR vai invocar.
Se a variável que referencia o objecto for null, lança excepção
do tipo NullReferenceException. Cátia Vaz 2012
Exemplo 1
using System;
public class TesteA{
public static void Main(){
Console.WriteLine( );
Object o = new Object();
o.GetHasCode();
}
}
.method public hidebysig static void Main() cil managed { .entrypoint // Code size 15 (0xf) .maxstack 1 .locals init (object V_0) IL_0000: nop IL_0001: call void [mscorlib]System.Console::WriteLine() IL_0006: nop IL_0007: newobj instance void [mscorlib]System.Object::.ctor() IL_000c: stloc.0 IL_000d: ldloc.0 IL_000e: callvirt instance int32 [mscorlib]System.Object::GetHashCode() IL_0013: pop IL_0014: ret } // end of method TesteA::Main 16
Cátia Vaz 2012
Exemplo 1
using System;
public class TesteA{
public static void Main(){
Object o = new Object();
o.GetType();
}
.method public hidebysig static void Main() cil managed { .entrypoint // Code size 15 (0xf) .maxstack 1 .locals init (object V_0) IL_0000: nop }
IL_0001: newobj instance void [mscorlib]System.Object::.ctor() IL_0006: stloc.0 IL_0007: ldloc.0 IL_0008: callvirt instance class [mscorlib]System.Type [mscorlib]System.Object::GetType() IL_000d: pop IL_000e: ret } // end of method TesteA::Main 17
Cátia Vaz 2012
Métodos de instância não virtuais em C#
} 
Em C#, nas chamadas aos métodos de instância não virtuais
para tipos referência é utilizada a instrução callvirt } 
verfica que o objecto que está a fazer esta invocação não é null. Se
for lança excepção do tipo NullReferenceException Ex: using System; } 
public sealed class Program{ public Int32 GetFive() { return 5;} public static void Main( ){ Program p = null; Int32 x = p.GetFive(); } 18
Cátia Vaz 2012
Métodos virtuais – instrução call
Por vezes o compilador usa a instrução call para
invocar métodos virtuais
}  Ex:
} 
internal class SomeClass{ public override String toString(){ return base.toString() } } 19
Cátia Vaz 2012
Exemplos
using System; class A{ public void F(){ Console.WriteLine("A.F"); } public virtual void G(){ Console.WriteLine( " A.G");} } class B: A{ public void F(){ Console.WriteLine("B.F");} public override void G() { Console.WriteLine("B.G");} } class Test{ static void Main(){ B b = new B(); A a = new B(); a.F(); b.F(); a.G(); b.G(); } } 20
Cátia Vaz 2012
Exemplos
using System; class A{ public void F(){ Console.WriteLine("A.F"); } public virtual void G(){ Console.WriteLine( " A.G");} } class B: A{ public void F(){ Console.WriteLine("B.F");} public override void G() { Console.WriteLine("B.G");} } class Test{ A.F
B.F
B.G
B.G
static void Main(){ B b = new B(); A a = new B(); a.F(); b.F(); a.G(); b.G(); } } 21
Cátia Vaz 2012
Métodos com número variável de argumentos
class TParams { static void showArgs(params object[] args) { foreach(object arg in args) Console.WriteLine(arg.ToString()); } static void Main() { showArgs("olá", "admirável", "mundo", "novo!"); } } Apenas o último parâmetro do método pode ser um parameter array.
22
Cátia Vaz 2012
Passagem de parâmetros: por valor
} 
Passagem por valor:
n  Através da cópia do conteúdo da variável;
n 
Comportamento por omissão.
x = 83
y = addr
Caller
f(int a, Patient b) “Don”
38
f(x,y) a = 83
b = addr
Callee
23
Cátia Vaz 2012
Passagem de parâmetros: por referência
} 
Passagem por referência:
n 
n 
Através de ponteiro managed para a variável;
Em IL indicado por & e em C# por ref.
x = 83
y = addr
Caller
f(ref int a, ref Patient b)
“Don”
f(ref x, ref y)
38
a = addr
b = addr
Callee
24
Cátia Vaz 2012
ref versus out using System; using System; public sealed class Program{ public sealed class Program{ public static void Main(){ public static void Main(){ Int32 x; Int32 x = 5; GetVal( out x ); GetVal( ref x ); Console.WriteLine(x); Console.WriteLine(x); } } private static private static void GetVal(out Int32 v){ void GetVal(ref Int32 v){ v = 10; v = 10; } } } } GetVal tem de inicializar v 25
x tem de ser inicializada. Cátia Vaz 2012
Parâmetros ref e a compatibilidade de tipos
class Utils { public static void swap(ref object a, ref object b) { object aux=a; a=b; b=aux; } } Sejam duas referências para string:
Qual o problema do seguinte código?
string s1,s2; Utils.swap(ref s1, ref s2)
26
Cátia Vaz 2012
Construtores
} 
CLR suporta:
} 
Construtores de tipo
} 
} 
} 
} 
Construtores de instância
} 
} 
27
Utilizados para estabelecer o estado inicial de um tipo.
É um método estático com um nome especial → .cctor.
O CLR garante a chamada ao construtor de tipo antes de qualquer
acesso a um campo de tipo.
Utilizados para estabelecer o estado inicial de uma instância de um
tipo.
É um método estático com um nome especial → .ctor.
Cátia Vaz 2012
Iniciação de tipos
} 
Em CLR, um construtor de tipo pode ser aplicado a
interfaces, tipos referência e tipos valor
} 
} 
} 
} 
Não é permitido em C# aplicar construtores de tipos a
interfaces.
Por omissão os tipos não têm um construtor de tipos definido.
Só pode ser definido, no máximo um construtor de tipo por
cada tipo.
Têm de ser privados
} 
} 
28
Em C# a acessibilidade private é colocada automaticamente
O método não recebe parâmetros;
Cátia Vaz 2012
Iniciação de tipos - Exemplos
internal sealed class SomeRefType{ static SomeRefType(){ //. . . } } } 
internal struct SomeValType{ static SomeValType(){ //. . . } } Os campos com expressões de iniciação na sua definição, são os
primeiros a ser iniciados pelo construtor
internal sealed class SomeType{ private static Int32 s = 5; static SomeType(){ s = 10; } } .
29
Cátia Vaz 2012
Políticas de iniciação de tipo
O CLR garante a chamada ao construtor de tipo antes de
qualquer acesso a um campo de tipo;
}  Políticas de iniciação de tipos:
} 
} 
} 
30
Imediatamente antes do primeiro acesso a qualquer
membro – usada em C# quando há construtores de tipo;
Em qualquer altura desde que antes do primeiro acesso a um
campo de tipo (atributo de Metadata beforefieldinit
- política em C# quando não for definido explicitamente
um constructor de tipo).
Cátia Vaz 2012
Construção de objectos
} 
Quando se cria uma instância de um reference type:
} 
} 
É reservado, no managed heap, um bloco de memória com o
número de bytes necessários para armazenar o objecto do
tipo especificado.
Inicia os membros overhead do objecto. Cada instância tem
associados dois membros adicionais usados pelo CLR na
gestão do objecto.
} 
} 
} 
} 
O primeiro membro é um apontador para a tabela de métodos do
tipo;
O segundo é o SyncBlockIndex (usado na sincronização).
É chamado o construtor de instância do tipo.
Por fim, devolve uma referência para o objecto criado.
Construção de objectos
} 
} 
O CLR requer que todos os objectos sejam criados usando o
operador new
} 
emite a instrução IL newobj.
} 
EX: Employee e = new Employee("ConstructorParam1");
Os construtores de instância nunca são herdados
} 
} 
Não lhes pode ser aplicado os modificadores virtual, new,
override, sealed e abstract Em C#, se uma classe não definir explicitamente um construtor, o
compilador gera um por omissão.
public class SomeType{ // ... Sem construtor de instâncias
} public class SomeType{ public SomeType() : base () { } // ... } Construção de objectos – keyword this
private sealed class SomeType{
private Int32 m_x;
private String m_s;
public SomeType( ){
m_x = 5;
m_s= “Ola”;
}
public SomeType( Int32 x) : this ( ){
m_x = 10;
}
}
} 
Nota: Embora a maioria das linguagens compilem os construtores de forma
a que seja chamado o construtor do tipo base, o CLR não obriga à
existência desta chamada.
Iniciação de instâncias
Construtor de instância:
} 
} 
} 
Tem nome especial → .ctor
Podem existir várias sobrecargas.
Comportamento do construtor:
} 
1. 
2. 
3. 
34
Inicia os campos que têm expressões de iniciação na sua definição;
Chama o construtor da classe base;
Executa o seu código.
Cátia Vaz 2012
Sobrecarga de métodos
} 
Podem ser sobrecarregados se diferirem em:
} 
} 
} 
} 
} 
Número de parâmetros;
Tipo dos parâmetros;
Tipo de retorno; (não em C#)
Passagem de parâmetro por valor ou referência.
As regras CLS permitem sobrecarga se os métodos
diferirem apenas em número ou tipo dos parâmetros.
35
Cátia Vaz 2012
O tipo valor Ponto em C#
(com redefinição de
Equals)
public struct Ponto { public int x, y;
public Ponto(int x, int y) { this.x=x; this.y=y; } public override bool Equals(object obj) { if (obj == null) return false; if (!(obj is Ponto)) return false; return Equals( (Ponto) obj); } public bool Equals(Ponto p) { return x== p.x && y == p.y; } public override int GetHashCode() { return x^y; }
public override string ToString() { return String.Format("({0},{1})", x, y); } } 36
Cátia Vaz 2012
Desambiguar colisões de nomes
} 
Campos de tipo:
} 
} 
Campos de instância:
} 
} 
Através do nome do tipo pretendido.
Através do uso das palavras this e base;
Métodos:
} 
2 políticas:
} 
} 
} 
37
Hide-by-name – esconde todos as sobrecargas de métodos com o mesmo
nome; (C++)
Hide-by-signature – esconde o método com igual assinatura. (C#)
Na CLS não existe colisão em nomes que variam apenas na capitalização
dos caracteres.
Cátia Vaz 2012
Operador new - Exemplo
using System;
class A {
public virtual void F() { Console.WriteLine("A.F"); } }
class B: A {
public override void F() { Console.WriteLine("B.F"); } }
class C: B {
new public virtual void F() { Console.WriteLine("C.F"); } }
class D: C {
public override void F() { Console.WriteLine("D.F"); } }
As classes C e D
contêm dois
métodos com a
mesma assinatura!
D redefine o
método
introduzido em C
class Test {
static void Main() {
D d = new D();
B.F
B.F
D.F
D.F
A a = d; B b = d; C c = d;
a.F(); b.F(); c.F(); d.F();
}}
38
Cátia Vaz 2012
Operador new - Exemplo
using System;
class A {
public virtual void F() {} }
class B: A {
new private void F() {} // Esconde A.F em B
}
class C: B {
public override void F() {} // Ok, redefine A.F
}
39
Cátia Vaz 2012
Atributos aplicáveis a campos
IL Term
C# Term
Visual Basic Term
static
static
Shared
initonly
readonly
ReadOnly
Description
Campo de tipo
Só pode ser iniciado num construtor
w  O CLR permite que um campo seja marcado como static,
initonly ou static e initonly.
w  O C# suporta a combinação dos dois.
40
Cátia Vaz 2012
Constantes – C#
• 
• 
• 
É um símbolo ao qual é atribuído a um valor que nunca se altera.
O valor a atribuir tem que ser determinado em tempo de
compilação, logo, apenas podem ser definidas constantes de
tipos primitivos da linguagem.
O compilador guarda o valor da constante na Metadata do
módulo (como um campo estático literal)
• 
não é alocada memória em tempo de execução
•  Não é possível obter o endereço duma constante nem passá-la por
referência.
•  Por levantar problemas de versões, só devem ser usadas quando
existe certeza que o seu valor é imutável (p.ex. Pi, MaxInt16,
MaxInt32, etc.).
•  Exemplo em C#
•  const Int32 SomeConstant
41
= 1;
Cátia Vaz 2012
Campos readonly – C#
• 
Campos readonly
•  Só podem ser afectados durante a construção da instância do tipo onde
estão definidos
•  Um campo static readonly é definido em run time.
•  Uma constante é definida em compile time.
•  Em C#: readonly Int32 SomeReadOnlyField = 2;
•  O campo é marcado com o atributo InitOnly
42
Cátia Vaz 2012
Propriedades
As propriedades permitem ao código fonte invocar um
método utilizando uma sintaxe simplificada.
}  Existem dois tipos de propriedades:
} 
} 
} 
Propriedades sem parâmetros
Propriedades com parâmetros
} 
43
C# designa as propriedades com parâmetros por indexers.
Cátia Vaz 2012
Propriedades sem parâmetros
public sealed class Employee{ Employee e = new Employee(); private String m_Name; String empName = e.Name; private Int32 m_Age; e.Age = 41; public String Name { Int32 i = e. Age; get { return( m_Name); } e.Age = -­‐5; set { m_Name = value; } } public Int32 Age { get { return( m_Age); } set { if ( value < 0 ) throw new ArgumentOutOfRangeException(“value”, value.ToString(), “O valor tem de ser maior ou igual a 0”); m_Age = value;} } } 44
Cátia Vaz 2012
Propriedades sem parâmetros
Cada propriedade tem um nome e um tipo;
}  Não pode existir sobrecarga de propriedades;
}  Acedidas através de um nome ou um acesso de membro
}  Pode ser um membro estático ou de instância
}  O get accessor de uma propriedade não tem parâmetros
}  O set accessor de uma propriedade contêm
implicitamente o parâmetro value.
} 
45
Cátia Vaz 2012
Propriedades sem parâmetros - Exemplo 2
public sealed class Employee{ private String m_Name; private Int32 m_Age; private static Int32 nR_Employees; public String Name { get { return(m_Name); } set { m_Name = value; } } public Int32 Age { get { return( m_Age); } set { if ( value < 0 ) throw new ArgumentOutOfRangeException(“value”, value.ToString(), “O valor tem de ser maior ou igual a 0”); m_Age = value;} } public static Int32 NrEmployees{ get { return(nR_Employees); } } 46
Cátia Vaz 2012
Propriedades estáticas e de instância
using System;
using CTSTester.Properties;
namespace CTSTester {
namespace Properties {
public class TypeWithProps {
private static int aTypeField;
public string AnInstanceProperty {
get { return "instance property"; }
}
public static int ATypeProperty {
get { return aTypeField; }
set { aTypeField = value; }
}
}
}
class TestProperties {
public static void Main() {
TypeWithProps mt = new TypeWithProps();
System.Console.WriteLine(mt.AnInstanceProperty);
System.Console.WriteLine(TypeWithProps.ATypeProperty);
TypeWithProps.ATypeProperty = 30;
System.Console.WriteLine(TypeWithProps.ATypeProperty);
}
}
}
47
Cátia Vaz 2012
Propriedades estáticas e de instância (IL de Main)
.method public hidebysig static void Main() cil managed {
.entrypoint
// Code size
45 (0x2d)
.maxstack 2
.locals init ([0] class CTSTester.Properties.TypeWithProps mt)
newobj
instance void CTSTester.Properties.TypeWithProps::.ctor()
stloc.0
ldloc.0
callvirt
instance string
CTSTester.Properties.TypeWithProps::get_AnInstanceProperty()
call
void [mscorlib]System.Console::WriteLine(string)
call
int32 CTSTester.Properties.TypeWithProps::get_ATypeProperty()
call
void [mscorlib]System.Console::WriteLine(int32)
ldc.i4.s
30
call
void CTSTester.Properties.TypeWithProps::set_ATypeProperty(int32)
call
int32 CTSTester.Properties.TypeWithProps::get_ATypeProperty()
call
void [mscorlib]System.Console::WriteLine(int32)
ret
} // end of method TestProperties::Main
48
Cátia Vaz 2012
Propriedades com parâmetros
Identificado pela sua assinatura.
}  Acedido através de um acesso de um elemento.
}  Tem de ser um membro de instância.
}  O get accessor de um indexer tem o mesma lista
de parâmetros formais que um indexer.
}  O set accessor de um indexer tem a mesma lista
de parâmetros formais de um indexer, assim
como o parâmetro value.
} 
49
Cátia Vaz 2012
Indexers (criação)
class IndexerClass { private int [] myArray = new int[100]; public int this [int index] { get { if (index < 0 || index >= 100) return 0; else return myArray[index]; } set { if (!(index < 0 || index >= 100)) myArray[index] = value; } } } 50
Cátia Vaz 2012
Indexers (Utilização)
public class MainClass { public static void Main() { IndexerClass b = new IndexerClass(); b[3] = 256; b[5] = 1024; for (int i=0; i<=10; i++) { Console.WriteLine("Element #{0} = {1}", i, b[i]); } } } 51
Cátia Vaz 2012
Classes parciais – C#
} 
Objectivo:
} 
} 
} 
Separar o código gerado automaticamente do código escrito pelo
programador
Uma classe pode ser dividida em partes, em que cada parte
corresponde a uma implementação parcial da classe.
Todas as partes da classe devem estar disponíveis no momento
da compilação
} 
} 
52
gera uma única classe em representação intermédia
classe reside num único assembly
Cátia Vaz 2012
Classes parciais – C#
} 
Aspectos acumulativos de uma classe:
} 
} 
} 
} 
} 
} 
Aspectos não acumulativos:
} 
} 
} 
} 
Campos
Métodos
Propriedades
Indexadores
Interfaces implementadas
Classe base
Tipo-valor ou tipo-referência
Visibilidade
As diversas partes de uma mesma classe devem concordar nos
aspectos não acumulativos.
53
Cátia Vaz 2012
Enumerados
} 
} 
} 
Os enumerados permitem definir especializações de tipos
integrais que não adicionam campos, mas simplesmente
restrigem o espaço de valores de um tipo integral específico.
O tipo enumerado é um tipo valor em que o tipo base é
System.Enum.
Os enumerados têm um segundo tipo subjacente que irá ser
usado para a representação dos dados da enumeração
} 
} 
} 
} 
Se não for especificado nenhum, é assumido pelo compilador C# o
tipo System.Int32.
O Tipo System.Char não pode ser utilizado.
Os enumerados pode ser representados em formas boxed e
unboxed.
Não podem definir métodos, propriedades ou eventos.
54
Cátia Vaz 2012
Enumerados
enum EstacoesDoAno {
Primavera, Verao, Outono, Inverno
};
.class private auto ansi sealed Geometry.EstacoesDoAno
extends [mscorlib]System.Enum {
.field public specialname rtspecialname int32 value__
.field public static literal valuetype
EstacoesDoAno Primavera = int32(0x00000000)
.field public static literal valuetype
EstacoesDoAno Verao = int32(0x00000001)
.field public static literal valuetype
EstacoesDoAno Outono = int32(0x00000002)
.field public static literal valuetype
EstacoesDoAno Inverno = int32(0x00000003)
} // end of class Geometry.EstacoesDoAno
55
Cátia Vaz 2012
Exemplo - Continuação
using System; internal enum Color{ White, Red, Green, Blue, Orange } public class Program{ public static void Main(){ Console.WriteLine(Color.Format(typeof(Color),3,"G")); Color c = (Color) Enum.Parse(typeof(Color), "White"); Console.WriteLine(c); Console.WriteLine("{0:D} \t {0:G}",c); c = (Color) Enum.Parse(typeof(Color), "white",true); Console.WriteLine(c.ToString("G")); Console.WriteLine(Enum.IsDefined(typeof(Color),"red")); } } 56
Cátia Vaz 2012
Blue White 0 White White False O tipo Enum (excerto)
int CompareTo(object target) Compara esta instância com o objecto especificado e retorna
uma indicação dos seus valores relativos.
static string Format(Type enumType, object value, string format) Converte o valor especificado de um tipo enumerado
especificado para a sua representação equivalente sob a
forma de string, de acordo com o formato especificado.
static string GetName(Type enumType, object value) Retorna o nome da constante na enumeração especificada
que tem aquele valor especificado.
static string[] GetNames(Type enumType) Retorna um array com os nomes das constantes na
enumeração especificada.
static Type GetUnderlyingType(Type enumType) Retorna o tipo subjacente da enumeração especificada.
static Array GetValues(Type enumType) Retorna um array com os valores das constantes numa
enumeração especificada.
static bool IsDefined(Type enumType,object value) Retorna true se e só se uma constante com um valor
especificado existe numa enumeração especificada.
static object Parse(Type enumType,string value) Converte a representação sob a forma de string do nome ou
valor numérico de uma ou mais constantes enumeradas para
um objecto enumerado equivalente.
57
Cátia Vaz 2012
Interfaces
} 
Keyword interface (para definição de “Interface Types”)
} 
Para especificação de contratos, isto é, conjunto de operações suportadas
} 
As interfaces suportam herança múltipla de outras interfaces.
} 
Não podem conter campos de instância nem métodos de
instância com implementação.
} 
Todos os métodos de instância têm, implicitamente, os
atributos public e virtual.
} 
Por convenção, o nome das interfaces começa pelo carácter ‘I’
} 
58
Exemplos: ICloneable, IEnumerable
Cátia Vaz 2012
Exemplo – interface A
public interface A{ void GetA(); } .class interface public abstract auto ansi A { .method public hidebysig newslot abstract virtual instance void GetA() cil managed { } // end of method A::GetA } // end of class A 59
Cátia Vaz 2012
Interface IComparable
public interface IComparable<T>{ Int32 CompareTo(T other); } public class Point : IComparable<Point>{ private Int32 x,y; public Point( Int32 x, Int32 y){ this.x=x; this.y=y; } public Int32 CompareTo(Point other){ return Math.Sign(Math.Sqrt(x*x+y*y) -­‐ Math.Sqrt(other.x*other.x + other.y*other.y) );} } 60
Cátia Vaz 2012
Interfaces
} 
Em C# a implementação de uma interface resulta, por
omissão, em métodos sealed.
} 
} 
O que não acontece se o método na classe for declarado
como virtual.
Exemplo: } 
Em C# ¨ 
} 
public Int32 CompareTo(Point other){...}
Em IL: ¨ 
.method public hidebysig newslot virtual final instance int32 CompareTo(class Point other) cil managed { 61
Cátia Vaz 2012
Linguagem C# - Excerto do modelo de tipos
(interfaces)
Legenda
Types
BCL
Namespace System
Reference Types
User defined
Interfaces
Object
Interface Type
...
ValueType
...
62
Cátia Vaz 2012
Interfaces – Exemplo 2
using System; using System.Collections; public class Program{ Porque o tipo do objecto
implementa ambas as interfaces
public static void Main(){ String s="AVE"; ICloneable cloneable = s; IComparable comparable = s; IEnumerable enumerable = (IEnumerable) comparable; } } 63
Cátia Vaz 2012
Interfaces (pré-genéricos) de enumeração - IEnumerable, IEnumerator e C#
foreach
public interface System.Collections.IEnumerable { IEnumerator GetEnumerator(); } public interface System.Collections.IEnumerator { Boolean MoveNext(); void Reset(); Object Current { get; } } ArrayList vals = new ArrayList(new Int32[]{ 1, 4, 5 }); IEnumerator itr = vals.GetEnumerator(); ... while(itr.MoveNext()) Console.WriteLine((Int32)itr.Current); ... ArrayList vals = new ArrayList(new Int32[]{ 1, 4, 5 }); foreach(Int32 v in vals) Console.WriteLine(v); 64
Cátia Vaz 2012
ICloneable
public interface System.ICloneable {
Object Clone();
}
w  Implementada por tipos que permitam “clonagem” de instâncias
w  Políticas de “clonagem”:
n 
Cópia superficial (shallow copy)
l 
n 
65
Método Object MemberwiseClone() de System.Object
Cópia total (deep copy)
Cátia Vaz 2012
Interfaces e Value Types
w  Os Value Types derivam obrigatoriamente e directamente de
System.ValueType ou de System.Enum mas podem implementar 0 ou
mais interfaces (via boxing)
w  A conversão entre um Value Type e as interfaces por ele implementadas está
sujeita às regras de conversão entre Value Types e Reference Types (boxing e
unboxing)
public struct Point : System.IComparable {
public Int32 CompareTo(Object o) { return ... }
}
...
Point p1 = new Point(1,2), p2 = new Point(2,1);
p1.CompareTo(p2);
// boxing em p2
((System.IComparable)p1).CompareTo(p2);
// boxing em p1 e p2
...
66
Cátia Vaz 2012
Implementação Explícita de interfaces
§  Uma classe que implementa uma interface pode explicitamente implementar um
membro dessa interface.
§  Quando um membro é explicitamente implementado, não pode ser acedido
através uma instância da classe.
Exemplo:
interface IDimensions { float Length(); float Width(); } class Box : IDimensions { float lengthInches; float widthInches; public Box(float length, float width) { lengthInches = length; widthInches = width; } float IDimensions.Length() { return lengthInches; } float IDimensions.Width() { return widthInches; } public static void Main() { Box myBox = new Box(30.0f, 20.0f); IDimensions myDimensions = (IDimensions) myBox; System.Console.WriteLine("Length: {0}", myDimensions.Length()); System.Console.WriteLine("Width: {0}", myDimensions.Width()); } } 67
Cátia Vaz 2012
Implementação Explícita de interfaces(2)
interface IEnglishDimensions { float Length(); float Width(); } interface IMetricDimensions { float Length(); float Width(); } class Box : IEnglishDimensions, IMetricDimensions { float lengthInches; float widthInches; public Box(float length, float width) { lengthInches = length; widthInches = width; float IEnglishDimensions.Length() { return lengthInches; } float IEnglishDimensions.Width() { return widthInches; } float IMetricDimensions.Length() { return lengthInches * 2.54f; } float IMetricDimensions.Width() { return widthInches * 2.54f; } public static void Main() { Box myBox = new Box(30.0f, 20.0f); A implementação
explícita de um
membro de
interface pode ser
útil, por exemplo,
em cenários de
implementação de
duas interfaces
que partilham
métodos com a
mesma assinatura
IEnglishDimensions eDimensions = (IEnglishDimensions) myBox; IMetricDimensions mDimensions = (IMetricDimensions) myBox; System.Console.WriteLine("Length(in): {0}", eDimensions.Length()); System.Console.WriteLine("Length(cm): {0}", mDimensions.Length()); } 68
} Cátia Vaz 2012
Implementação explícita de Interfaces
} 
Os tipos que implementam as interfaces podem dar uma implementação
explícita de alguns métodos da interface.
} 
A implementação explícita é privada
public interface IA { void Method1(); void Method2(Int32 val); } 69
public class Impl : IA { public void Method1(){ .. } void IA.Method2(Int32 val){ .. } } Cátia Vaz 2012
Implementação explicita de interfaces
} 
Um tipo exacto (classe) pode optar por esconder a
implementação de um método da sua “interface” pública
AClass a = new AClass();
a.Draw(); // AClass.Draw
IWindow iw = (IWindow) a;
iw.Draw(); // IWindow.Draw
public interface IWindow { void Draw(); } public interface IArtist[ void Draw(); } public class AClass : IWindow , IArtist { // apenas visivel com uma referência para ICowboy void IWindow.Draw() { } // apenas visível com uma referência para IArtist void IArtist.Draw() { } // visível com uma referência para aClass public void Draw() { } } 70
Cátia Vaz 2012
Implementação explícita de Interfaces (II)
A implementação explícita de interfaces permite evitar operações de box e
unbox na invocação de métodos de implementação de interfaces em tipos
valor, usando o idioma mostrado a seguir:
struct Val : ICloneable { public int v; object ICloneable.Clone() { return MemberWiseClone(); } public Val Clone() { return new Val(v); }
} 71
Usado quando:
ICloneable ic = new Val(5);
Val v1 = (Val) ic.Clone();
Permite:
Val v = new Val(5);
Val v1 = v.Clone();
Sem operações de box e unbox
Cátia Vaz 2012
Linguagem C# - Modelo de tipos revisitado
Legenda
BCL
Namespace System
Object
object
User defined
String
string
ValueType
Interface Type
Class Type
Array
Array Type
Enum
Double
double
Char
char
Single
float
Boolean
bool
Int64
long
UInt64
ulong
Int32
int
UInt32
uint
Int16
short
UInt16
ushort
Sbyte
sbyte
Byte
byte
Struct Type
Enum Type
72
Cátia Vaz 2012
72
Tabela de métodos
} 
Quando um tipo armazenado no CLR, uma tabela de
métodos é inicializada para o tipo.
} 
A tabela de métodos no CLR tem entradas para métodos de
instância e estáticos.
} 
A primeira região é usada para os métodos virtuais (declarados no
tipo actual, nos tipos base ou interfaces)
Slots iniciais irão corresponder aos métodos virtuais declarados pelos tipo
base;
¨  Slots seguintes irão corresponder aos novos métodos virtuais introduzidos
pelo tipo;
¨ 
} 
Exemplo:
¨ 
} 
73
Como System.Object é o tipo base de todos os tipos concretos e tem
4 métodos virtuais, os primeiros slots de todas as tabelas de métodos
correspondem a esses 4 métodos
A segunda região é usada para métodos não virtuais
Cátia Vaz 2012
Atributos de metadata e métodos virtuais
Atributos
de
metadata
Presente
Ausente
virtual
O índice na tabela de métodos
está na região dos métodos
virtuais.
O índice na tabela de métodos está
na região dos métodos não
virtuais.
newslot
Aloca um novo índice na tabela de
métodos
Re-utiliza o índice do método do
tipo base, se possível.
abstract
Requere substituição no tipo
derivado.
Permite substituição no tipo
derivado
final
Proíbe subtituição no tipo
derivado.
Permite substituição no tipo
derivado
74
Cátia Vaz 2012
Tabela de interfaces
} 
Quando um tipo armazenado no CLR, uma tabela de
interfaces é inicializada para o tipo.
} 
75
A tabela de interfaces tem entradas para cada interface que o
tipo é compatível
Cátia Vaz 2012
Informação de tipo em tempo de execução (RTTI)
object
reference
instância de T2
htype
(T2) RTTI
Interface table
htype (IB)
pItfTable
campos
pBase
Method
table
interface IA { } interface IB { } class T1 : IA, IB { } class T2 : T1, IB { } (T1) RTTI
pItfTable
Interface table
htype (IA)
htype (IB)
pBase
(Object) RTTI
Method
table
pItfTable
null
pBase
Method
table
baseado no livro “Essential .NET”
76
Cátia Vaz 2012
Arrays
} 
} 
Todos os tipos de arrays derivam implicitamente da classe abstracta
System.Array.
Exemplos:
} 
} 
} 
} 
} 
} 
} 
} 
} 
} 
} 
} 
77
Int32[ ] myIntegers = new Int32[100]; Point[ ] myPoints = new Point[10]; Double[ , ] myDoubles = Double[10,20]; int[] numbers = new int[5] {1, 2, 3, 4, 5}; int[] numbers = new int[] {1, 2, 3, 4, 5}; int[] numbers = {1, 2, 3, 4, 5}; int[,] numbers = { {1, 2}, {3, 4}, {5, 6} }; //jagged arrays (arrays de arrays)
Point[ ][ ] myPoligon = new Point[3][ ]; myPoligon[0] = new Point[10]; myPoligon[1] = new Point[20]; myPoligon[2] = new Point[30]; Cátia Vaz 2012
Conversão de Arrays
} 
CLR permite a conversão do tipo dos elementos do array
origem para o tipo pretendido
} 
} 
Ambos os arrays têm de ter as mesmas dimensões
Tem de existir uma conversão implícita ou explícita do tipo do
elemento do array de origem para o tipo do elemento do array
destino
} 
} 
} 
} 
FileStream[ ] s1 = new FileStream[10]; Object[ ] o1= s1; FileStream[ ] s2 = (FileStream[ ]) o1; A conversão dos arrays de um tipo para o outro designase por covariância.
78
Cátia Vaz 2012
covariância em arrays
Seja o seguinte código:
string[] tabStrings = new string[] { "str1", "str2", "str3" };
Console.WriteLine("Size={0}", tabStrings.Length);
foreach( string str in tabStrings )
Console.WriteLine(str);
// E o código seguinte?
object[] tabObjects = tabStrings;
// covariância em arrays
tabObjects[2]= new object();
// problemas?
79
Cátia Vaz 2012
Arrays com limite inferior diferente de zero
} 
É possível criar este tipo de arrays recorrendo à método:
public static Array CreateInstance(Type elementType, int[] lengths, int[] lowerBounds) Array unidimensional que contém
Um
array
unidimensional
que
O tipo do array
o limite inferior (o índice de início)
contém o tamanho de cada
de cada dimensão do array a criar dimensão do array a criar
Exemplos:
Array a = Array.CreateInstance(typeof(String),new Int32[] {0} , new Int32[] {1}) Array b; b= Array.CreateInstance(typeof(String),new Int32[] {0,0} , new Int32[] {1,1}) 80
Cátia Vaz 2012
Interfaces implementadas pela classe Array
interface
System.Collections.IList
interface
System.Collections.ICollection
+Add(value:object):int
+Clear():void
+Contains(value:object):bool
+IndexOf(value :object):int
+Insert(index:int,value:object):void
+Rem ove(value:object):void
+Rem oveAt(index:int):void
+this(index:int):object
+CopyTo(array:Array,inde x:int):void
C ount:int
S yncRoot:object
IsSynchronized:bool
IsFixedSiz e:bool
IsReadOnly:bool
Array
interface
System.Collections.IEnum erable
+Ge tEnume rator():IEnumerator
81
interface
System.Collections.ICloneable
+Clone():object
Cátia Vaz 2012
O tipo Array - propriedades
Para além das propriedades relacionadas com a implementação
das interfaces IList, IEnumerable e IClonable
Length
Gets a 32-bit integer that represents the total number of elements in all the
dimensions of the Array.
LongLength
Gets a 64-bit integer that represents the total number of elements in all the
dimensions of the Array.
Rank
Gets the rank (number of dimensions) of the Array.
82
Cátia Vaz 2012
O tipo Array – métodos publicos (I)
Para além dos métodos relacionados com a implementação
das interfaces IList, IEnumerable e IClonable e dos
definidos em object
static int BinarySearch(Array, object)
Overloaded. Searches a one-dimensional sorted Array for a
value, using a binary search algorithm.
static void Copy(Array, Array, int)
Overloaded. Copies a section of one Array to another Array
and performs type casting and boxing as required.
static Array CreateInstance(Type, int)
Overloaded. Initializes a new instance of the Array class.
int GetLength( int dimension)
Gets a 32-bit integer that represents the number of elements in
the specified dimension of the Array.
int GetLowerBound(int dimension)
Gets the lower bound of the specified dimension in the Array.
83
Cátia Vaz 2012
O tipo Array – métodos publicos (II)
public int GetUpperBound( int dimension)
Gets the upper bound of the specified dimension in the Array.
public object GetValue(int)
Overloaded. Gets the value of the specified element in the current Array.
The indexes are specified as an array of 32-bit integers.
public void Initialize()
Initializes every element of the value-type Array by calling the default
constructor of the value type.
public static void Reverse(Array)
Overloaded. Reverses the order of the elements in a one-dimensional
Array or in a portion of the Array.
public void SetValue(object, int)
Overloaded. Sets the specified element in the current Array to the
specified value.
public static void Sort(Array)
Overloaded. Sorts the elements in one-dimensional Array objects.
Acesso a array não seguro
} 
O acesso a array não seguro permite aceder
} 
} 
} 
} 
A elementos de um objecto array managed (alojado no heap)
A elementos de um array que está alojado no unmanaged heap
A elementos de um array que está alojado na stack
Para alojar um array na stack utiliza-se a instrução stackalloc
} 
Apenas se podem criar arrays unidimensionais, cujo tipo de elementos
seja tipo valor, com limite inferior zero (zero-based arrays)
} 
} 
O tipo valor poderá conter campos de tipo referência
É necessário especificar o swich /unsafe ao compilador de C#
Acesso a array não seguro – Exemplo 1
//. . . public static void Main(){ StackallocDemo(); } private static void StackallocDemo( ){ unsafe{ const Int32 width = 20 ; Char * pc = stackalloc Char [ width ]; String s =“ Ola Mundo “; for(Int32 index = 0; index <width; index++){ pc[width – index – 1] = (index <s.Length) ? s[index] : ‘.’; } Console.WriteLine(new String(pc,0,width)); } //. . . Acesso a array não seguro – Exemplo 2
//. . . public static void Main{ InlineArrayDemo(); } internal unsafe struct CharArray { public fixed Char Characters[ 20 ]; } private static void InlineArrayDemo( ){ unsafe{ CharArray ca; const Int32 width = 20 ; String s =“Ola Mundo“; for(Int32 index = 0; index <width; index++){ ca.Characters[width – index – 1] = (index <s.Length) ? s[index] : ‘.’; } Console.WriteLine(new String(ca.Characters,0,width)); } //. . . Namespaces e Assemblies
} 
Os namespaces permitem o agrupamento lógico de tipos relacionados. Este mecanismo é usado pelo
programadores para localizarem facilmente um determinado tipo. Por exemplo, o namespace
System.Collections define o grupo de tipos colecção, e o namespace System.IO define o grupo de tipos
relacionados com as operações de I/O. A seguir apresenta-se código que constrói um objecto do tipo
System.IO.FileStream e um objecto do tipo System.Collections.Queue:
class App {
static void Main() {
System.IO.FileStream fs = new System.IO.FileStream(...);
System.Collections.Queue q = new System.Collections.Queue();
}
}
// ou
using System.IO;
// Try prepending "System.IO"
using System.Collections; // Try prepending "System.Collections"
class App {
static void Main() {
FileStream fs = new FileStream(...);
Queue q = new Queue();
}
}
Importante O CLR não tem a noção de namespaces. Quando acede a um tipo, o CLR necessita de
conhecer o nome completo do tipo e qual o assembly que contém a respectiva definição.
Não existe nenhuma relação entre assemblies e namespaces.
88
Cátia Vaz 2012
Download

public