Anda di halaman 1dari 800

O autor

JOHN SHARP o mais importante tecnlogo da Content Master,


uma diviso do CM Group Ltd, no Reino Unido. A empresa espe-
cializada em solues de treinamento avanadas para grandes mul-
tinacionais, frequentemente utilizando as tecnologias mais recentes
e inovadoras para obter resultados de aprendizado eficientes. John
obteve ttulo de distino em Computao do Imperial College, Lon-
dres. Vem desenvolvendo software e cursos de treinamento em redao, guias e livros
h mais de 27 anos. Tem ampla experincia em diversas tecnologias, de sistemas de
banco de dados e UNIX a aplicativos em C, C++ e C# para o .NET Framework.
Tambm j escreveu sobre desenvolvimento em Java e JavaScript, e sobre projeto de
solues empresariais utilizando Windows Azure. Alm das sete edies do Microsoft
Visual C# Passo a Passo, escreveu vrios outros livros, incluindo Microsoft Windows
Communication Foundation Step By Step e J# Core Reference. Em seu cargo na Content
Master, autor regular da Microsoft Patterns & Practices, tendo trabalhado recente-
mente em guias, como Building Hybrid Applications in the Cloud on Windows Azure e
Data Access for Highly Scalable Solutions Using SQL, NoSQL, and Polyglot Persistence.

S531m Sharp, John.


Microsoft Visual C# 2013 : passo a passo [recurso
eletrnico] / John Sharp ; traduo : Joo Eduardo Nbrega
Tortello ; reviso tcnica: Daniel Antonio Callegari. Porto
Alegre : Bookman, 2014.

Editado tambm como livro impresso em 2014.


ISBN 978-85-8260-210-2

1. Computao - Desenvolvimento de programas. I. Ttulo.

CDU 004.413Visual C#

Catalogao na publicao: Poliana Sanchez de Araujo CRB-10/2094

Sharp_Visual_Iniciais_eletronica.indd ii 18/09/14 15:01


Traduo:
Joo Eduardo Nbrega Tortello

Reviso tcnica:
Daniel Antonio Callegari
Doutor em Cincia da Computao e professor da PUCRS
Profissional certificado Microsoft

Verso impressa
desta obra: 2014

2014

Sharp_Visual_Iniciais_eletronica.indd iii 18/09/14 15:01


Obra originalmente publicada sob o ttulo

Microsoft Visual C# 2013 Step by Step, de John Sharp
ISBN 978-0-7356-8183-5
Edio original em ingls copyright 2013 de CM Group, Ltd.
Traduo para a lngua portuguesa copyright 2014, Bookman Companhia Editora Ltda., uma
empresa do Grupo A Educao S.A. Traduo publicada e comercializada com permisso da OReilly
Media,Inc., que detm ou controla todos os direitos de publicao e comercializao da mesma.

Gerente editorial: Arysinha Jacques Affonso

Colaboraram nesta edio:

Editora: Mariana Belloli

Capa: Kale, arte sobre capa original

Leitura final: Bianca Basile

Editorao: Techbooks

Microsoft e todas as marcas listadas em http://www.microsoft.com/about/legal/en/us/Intellectual-


Property/Trademarks/EN-US.aspx so marcas comerciais registradas do grupo de empresas da Mi-
crosoft. Outras marcas mencionadas aqui so marcas comerciais de seus respectivos proprietrios.
Os exemplos de empresas, organizaes, produtos, nomes de domnio, endereos de correio
eletrnico, logotipo, pessoas, lugares ou eventos aqui apresentados so fictcios. Nenhuma as-
sociao com qualquer empresa, organizao, produto, nome de domnio, endereo de correio
eletrnico, logotipo, pessoa, lugar ou eventos reais foi proposital ou deve ser inferido.
Este livro expressa as vises e opinies dos autores. As informaes aqui contidas so fornecidas
sem quaisquer garantias expressas, legais ou implcitas. Os autores, a Microsoft Corporation e
seus revendedores ou distribuidores no podero ser responsabilizados por qualquer dano cau-
sado, ou supostamente causado, direta ou indiretamente, por este livro.

Reservados todos os direitos de publicao, em lngua portuguesa,


BOOKMAN EDITORA LTDA., uma empresa do GRUPO A EDUCAO S.A.
Av. Jernimo de Ornelas, 670 Santana
90040-340 Porto Alegre RS
Fone: (51) 3027-7000 Fax: (51) 3027-7070

proibida a duplicao ou reproduo deste volume, no todo ou em parte, sob quaisquer


formas ou por quaisquer meios (eletrnico, mecnico, gravao, fotocpia, distribuio na Web
e outros), sem permisso expressa da Editora.

Unidade So Paulo
Av. Embaixador Macedo Soares, 10.735 Pavilho 5 Cond. Espace Center
Vila Anastcio 05095-035 So Paulo SP
Fone: (11) 3665-1100 Fax: (11) 3667-1333

SAC 0800 703-3444 www.grupoa.com.br

IMPRESSO NO BRASIL
PRINTED IN BRAZIL

_Livro_Sharp_Visual.indb iv 30/06/14 15:02


Sumrio

Introduo xvii
Quem deve ler este livro . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xviii
Quem no deve ler este livro . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xviii
Organizao deste livro . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xix
Encontre o melhor ponto de partida . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xix
Convenes e recursos deste livro . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .xx
Requisitos de sistema. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xxi
Exemplos de cdigo. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .xxii
Instale os exemplos de cdigo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .xxii
Utilize os exemplos de cdigo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xxiii
Agradecimentos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xxviii
Suporte tcnico . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xxix

PARTE I INTRODUO AO MICROSOFT VISUAL C# E AO


MICROSOFT VISUAL STUDIO 2013

Captulo 1 Bem-vindo ao C# 3
Comece a programar com o ambiente do Visual Studio 2013 . . . . . . . . . . . . . . 3
Escreva seu primeiro programa . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
Namespaces . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
Crie um aplicativo grfico . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
Examine o aplicativo Windows Store . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
Examine o aplicativo WPF. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33
Adicione cdigo ao aplicativo grfico . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34
Resumo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38
Referncia rpida . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38

Captulo 2 Variveis, operadores e expresses 39


Instrues . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39
Identificadores . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40
Identifique palavras-chave . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40

_Livro_Sharp_Visual.indb v 30/06/14 15:02


vi Sumrio

Variveis . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41
Nomeie variveis . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41
Declare variveis . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42
Tipos de dados primitivos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43
Variveis locais no atribudas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43
Exiba valores de tipos de dados primitivos . . . . . . . . . . . . . . . . . . . . . . . . 44
Operadores aritmticos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52
Operadores e tipos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52
Examine operadores aritmticos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53
Controle a precedncia . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59
Utilize a associatividade para avaliar expresses. . . . . . . . . . . . . . . . . . . . 60
A associatividade e o operador de atribuio . . . . . . . . . . . . . . . . . . . . . . 60
Incremente e decremente variveis . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61
Prefixo e sufixo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61
Declare variveis locais implicitamente tipadas. . . . . . . . . . . . . . . . . . . . . . . . . . 62
Resumo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63
Referncia rpida . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 64

Captulo 3 Como escrever mtodos e aplicar escopo 65


Crie mtodos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65
Declare um mtodo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 66
Retorne dados de um mtodo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67
Chame mtodos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69
Aplique escopo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72
Defina o escopo local . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72
Defina o escopo de classe . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73
Sobrecarregue mtodos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74
Escreva mtodos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74
Parmetros opcionais e argumentos nomeados . . . . . . . . . . . . . . . . . . . . . . . . . 83
Define parmetros opcionais . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85
Passe argumentos nomeados. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85
Resolva ambiguidades com parmetros opcionais e
argumentos nomeados . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 86
Resumo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 91
Referncia rpida . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 92

_Livro_Sharp_Visual.indb vi 30/06/14 15:02


Sumrio vii

Captulo 4 Instrues de deciso 93


Declare variveis booleanas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 93
Operadores booleanos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 94
Entenda os operadores de igualdade e relacionais . . . . . . . . . . . . . . . . . 94
Entenda os operadores lgicos condicionais . . . . . . . . . . . . . . . . . . . . . . . 95
Curto-circuito . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 96
Um resumo da precedncia e da associatividade dos operadores . . . . 96
Instrues if para tomar decises . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 97
Entenda a sintaxe da instruo if . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 97
Utilize blocos para agrupar instrues . . . . . . . . . . . . . . . . . . . . . . . . . . . . 98
Instrues if em cascata . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 99
Instrues switch. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 105
Entenda a sintaxe da instruo switch . . . . . . . . . . . . . . . . . . . . . . . . . . . 106
Siga as regras da instruo switch . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 107
Resumo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 111
Referncia rpida . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 111

Captulo 5 Atribuio composta e instrues de iterao 113


Operadores de atribuio composta. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 113
Escreva instrues while . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 115
Escreva instrues for. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 121
Entendendo o escopo da instruo for. . . . . . . . . . . . . . . . . . . . . . . . . . . 123
Escreva instrues do . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 123
Resumo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 132
Referncia rpida . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 133

Captulo 6 Gerenciamento de erros e excees 134


Lide com erros . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 134
Teste o cdigo e capture as excees . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 135
Excees no tratadas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 136
Utilize vrias rotinas de tratamento catch . . . . . . . . . . . . . . . . . . . . . . . . 137
Capture mltiplas excees . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 138
Propague excees . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 144
Aritmtica verificada e no verificada de nmeros inteiros. . . . . . . . . . . . . . . 146
Escreva instrues verificadas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 147
Escreva expresses verificadas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 148

_Livro_Sharp_Visual.indb vii 30/06/14 15:02


viii Sumrio

Lance excees . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 151


Bloco finally . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 155
Resumo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 156
Referncia rpida . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 157

PARTE II O MODELO DE OBJETOS DO C#

Captulo 7 Criao e gerenciamento de classes e objetos 161


Classificao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 161
O objetivo do encapsulamento . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 162
Defina e utilize uma classe . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 162
Controle a acessibilidade . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 164
Trabalhe com construtores . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 165
Sobrecarregue construtores . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 167
Dados e mtodos static . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 175
Crie um campo compartilhado . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 176
Crie um campo static utilizando a palavra-chave const . . . . . . . . . . . . . 177
Entenda as classes static . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 177
Classes annimas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 180
Resumo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 181
Referncia rpida . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 182

Captulo 8 Valores e referncias 183


Copie variveis de tipo-valor e classes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 183
Valores nulos e tipos nullable . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 189
Utilize tipos nullable . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 190
Entenda as propriedades dos tipos nullable . . . . . . . . . . . . . . . . . . . . . . 191
Parmetros ref e out . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 192
Crie parmetros ref. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 193
Crie parmetros out . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 193
Como a memria do computador organizada . . . . . . . . . . . . . . . . . . . . . . . . 195
Utilize a pilha e o heap . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 197
A classe System.Object . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 198
Boxing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 199
Unboxing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 199

_Livro_Sharp_Visual.indb viii 30/06/14 15:02


Sumrio ix

Casting de dados seguro . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 201


O operador is . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 201
O operador as . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 202
Resumo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 204
Referncia rpida . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 204

Captulo 9 Como criar tipos-valor com enumeraes e estruturas 206


Enumeraes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 206
Declare uma enumerao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 207
Utilize uma enumerao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 207
Escolha valores literais de enumerao . . . . . . . . . . . . . . . . . . . . . . . . . . 208
Escolha o tipo subjacente de uma enumerao . . . . . . . . . . . . . . . . . . . 209
Estruturas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 211
Declare uma estrutura . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 213
Entenda as diferenas entre estrutura e classe . . . . . . . . . . . . . . . . . . . . 214
Declare variveis de estrutura . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 215
Entenda a inicializao de estruturas . . . . . . . . . . . . . . . . . . . . . . . . . . . . 216
Copie variveis de estrutura . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 220
Resumo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 224
Referncia rpida . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 224

Captulo 10 Arrays 226


Declare e crie um array . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 226
Declare variveis de array . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 226
Crie uma instncia de array . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 227
Preencha e utilize um array . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 228
Crie um array implicitamente tipado . . . . . . . . . . . . . . . . . . . . . . . . . . . . 229
Acesse um elemento individual de um array . . . . . . . . . . . . . . . . . . . . . . 230
Itere por um array . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 230
Passe arrays como parmetros e valores de retorno
para um mtodo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 232
Copie arrays. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 233
Arrays multidimensionais . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 235
Crie arrays irregulares . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 236
Resumo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 247
Referncia rpida . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 247

_Livro_Sharp_Visual.indb ix 30/06/14 15:02


x Sumrio

Captulo 11 Arrays de parmetros 249


Sobrecarga uma recapitulao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 249
Argumentos de arrays . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 250
Declare um array params . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 251
Utilize params object[ ] . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 253
Utilize um array params . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 254
Compare arrays de parmetros e parmetros opcionais . . . . . . . . . . . . . . . . . 257
Resumo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 260
Referncia rpida . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 260

Captulo 12 Herana 261


O que herana? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 261
Herana . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 262
A classe System.Object revisitada . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 264
Chame construtores da classe base. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 264
Atribua classes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 265
Declare mtodos new . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 267
Declare mtodos virtuais . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 268
Declare mtodos override . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 269
Entenda o acesso protected . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 272
Mtodos de extenso . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 278
Resumo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 282
Referncia rpida . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 282

Captulo 13 Como criar interfaces e definir classes abstratas 284


Interfaces . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 284
Defina uma interface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 285
Implemente uma interface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 286
Referencie uma classe por meio de sua interface . . . . . . . . . . . . . . . . . . 287
Trabalhe com vrias interfaces . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 288
Implemente uma interface explicitamente . . . . . . . . . . . . . . . . . . . . . . . 289
Restries das interfaces . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 290
Defina e utilize interfaces . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 291
Classes abstratas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 301
Mtodos abstratos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 303

_Livro_Sharp_Visual.indb x 30/06/14 15:02


Sumrio xi

Classes seladas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 303


Mtodos selados . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 303
Implemente e utilize uma classe abstrata . . . . . . . . . . . . . . . . . . . . . . . . 304
Resumo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 310
Referncia rpida . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 311

Captulo 14 Coleta de lixo e gerenciamento de recursos 313


O tempo de vida de um objeto . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 313
Escreva destrutores . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 314
Por que utilizar o coletor de lixo? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 316
Como funciona o coletor de lixo? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 318
Recomendaes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 318
Gerenciamento de recursos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 319
Mtodos de descarte . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 319
Descarte seguro quanto a excees . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 320
A instruo using e a interface IDisposable . . . . . . . . . . . . . . . . . . . . . . . 320
Chame o mtodo Dispose a partir de um destrutor . . . . . . . . . . . . . . . . 322
Implemente o descarte seguro quanto a excees . . . . . . . . . . . . . . . . . . . . . 324
Resumo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 332
Referncia rpida . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 333

PARTE III DEFINIO DE TIPOS EXTENSVEIS EM C#

Captulo 15 Implementao de propriedades para acessar campos 337


Implemente encapsulamento com mtodos . . . . . . . . . . . . . . . . . . . . . . . . . . . 337
O que so propriedades? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 339
Utilize propriedades. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 341
Propriedades somente-leitura . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 342
Propriedades somente-gravao. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 342
Acessibilidade de propriedades . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 343
Restries de uma propriedade . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 344
Declare propriedades de interface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 345
Substitua mtodos por propriedades . . . . . . . . . . . . . . . . . . . . . . . . . . . . 347
Como gerar propriedades automticas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 351
Como inicializar objetos com propriedades. . . . . . . . . . . . . . . . . . . . . . . . . . . . 353
Resumo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 356
Referncia rpida . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 357

_Livro_Sharp_Visual.indb xi 30/06/14 15:02


xii Sumrio

Captulo 16 Indexadores 359


O que um indexador? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 359
Um exemplo que no utiliza indexadores . . . . . . . . . . . . . . . . . . . . . . . . 360
O mesmo exemplo utilizando indexadores . . . . . . . . . . . . . . . . . . . . . . . 362
Entenda os mtodos de acesso do indexador . . . . . . . . . . . . . . . . . . . . . 364
Compare indexadores e arrays. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 364
Indexadores em interfaces . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 366
Indexadores em um aplicativo Windows . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 367
Resumo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 374
Referncia rpida . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 375

Captulo 17 Genricos 376


O problema do tipo object . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 376
A soluo dos genricos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 380
Classes genricas versus generalizadas. . . . . . . . . . . . . . . . . . . . . . . . . . . 382
Genricos e restries . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 382
Crie uma classe genrica . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 383
A teoria das rvores binrias . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 383
Construa uma classe de rvore binria com genricos . . . . . . . . . . . . . 386
Crie um mtodo genrico . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 396
Defina um mtodo genrico para criar uma rvore binria . . . . . . . . . 396
Varincia e interfaces genricas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 398
Interfaces covariantes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 400
Interfaces contravariantes. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 402
Resumo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 404
Referncia rpida . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 404

Captulo 18 Colees 406


O que so classes de coleo? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 406
A classe de coleo List<T> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 408
A classe de coleo LinkedList<T>. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 410
A classe de coleo Queue<T> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 412
A classe de coleo Stack<T> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 413
A classe de coleo Dictionary<TKey, TValue> . . . . . . . . . . . . . . . . . . . . 414
A classe de coleo SortedList<TKey, TValue> . . . . . . . . . . . . . . . . . . . . . 415
A classe de coleo HashSet<T> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 417
Inicializadores de coleo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 418

_Livro_Sharp_Visual.indb xii 30/06/14 15:02


Sumrio xiii

Os mtodos Find, predicados e expresses lambda . . . . . . . . . . . . . . . . . . . . . 419


Compare arrays e colees . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 421
Utilize classes de coleo para jogar cartas . . . . . . . . . . . . . . . . . . . . . . . 421
Resumo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 426
Referncia rpida . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 426

Captulo 19 Enumerao sobre colees 428


Enumere os elementos em uma coleo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 428
Implemente manualmente um enumerador . . . . . . . . . . . . . . . . . . . . . . 430
Implemente a interface IEnumerable . . . . . . . . . . . . . . . . . . . . . . . . . . . . 434
Implemente um enumerador utilizando um iterador . . . . . . . . . . . . . . . . . . . 437
Um iterador simples. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 437
Defina um enumerador para a classe Tree<TItem>
por meio de um iterador . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 439
Resumo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 441
Referncia rpida . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 442

Captulo 20 Separao da lgica do aplicativo e


tratamento de eventos 443
Delegates . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 444
Exemplos de delegates na biblioteca de classes do .NET Framework. . . 445
O cenrio da fbrica automatizada . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 447
Implemente o sistema de controle da fbrica
sem utilizar delegates . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 447
Implemente a fbrica utilizando um delegate . . . . . . . . . . . . . . . . . . . . 448
Declare e utilize delegates . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 451
Expresses lambda e delegates . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 460
Crie um mtodo adaptador . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 461
As formas das expresses lambda . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 461
Ative notificaes por meio de eventos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 463
Declare um evento . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 464
Faa a inscrio em um evento . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 464
Cancele a inscrio em um evento . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 465
Dispare um evento . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 465
Eventos de interface de usurio . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 466
Utilize eventos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 467
Resumo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 474
Referncia rpida . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 474

_Livro_Sharp_Visual.indb xiii 30/06/14 15:02


xiv Sumrio

Captulo 21 Consulta a dados na memria usando


expresses de consulta 477
O que a Language-Integrated Query? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 477
Como utilizar a LINQ em um aplicativo C# . . . . . . . . . . . . . . . . . . . . . . . . . . . . 478
Selecione dados . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 480
Filtre dados . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 482
Ordene, agrupe e agregue dados . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 483
Juno de dados . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 485
Utilize operadores de consulta . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 487
Consulte dados em objetos Tree<TItem> . . . . . . . . . . . . . . . . . . . . . . . . 489
LINQ e avaliao postergada . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 495
Resumo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 499
Referncia rpida . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 500

Captulo 22 Sobrecarga de operadores 502


Operadores . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 502
Restries dos operadores . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 503
Operadores sobrecarregados . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 503
Crie operadores simtricos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 505
Avaliao da atribuio composta. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 507
Declare operadores de incremento e decremento . . . . . . . . . . . . . . . . . . . . . . 508
Como comparar operadores em estruturas e classes . . . . . . . . . . . . . . . . . . . . 509
Defina pares de operadores . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 509
Como implementar operadores . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 511
Operadores de converso . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 517
Fornea converses predefinidas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 518
Implemente operadores de converso definidos pelo usurio. . . . . . . 519
Crie operadores simtricos, uma retomada do assunto. . . . . . . . . . . . . 520
Escreva operadores de converso . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 520
Resumo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 523
Referncia rpida . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 523

_Livro_Sharp_Visual.indb xiv 30/06/14 15:02


Sumrio xv

PARTE IV CONSTRUO DE APLICATIVOS WINDOWS 8.1


PROFISSIONAIS COM C#

Captulo 23 Como melhorar o desempenho usando tarefas 527


Por que fazer multitarefa por meio de processamento paralelo? . . . . . . . . . 527
O surgimento do processador multincleo . . . . . . . . . . . . . . . . . . . . . . . 528
Como implementar multitarefa com o Microsoft .NET Framework . . . . . . . . 530
Tarefas, threads e o ThreadPool . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 530
Crie, execute e controle tarefas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 531
Utilize a classe Task para implementar paralelismo . . . . . . . . . . . . . . . . 534
Abstraia tarefas com a classe Parallel . . . . . . . . . . . . . . . . . . . . . . . . . . . . 546
Quando no utilizar a classe Parallel . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 550
Cancele tarefas e trate excees . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 552
Mecnica do cancelamento cooperativo . . . . . . . . . . . . . . . . . . . . . . . . . 552
Utilize continuaes com tarefas canceladas e com falhas . . . . . . . . . . 566
Resumo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 567
Referncia rpida . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 568

Captulo 24 Como melhorar o tempo de resposta empregando


operaes assncronas 570
Implemente mtodos assncronos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 571
Definio de mtodos assncronos: o problema . . . . . . . . . . . . . . . . . . . 571
Definio de mtodos assncronos: a soluo . . . . . . . . . . . . . . . . . . . . . 574
Defina mtodos assncronos que retornam valores . . . . . . . . . . . . . . . . 580
Mtodos assncronos e as APIs do Windows Runtime . . . . . . . . . . . . . . 581
Utilize a PLINQ para paralelizar o acesso declarativo a dados . . . . . . . . . . . . 584
Utilize a PLINQ para melhorar o desempenho ao iterar
sobre uma coleo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 585
Cancele uma consulta PLINQ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 590
Sincronize acessos simultneos a dados . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 591
Bloqueie dados . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 593
Primitivas de sincronizao para coordenar tarefas . . . . . . . . . . . . . . . . 594
Cancele a sincronizao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 596
Classes de coleo concorrentes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 597
Utilize uma coleo concorrente e um bloqueio para implementar
acesso a dados thread-safe . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 598
Resumo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 608
Referncia rpida . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 608

_Livro_Sharp_Visual.indb xv 30/06/14 15:02


xvi Sumrio

Captulo 25 Implementao da interface do usurio de


um aplicativo Windows Store 611
O que um aplicativo Windows Store? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 612
Use o template Blank App para compilar um aplicativo Windows Store . . . 616
Implemente uma interface de usurio escalonvel . . . . . . . . . . . . . . . . 618
Aplique estilos em uma interface de usurio . . . . . . . . . . . . . . . . . . . . . 650
Resumo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 659
Referncia rpida . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 660

Captulo 26 Exibio e busca de dados em um aplicativo


Windows Store 661
Implemente o padro Model-View-ViewModel . . . . . . . . . . . . . . . . . . . . . . . . 661
Contratos do Windows 8.1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 689
Resumo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 704
Referncia rpida . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 707

Captulo 27 Acesso a um banco de dados remoto


em um aplicativo Windows Store 709
Recupere dados de um banco de dados . . . . . . . . . . . . . . . . . . . . . . . . . 709
Insira, atualize e exclua dados por meio
de um web service REST . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 729
Resumo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 747
Referncia rpida . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 748

ndice 750

_Livro_Sharp_Visual.indb xvi 30/06/14 15:02


Introduo

M icrosoft Visual C# uma linguagem poderosa e simples, voltada principalmente


para os desenvolvedores que criam aplicativos com o Microsoft .NET Framework.
Ela herda grande parte dos melhores recursos do C++ e Microsoft Visual Basic e pou-
co das inconsistncias e anacronismos, resultando em uma linguagem mais limpa e
lgica. O C# 1.0 foi lanado em 2001. O advento do C# 2.0 com o Visual Studio 2005
introduziu vrios recursos novos importantes na linguagem, como genricos, itera-
dores e mtodos annimos. O C# 3.0, lanado com o Visual Studio 2008, acrescentou
mtodos de extenso, expresses lambda e, o mais famoso de todos os recursos, a
Language-Integrated Query (LINQ). O C# 4.0, lanado em 2010, ofereceu aprimora-
mentos que melhoram sua interoperabilidade com outras linguagens e tecnologias.
Esses recursos abrangeram o suporte para argumentos nomeados e opcionais, e o tipo
dynamic (dinmico), o qual indica que o tempo de execuo da linguagem deve im-
plementar a ligao tardia para um objeto. Incluses importantes no .NET Framework
lanado concomitantemente ao C# 4.0 foram as classes e os tipos que constituem
a Task Parallel Library (TPL). Com a TPL possvel construir, de modo rpido e fcil,
aplicativos altamente escalonveis para processadores multincleo. O C# 5.0 adiciona
suporte nativo para processamento assncrono baseado em tarefas, por meio do mo-
dificador de mtodo async e do operador await.
Outro evento importante da Microsoft foi o lanamento do Windows 8. Essa
nova verso do Windows suporta aplicativos altamente interativos que podem com-
partilhar dados e colaborar entre si, alm de se conectarem com servios em execuo
na nuvem. O ambiente de desenvolvimento fornecido pelo Microsoft Visual Studio
2012 facilitou o uso de todos esses recursos poderosos, e os muitos assistentes e apri-
moramentos novos do Visual Studio 2012 podem aumentar muito sua produtividade
como desenvolvedor.
Aps escutar as opinies dos desenvolvedores, a Microsoft modificou alguns as-
pectos do funcionamento da interface do usurio e lanou uma verso de pr-estreia
tcnica (Technical Preview) do Windows 8.1 contendo essas alteraes. Ao mesmo
tempo, a Microsoft lanou uma edio de pr-estreia do Visual Studio 2013, contendo
alteraes adicionais em relao ao Visual Studio 2012 e adicionando novos recursos
que ajudam a aumentar ainda mais a produtividade do programador. Embora muitas
das atualizaes feitas no Visual Studio sejam pequenas e no tenha havido altera-
es na linguagem C# nessa verso, achamos que as modificaes feitas no modo do
Windows 8.1 manipular a interface do usurio mereceriam uma atualizao gradual
semelhante neste livro. O resultado esta obra.

_Livro_Sharp_Visual.indb xvii 30/06/14 15:02


xviii Introduo

Nota Este livro se baseia na Technical Preview do Visual Studio 2013. Conse-
quentemente, alguns recursos do IDE podem mudar na verso final do software.

Quem deve ler este livro


Este livro destinado a desenvolvedores que desejam aprender os conceitos bsicos
da programao com o C# utilizando o Visual Studio 2013 e o .NET Framework ver-
so 4.5.1. Ao concluir esta obra, voc ter um entendimento completo do C# e o ter
utilizado para produzir aplicativos geis e escalonveis que podem ser executados no
sistema operacional Windows.
possvel construir e executar aplicativos do C# 5.0 no Windows 7, no Win-
dows 8 e no Windows 8.1, embora as interfaces do usurio fornecidas pelo Windows
7 e pelo Windows 8 tenham algumas diferenas significativas. Alm disso, o Windows
8.1 modificou algumas partes do modelo de interface do usurio, e os aplicativos
projetados para tirar proveito dessas alteraes talvez no funcionem no Windows 8.
Consequentemente, as Partes I a III deste livro fornecem exerccios e exemplos traba-
lhados que funcionam no Windows 7, no Windows 8 e no Windows 8.1. A Parte IV se
concentra no modelo de desenvolvimento de aplicativos utilizado pelo Windows 8.1,
sendo que o material dessa seo fornece uma introduo para a criao de aplicati-
vos interativos para essa nova plataforma.

Quem no deve ler este livro


Esta obra se destina a desenvolvedores iniciantes em C#, mas no totalmente inician-
tes em programao. Assim, ela se concentra principalmente na linguagem C#. O livro
no tem como objetivo fornecer uma abordagem detalhada da grande quantidade de
tecnologias disponveis para a criao de aplicativos de nvel empresarial para Win-
dows, como ADO.NET, ASP.NET, Windows Communication Foundation ou Workflow
Foundation. Caso precise de mais informaes sobre qualquer um desses itens, pense
na possibilidade de ler alguns dos outros ttulos da srie Passo a Passo.

_Livro_Sharp_Visual.indb xviii 30/06/14 15:02


Introduo xix

Organizao deste livro


Esta obra est dividida em quatro partes:
j A Parte I, Introduo ao Microsoft Visual C# e ao Microsoft Visual Studio 2013,
fornece uma introduo sintaxe bsica da linguagem C# e ao ambiente de
programao do Visual Studio.
j A Parte II, O modelo de objetos do C#, entra nos detalhes sobre como criar e
gerenciar novos tipos com C# e como gerenciar os recursos referenciados por
esses tipos.
j A Parte III, Definio de tipos extensveis com C#, contm uma abordagem
ampliada dos elementos fornecidos pelo C# para a criao de tipos que podem
ser reutilizados em vrios aplicativos.
j A Parte IV, Construo de aplicativos profissionais do Window 8.1 com C#, des-
creve o modelo de programao do Windows 8.1 e como possvel utilizar C#
para criar aplicativos interativos para esse novo modelo.

Nota Embora a Parte IV seja voltada para o Windows 8.1, muitos conceitos
descritos nos Captulos 23 e 24 tambm so adequados para aplicativos do Win-
dows 8 e do Windows 7.

Encontre o melhor ponto de partida


Este livro foi projetado para ajud-lo a desenvolver habilidades em vrias reas essen-
ciais. Voc pode utiliz-lo se for iniciante em programao ou se estiver migrando de
outra linguagem, como C, C++, Java ou Visual Basic. Consulte a tabela a seguir para
encontrar seu melhor ponto de partida.

Se voc est Siga estes passos


Comeando em programao orientada a 1. Instale os arquivos de prtica conforme
objetos descrito na prxima seo, Exemplos de
cdigo.
2. Siga os captulos nas Partes I, II e III
sequencialmente.
3. Complete a Parte IV conforme seu nvel
de experincia e interesse.
Familiarizado com linguagens de 1. Instale os arquivos de prtica conforme
programao procedural, como C, mas for descrito na prxima seo, Exemplos
iniciante em C# de cdigo. Folheie os cinco primeiros
captulos para obter uma viso geral do
C# e do Visual Studio 2013 e, em seguida,
concentre-se nos Captulos 6 a 22.
2. Complete a Parte IV conforme seu nvel
de experincia e interesse.

_Livro_Sharp_Visual.indb xix 30/06/14 15:02


xx Introduo

Se voc est Siga estes passos


Migrando de uma linguagem orientada a 1. Instale os arquivos de prtica conforme
objetos como C++ ou Java descrito na prxima seo, Exemplos de
cdigo.
2. Folheie os sete primeiros captulos para
obter uma viso geral do C# e do Visual
Studio 2013 e, em seguida, concentre-se
nos Captulos 7 a 22.
3. Leia a Parte IV para obter informaes
sobre como criar aplicativos Windows 8.1
escalonveis.
Trocando do Visual Basic para o C# 1. Instale os arquivos de prtica conforme
descrito na prxima seo, Exemplos de
cdigo.
2. Siga os captulos nas Partes I, II e III
sequencialmente.
3. Leia a Parte IV para obter informaes
sobre como criar aplicativos Windows
8.1.
4. Leia as sees de Referncia rpida
no final dos captulos para obter
informaes sobre questes especficas
do C# e construes do Visual Studio
2013.
Consultando o livro aps fazer os exerccios 1. Utilize o ndice ou o sumrio para
localizar as informaes sobre assuntos
especficos.
2. Leia as sees de Referncia rpida no
final de cada captulo para encontrar
uma reviso sucinta da sintaxe e das
tcnicas apresentadas no captulo.

A maioria dos captulos do livro contm exemplos prticos que permitem a voc
experimentar os conceitos que acabou de aprender. Independentemente das sees
em que queira se concentrar, certifique-se de baixar e instalar os exemplos de aplica-
tivos em seu sistema.

Convenes e recursos deste livro


Este livro usa algumas convenes para tornar as informaes legveis e fceis de com-
preender.
j Cada exerccio consiste em uma srie de tarefas, apresentadas como etapas nu-
meradas (1, 2 e assim por diante) listando cada ao a ser executada para com-
pletar o exerccio.

_Livro_Sharp_Visual.indb xx 30/06/14 15:02


Introduo xxi

j Os elementos em quadros marcados como Nota fornecem informaes adicio-


nais ou mtodos alternativos para completar uma etapa com sucesso.
j Textos que voc deve digitar (com exceo dos blocos de cdigo) aparecem em
negrito.
j Um sinal de adio (+) entre dois nomes de tecla significa que voc deve pres-
sionar essas teclas ao mesmo tempo. Por exemplo, Pressione Alt+Tab quer di-
zer que a tecla Alt deve ser pressionada ao mesmo tempo que a tecla Tab.
j Uma barra vertical entre dois ou mais itens de menu (por exemplo, Arquivo |
Fechar) significa que voc deve selecionar o primeiro menu ou item de menu e,
ento, o seguinte e assim por diante.

Requisitos de sistema
Voc precisar dos seguintes hardware e software para completar os exerccios deste
livro:
j Windows 7 (x86 e x64), Windows 8 (x86 e x64), Windows 8.1 (x86 e x64), Win-
dows Server 2008 R2 SP1 (x64), Windows Server 2012 (x64) ou Windows Server
2012 R2 (x64).

Importante Os templates Windows Store para Visual Studio 2013 no esto


disponveis no Windows 8, Windows 7, Windows Server 2012 ou Windows Ser-
ver 2008 R2. Se quiser usar esses templates ou fazer os exerccios que produzem
aplicativos Windows Store, voc deve usar Windows 8.1 ou Windows Server
2012 R2.

j Visual Studio 2013 (qualquer edio, exceto Visual Studio Express para Windows
8.1).

Importante possvel usar Visual Studio Express 2013 para Windows Desktop,
mas com esse software voc s poder executar a verso para Windows 7 dos
exerccios do livro. No possvel utilizar esse software para fazer os exerccios
da Parte IV desta obra.

j Computador com um processador de 1,6 GHz ou mais rpido (2 GHz recomen-


dado).
j 1 GB (32 bits) ou 2 GB (64 bits) de memria RAM (acrescente 512 MB se estiver
executando em uma mquina virtual).
j 10 GB de espao disponvel no disco rgido.
j Unidade de disco rgido de 5400 RPM.

_Livro_Sharp_Visual.indb xxi 30/06/14 15:02


xxii Introduo

j Placa de vdeo com capacidade para DirectX 9, executando em resoluo de


tela de 1024 768 ou mais; se estiver usando Windows 8.1, recomenda-se uma
resoluo de 1366 768 ou mais.
j Unidade de DVD-ROM (se estiver instalando o Visual Studio a partir de um DVD).
j Conexo com a Internet para baixar software ou os exemplos dos captulos.
Dependendo de sua configurao de Windows, talvez sejam necessrios direitos
de Administrador Local para instalar ou configurar o Visual Studio 2013.

Exemplos de cdigo
A maioria dos captulos do livro contm exerccios com os quais possvel testar inte-
rativamente a nova matria aprendida no livro. Todos os exemplos de projeto, tanto
em seus formatos anteriores como posteriores aos exerccios, podem ser baixados em:
www.grupoa.com.br
Cadastre-se gratuitamente no site, encontre a pgina do livro por meio do cam-
po de busca, acesse a pgina do livro e clique no link Contedo Online para fazer
download dos arquivos.

Nota Alm dos exemplos de cdigo, seu sistema deve ter o Visual Studio 2013
instalado. Se estiver disponvel, instale os pacotes de servio mais recentes para
Windows e Visual Studio.

Instale os exemplos de cdigo


Siga estes passos para instalar os exemplos de cdigo no computador a fim de us-los
com os exerccios do livro.
1. Faa download do arquivo 9780735681835.zip a partir da pgina do livro no site
www.grupoa.com.br
2. Descompacte na sua pasta Documentos (ou em um diretrio especfico, se pre-
ferir) o arquivo 9780735681835.zip que voc baixou.

Sharp_Visual_Iniciais.indd xxii 10/09/14 16:47


Introduo xxiii

Utilize os exemplos de cdigo


Todos os captulos explicam quando e como usar os exemplos de cdigo. Quando for
o momento de usar um exemplo de cdigo, o livro listar as instrues sobre como
abrir os arquivos.
Para quem gosta de conhecer todos os detalhes, segue uma lista dos projetos
e das solues do Visual Studio 2013 contendo exemplos de cdigo, agrupada pelas
pastas em que voc pode localiz-los. Em diversos casos, os exerccios fornecem ar-
quivos provisrios e verses completas dos mesmos projetos, que voc pode utilizar
como referncia. Os exemplos de cdigo fornecem verses para Window 7 e para
Windows 8.1, e as instrues dos exerccios salientam quaisquer diferenas nas tarefas
a serem executadas ou no cdigo que voc precisa escrever para esses dois sistemas
operacionais. Os projetos concludos de cada captulo so armazenados em pastas
com o sufixo - Complete.

Importante Se voc estiver utilizando Windows 8, Windows Server 2012 ou


Windows Server 2008 R2, siga as instrues para Windows 7. Se estiver utilizan-
do o Windows Server 2012 R2, siga as instrues para Windows 8.1.

Projeto Descrio
Captulo 1
TextHello Esse projeto o inicia nas atividades. Guia voc
passo a passo ao longo do processo de criao
de um programa simples que exibe uma
saudao baseada em texto.
WPFHello Exibe a saudao em uma janela, utilizando o
Windows Presentation Foundation (WPF).
Captulo 2
PrimitiveDataTypes Demonstra como declarar variveis de cada um
dos tipos primitivos, como atribuir valores a
essas variveis e como exibi-los em uma janela.
MathsOperators Apresenta os operadores aritmticos (+ * / %).
Captulo 3
Methods Reexamina o cdigo do projeto anterior e
investiga como so empregados os mtodos
para estruturar o cdigo.
DailyRate Ensina a escrever e executar seus prprios
mtodos e a inspecionar passo a passo as
chamadas de mtodo utilizando o depurador
do Visual Studio 2013.
DailyRate Using Optional Parameters Mostra como definir um mtodo que aceita
parmetros opcionais e como cham-lo por
meio de argumentos nomeados.

_Livro_Sharp_Visual.indb xxiii 30/06/14 15:02


xxiv Introduo

Projeto Descrio
Captulo 4
Selection Mostra como utilizar uma instruo if em
cascata para implementar uma lgica complexa,
como comparar a equivalncia de duas datas.
SwitchStatement Utiliza uma instruo switch para converter
caracteres em suas representaes XML.
Captulo 5
WhileStatement Demonstra uma instruo while que l o
contedo de cada linha de um arquivo-fonte
e o exibe em uma caixa de texto em um
formulrio.
DoStatement Esse projeto utiliza uma instruo do para
converter um nmero decimal em sua
representao octal.
Captulo 6
MathsOperators Revisita o projeto MathsOperators do Captulo
2 e mostra como vrias excees no tratadas
podem fazer o programa falhar. As palavras-
-chave try e catch tornam o aplicativo mais
robusto, evitando que ocorram mais falhas.
Captulo 7
Classes Aborda os fundamentos da definio de
suas prprias classes, incluindo construtores
pblicos, mtodos e campos privados. Alm
disso, mostra como criar instncias de classe
utilizando a palavra-chave new e como definir
mtodos e campos estticos.
Captulo 8
Parameters Investiga a diferena entre os parmetros
por valor e os parmetros por referncia.
Demonstra como utilizar as palavras-chave ref
e out.
Captulo 9
StructsAndEnums Define um tipo struct para representar uma
data de calendrio.
Captulo 10
Cards Mostra como utilizar arrays para modelar mos
de cartas em um jogo de baralho.
Captulo 11
ParamsArrays Demonstra como utilizar a palavra-chave
params para criar um nico mtodo que aceite
todos os argumentos int.

_Livro_Sharp_Visual.indb xxiv 30/06/14 15:02


Introduo xxv

Projeto Descrio
Captulo 12
Vehicles Cria uma hierarquia simples de classes de
veculos utilizando herana. Tambm demonstra
como definir um mtodo virtual.
ExtensionMethod Mostra como produzir um mtodo de extenso
para o tipo int, fornecendo um mtodo que
converte um valor inteiro de base 10 em uma
base numrica diferente.
Captulo 13
Drawing Using Interfaces Implementa parte de um pacote de desenho
grfico. O projeto utiliza interfaces para definir
os mtodos que as formas de desenho expem
e implementam.
Drawing Using Abstract Classes Estende o projeto Drawing Using Interfaces
para fatorar a funcionalidade comum de
objetos de forma em classes.
Captulo 14
GarbageCollectionDemo Mostra como implementar o descarte de
recursos seguro para excees, usando o
padro Dispose.
Captulo 15
Drawing Using Properties Estende o aplicativo do projeto Drawing Using
Abstract Classes, desenvolvido no Captulo 13,
para encapsular dados em uma classe usando
propriedades.
AutomaticProperties Mostra como criar propriedades automticas
para uma classe e utiliz-las para inicializar
instncias da classe.
Captulo 16
Indexers Utiliza dois indexadores: um procura o nmero
de telefone de uma pessoa quando um nome
fornecido e o outro procura o nome de uma
pessoa quando um nmero de telefone
fornecido.
Captulo 17
BinaryTree Mostra como empregar genricos para criar
uma estrutura typesafe que possa conter
elementos de qualquer tipo.
BuildTree Demonstra como utilizar genricos para
implementar um mtodo typesafe que possa
receber parmetros de qualquer tipo.

_Livro_Sharp_Visual.indb xxv 30/06/14 15:02


xxvi Introduo

Projeto Descrio
Captulo 18
Cards Atualiza o cdigo do Captulo 10 para mostrar
como usar colees para modelar mos de
cartas em um jogo de baralho.
Captulo 19
BinaryTree Mostra como implementar a interface genrica
IEnumerator<T> para criar um enumerador
para a classe genrica Tree.
IteratorBinaryTree Utiliza um iterador para gerar um enumerador
para a classe genrica Tree.
Captulo 20
Delegates Mostra como desacoplar um mtodo da
lgica do aplicativo que o chama, usando um
delegado.
Delegates With Event Mostra como usar um evento para alertar
um objeto sobre uma ocorrncia significativa
e como capturar um evento e realizar o
processamento necessrio.
Captulo 21
QueryBinaryTree Mostra como utilizar consultas LINQ para
recuperar dados de um objeto de rvore
binria.
Captulo 22
ComplexNumbers Define um novo tipo que modela nmeros
complexos e implementa operadores comuns
para esse tipo.
Captulo 23
GraphDemo Gera e exibe um grfico complexo em um
formulrio WPF. Utiliza um nico thread para
efetuar os clculos.
GraphDemo With Tasks Verso do projeto GraphDemo que cria vrias
tarefas para efetuar os clculos do grfico
simultaneamente.
Parallel GraphDemo Verso do projeto GraphDemo que usa a classe
Parallel para abstrair o processo de criao e
gerenciamento de tarefas.
GraphDemo With Cancellation Demonstra como implementar o cancelamento
para interromper tarefas de modo controlado,
antes de sua concluso.
ParallelLoop Fornece um exemplo de quando voc no deve
utilizar a classe Parallel para criar e executar
tarefas.

_Livro_Sharp_Visual.indb xxvi 30/06/14 15:02


Introduo xxvii

Projeto Descrio
Captulo 24
GraphDemo Verso do projeto GraphDemo do Captulo 23
que usa a palavra-chave async e o operador
await para efetuar os clculos que geram os
dados do grfico de forma assncrona.
PLINQ Apresenta alguns exemplos de como utilizar
PLINQ para consultar dados por meio de tarefas
paralelas.
CalculatePI Utiliza um algoritmo de amostragem estatstica
para calcular uma aproximao de pi. Usa
tarefas paralelas.
Captulo 25
Customers Without Scalable UI Utiliza o controle Grid padro para organizar
a interface do usurio do aplicativo Adventure
Works Customers. A interface utiliza
posicionamento absoluto para os controles e
no muda de escala para diferentes resolues
de tela e tamanhos fsicos.
Customers With Scalable UI Utiliza controles Grid aninhados com
definies de linha e coluna para permitir
seu posicionamento relativo. Essa verso da
interface do usurio muda de escala para
diferentes resolues de tela e tamanhos fsicos,
mas no se adapta bem ao modo de exibio
Snapped.
Customers With Adaptive UI Estende a verso com a interface do usurio
escalonvel. Utiliza o Visual State Manager para
detectar se o aplicativo est sendo executado
no modo de exibio Snapped e muda o layout
dos controles de forma correspondente.
Customers With Styles Verso do projeto Customers que utiliza estilos
XAML para mudar a fonte e a imagem de fundo
exibidas pelo aplicativo.
Captulo 26
DataBinding Utiliza vinculao de dados para exibir na
interface do usurio informaes de clientes
recuperadas de uma fonte de dados. Mostra
tambm como implementar a interface
INotifyPropertyChanged para que a interface
do usurio possa atualizar as informaes dos
clientes e enviar essas alteraes de volta para a
fonte de dados.
ViewModel Verso do projeto Customers que separa a
interface do usurio da lgica que acessa a
fonte de dados, implementando o padro
Model-View-ViewModel.

_Livro_Sharp_Visual.indb xxvii 30/06/14 15:02


xxviii Introduo

Projeto Descrio
Search Implementa o contrato Windows 8.1 Search. O
usurio pode procurar clientes pelo nome ou
pelo sobrenome.
Captulo 27
Web Service Contm um aplicativo web que fornece um
web service ASP.NET Web API, utilizado pelo
aplicativo Customers para recuperar dados de
clientes de um banco de dados SQL Server. O
web service utiliza um modelo de entidade
criado com o Entity Framework para acessar o
banco de dados.
Updatable ViewModel Nesta soluo, o projeto Customers contm
um ViewModel estendido com comandos
que permitem interface do usurio inserir e
atualizar informaes de clientes usando o WCF
Data Service.

Agradecimentos
Apesar de meu nome estar na capa, escrever um livro como este est longe de ser um
projeto solitrio. Gostaria de agradecer s seguintes pessoas que apoiaram e ajudaram
generosamente em todo este exerccio um tanto prolongado.
Primeiramente, Russell Jones, que foi o primeiro a me alertar sobre o iminente
lanamento das verses de pr-estreia do Windows 8.1 e do Visual Studio 2013. Ele
conseguiu acelerar todo o processo de envio desta edio do livro para a grfica. Sem
seus esforos talvez voc lesse este livro apenas quando a prxima edio de Windows
surgisse.
A seguir, Mike Sumsion e Paul Barnes, meus estimados colegas da Content Mas-
ter, que realizaram um excelente trabalho de reviso do material das verses originais
de cada captulo, testando meu cdigo e apontando os numerosos erros que eu havia
cometido! Acho que agora identifiquei todos eles, mas, claro, quaisquer erros que
restem so de minha inteira responsabilidade.
Alm disso, John Mueller, que fez um trabalho notvel e muito gil de reviso
tcnica desta edio. Sua experincia em escrita e conhecimento das tecnologias aqui
abordadas foram extremamente teis, enriquecendo esta obra.
Evidentemente, assim como muitos programadores, posso entender a tecnolo-
gia, mas meu texto nem sempre to fluente ou claro como poderia ser. Gostaria de
agradecer aos editores por corrigirem minha gramtica, meus erros ortogrficos e, de
modo geral, por tornarem meu material muito mais fcil de entender.
Por fim, gostaria de agradecer minha esposa e companheira de crquete, Dia-
na, por no franzir muito as sobrancelhas quando eu disse que comearia a trabalhar
em uma edio atualizada deste livro. Agora ela j se acostumou com meus murm-
rios raivosos enquanto depuro cdigo e com os numerosos oh que emito ao perce-
ber os erros crassos que cometi.

_Livro_Sharp_Visual.indb xxviii 30/06/14 15:02


Introduo xxix

Suporte tcnico
Todos os esforos foram feitos para garantir a exatido deste livro e do contedo
complementar que o acompanha. Caso queira fazer comentrios ou sugestes, tirar
dvidas ou reportar erros, escreva para secretariaeditorial@grupoa.com.br.

_Livro_Sharp_Visual.indb xxix 30/06/14 15:02


Esta pgina foi deixada em branco intencionalmente.

_Livro_Sharp_Visual.indb xxx 30/06/14 15:02


PARTE I

Introduo ao Microsoft
Visual C# e ao Microsoft
Visual Studio 2013
CAPTULO 1 Bem-vindo ao C# . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .3

CAPTULO 2 Variveis, operadores e expresses . . . . . . . . . . . . . . . . . . . . . . . . . . . . .39

CAPTULO 3 Como escrever mtodos e aplicar escopo . . . . . . . . . . . . . . . . . . . . . . .65

CAPTULO 4 Instrues de deciso . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .93

CAPTULO 5 Atribuio composta e instrues de iterao . . . . . . . . . . . . . . . . . 113

CAPTULO 6 Gerenciamento de erros e excees . . . . . . . . . . . . . . . . . . . . . . . . . . 134

Sharp_Visual_01.indd 1 30/06/14 17:02


Esta pgina foi deixada em branco intencionalmente.

Sharp_Visual_01.indd 2 30/06/14 17:02


CAPTULO 1

Bem-vindo ao C#
Neste captulo, voc vai aprender a:
j Utilizar o ambiente de programao do Microsoft Visual Studio 2013.
j Criar um aplicativo de console em C#.
j Explicar o objetivo dos namespaces.
j Criar um aplicativo grfico simples em C#.
Este captulo apresenta o Visual Studio 2013, o ambiente de programao, e o conjun-
to de ferramentas projetadas para criar aplicativos para o Microsoft Windows. O Visual
Studio 2013 a ferramenta ideal para escrever cdigo em C#, oferecendo muitos
recursos que voc vai conhecer medida que avanar neste livro. Neste captulo, voc
vai usar o Visual Studio 2013 para criar alguns aplicativos simples em C# e comear a
construir solues altamente funcionais para Windows.

Comece a programar com o ambiente do


Visual Studio 2013
O Visual Studio 2013 um ambiente de programao rico em recursos que contm a
funcionalidade necessria para criar projetos grandes ou pequenos em C# que funcio-
nam no Windows 7, no Windows 8 e no Windows 8.1. Voc pode inclusive construir
projetos que combinem mdulos de diferentes linguagens, como C++, Visual Basic e
F#. No primeiro exerccio, voc vai abrir o ambiente de programao do Visual Studio
2013 e aprender a criar um aplicativo de console.

Nota Um aplicativo de console executado em uma janela de prompt de co-


mando, em vez de fornecer uma interface grfica com o usurio (GUI).

Crie um aplicativo de console no Visual Studio 2013


j Se voc estiver utilizando Windows 8.1 ou Windows 8, na tela Iniciar, digite Vi-
sual Studio e, no painel Resultados da Pesquisa, clique em Visual Studio 2013.

Sharp_Visual_01.indd 3 30/06/14 17:02


4 PARTE I Introduo ao Microsoft Visual C# e ao Microsoft Visual Studio 2013

Nota No Windows 8 e no Windows 8.1, para encontrar um aplicativo,


voc pode digitar o nome dele literalmente (como Visual Studio) em qual-
quer parte em branco da tela Iniciar, longe de quaisquer tiles. O painel
Resultados da Pesquisa aparecer automaticamente.

O Visual Studio 2013 iniciado e apresenta a Pgina Iniciar (Start page), se-
melhante seguinte (sua Pgina Iniciar poder ser diferente, dependendo da
edio de Visual Studio 2013 que estiver usando).

Nota Se voc estiver usando o Visual Studio 2013 pela primeira vez, tal-
vez aparea uma caixa de dilogo solicitando a escolha das configuraes
de ambiente de desenvolvimento padro. O Visual Studio 2013 pode ser
personalizado de acordo com a sua linguagem de desenvolvimento pre-
ferida. As selees padro das diversas caixas de dilogo e ferramentas do
ambiente de desenvolvimento integrado (Integrated Development Envi-
ronment IDE) so definidas para a linguagem que voc escolher. Na lista,
selecione Visual C# Development Settings e clique no boto Start Visual
Studio. Aps alguns instantes, o IDE do Visual Studio 2013 aparecer.

j Se estiver usando o Windows 7, execute as seguintes operaes para iniciar o


Visual Studio 2013:
a. Na barra de tarefas do Windows, clique no boto Iniciar, clique em Todos os
Programas e, em seguida, clique no grupo de programas Microsoft Visual
Studio 2013.
b. No grupo de programas Microsoft Visual Studio 2013, clique em Visual Stu-
dio 2013.
O Visual Studio 2013 iniciado e apresenta a Pgina Iniciar.

Sharp_Visual_01.indd 4 30/06/14 17:02


CAPTULO 1 Bem-vindo ao C# 5

Nota Para no ser repetitivo e economizar espao, escreverei apenas


Inicie o Visual Studio quando voc precisar abrir o Visual Studio 2013,
independentemente do sistema operacional que esteja usando.

j Siga estes passos para criar um novo aplicativo de console.


a. No menu File, aponte para New e ento clique em Project.
A caixa de dilogo New Project se abre. Ela lista os templates que voc
pode utilizar como ponto de partida para construir um aplicativo. A
caixa de dilogo categoriza os templates de acordo com a linguagem
de programao que voc est utilizando e o tipo de aplicativo.
b. No painel esquerda, na seo Templates, clique em Visual C#. No painel
central, verifique se a caixa de combinao posicionada no incio do painel
exibe o texto .NET Framework 4.5 e depois clique no cone Console Applica-
tion.

c. Na caixa Location, digite C:\Users\SeuNome\Documents\Microsoft


Press\Visual CSharp Step By Step\Chapter 1. Substitua o texto SeuNome
nesse caminho pelo seu nome de usurio do Windows.

Sharp_Visual_01.indd 5 30/06/14 17:02


6 PARTE I Introduo ao Microsoft Visual C# e ao Microsoft Visual Studio 2013

Nota Para no ser repetitivo e economizar espao, no restante deste livro


vou me referir ao caminho C:\Users\SeuNome\Documentos simplesmente
como sua pasta Documentos.
Dica Se a pasta especificada no existir, o Visual Studio 2013 criar uma
nova para voc.

d. Na caixa Name, digite TestHello (digite sobre o nome existente, Console-


Application1).
e. Certifique-se de que a caixa de seleo Create Directory For Solution est
selecionada e clique em OK.
O Visual Studio cria o projeto utilizando o template Console Application e exibe
o cdigo bsico para o projeto, como na ilustrao:

A barra de menus na parte superior da tela fornece acesso aos recursos que voc
utilizar no ambiente de programao. Voc pode usar o teclado ou o mouse
para acessar os menus e os comandos, exatamente como faz em todos os pro-
gramas baseados em Windows. A barra de ferramentas est localizada abaixo
da barra de menus. Ela oferece botes de atalho para executar os comandos
utilizados com mais frequncia.
A janela Code and Text Editor, que ocupa a parte principal da tela, exibe o con-
tedo dos arquivos-fonte. Em um projeto com vrios arquivos, quando voc edi-
ta mais de um deles, cada arquivo-fonte tem uma guia prpria com seu nome.
Voc pode clicar na guia para trazer o arquivo-fonte nomeado para o primeiro
plano na janela Code and Text Editor.
O painel Solution Explorer aparece no lado direito da caixa de dilogo:

Sharp_Visual_01.indd 6 30/06/14 17:02


CAPTULO 1 Bem-vindo ao C# 7

O Solution Explorer exibe os nomes dos arquivos associados ao projeto, entre


outros itens. Voc pode clicar duas vezes em um nome de arquivo no painel
Solution Explorer para trazer esse arquivo-fonte para o primeiro plano na janela
do Code and Text Editor.
Antes de escrever o cdigo, examine os arquivos listados no Solution Explorer,
criados pelo Visual Studio 2013 como parte do seu projeto:
j Solution TestHello o arquivo de soluo de nvel superior. Cada aplicativo
contm apenas um arquivo de soluo. Uma soluo pode conter um ou mais
projetos; o Visual Studio 2013 cria o arquivo de soluo para ajudar a organizar
esses projetos. Se utilizar o Windows Explorer para examinar a pasta Documen-
tos\Microsoft Press\Visual CSharp Step By Step\Chapter 1\TestHello, voc ver
que o nome real desse arquivo TestHello.sln.
j TestHello o arquivo de projeto do C#. Cada arquivo de projeto faz referncia
a um ou mais arquivos que contm o cdigo-fonte e outros artefatos do projeto,
como imagens grficas. Todos os cdigos-fonte de um mesmo projeto devem ser
escritos na mesma linguagem de programao. No Windows Explorer, esse arqui-
vo se chama TestHello.csproj e est armazenado na pasta \Microsoft Press\Visual
CSharp Step By Step\Chapter 1\TestHello\TestHello em sua pasta Documentos.
j Properties uma pasta do projeto TestHello. Se for expandida (clique na seta
ao lado de Properties), voc ver que ela contm um arquivo chamado Assem-
blyInfo.cs. Esse um arquivo especial que voc pode utilizar para adicionar atri-
butos a um programa, como o nome do autor, a data em que o programa foi
escrito, etc. Voc pode especificar atributos adicionais para modificar a maneira
como o programa executado. Explicar como esses atributos so utilizados est
alm dos objetivos deste livro.
j References Essa pasta contm as referncias s bibliotecas de cdigo compi-
lado que seu aplicativo pode utilizar. Quando o cdigo C# compilado, ele
convertido em uma biblioteca e recebe um nome exclusivo. No Microsoft .NET
Framework, essas bibliotecas so chamadas assemblies. Desenvolvedores utilizam
assemblies para empacotar funcionalidade til que escreveram, podendo distri-

Sharp_Visual_01.indd 7 30/06/14 17:02


8 PARTE I Introduo ao Microsoft Visual C# e ao Microsoft Visual Studio 2013

bu-los para outros desenvolvedores que queiram utilizar esses recursos nos seus
aplicativos. Se voc expandir a pasta References, ver o conjunto de referncias
padro adicionado em seu projeto pelo Visual Studio 2013. Esses assemblies do
acesso a muitos dos recursos normalmente utilizados do .NET Framework e so
fornecidos pela Microsoft com o Visual Studio 2013. Voc vai aprender sobre
muitos desses assemblies medida que avanar nos exerccios do livro.
j App.config o arquivo de configurao de aplicativo. Ele opcional e poder
no estar presente todas as vezes. possvel especificar, durante a execuo, as
configuraes que seu aplicativo pode utilizar para modificar seu comportamen-
to, como a verso do .NET Framework a ser utilizada para executar o aplicativo.
Voc vai aprender mais sobre esse arquivo nos captulos posteriores deste livro.
j Program.cs um arquivo-fonte do C# exibido na janela Code and Text Edi-
tor quando o projeto criado. Voc escrever seu cdigo para o aplicativo de
console nesse arquivo. Ele contm um cdigo que o Visual Studio 2013 fornece
automaticamente, o qual ser examinado a seguir.

Escreva seu primeiro programa


O arquivo Program.cs define uma classe chamada Program que contm um mto-
do chamado Main. Em C#, todo cdigo executvel deve ser definido dentro de um
mtodo e todos os mtodos devem pertencer a uma classe ou a uma estrutura. Voc
aprender mais sobre classes no Captulo 7, Criao e gerenciamento de classes e
objetos, e sobre estruturas, no Captulo 9, Como criar tipos-valor com enumeraes
e estruturas.
O mtodo Main designa o ponto de entrada do programa. Ele deve ser definido
como um mtodo esttico, da maneira especificada na classe Program; caso contrrio,
o .NET Framework poder no reconhec-lo como ponto de partida de seu aplicativo,
quando for executado. (Veremos mtodos em detalhes no Captulo 3, Como escrever
mtodos e aplicar escopo, e o Captulo 7 fornece mais informaes sobre os mtodos
estticos.)

Importante O C# uma linguagem que diferencia maisculas de minsculas:


Voc deve escrever Main com M maisculo.

Nos exerccios a seguir, voc vai escrever um cdigo para exibir a mensagem
Hello World! na janela do console, vai compilar e executar seu aplicativo de console
Hello World e vai aprender como os namespaces so utilizados para dividir elementos
do cdigo.

Escreva o cdigo utilizando o Microsoft IntelliSense


1. Na janela Code and Text Editor que exibe o arquivo Program.cs, coloque o cursor
no mtodo Main logo aps a chave de abertura, {, e pressione Enter para criar
uma nova linha.

Sharp_Visual_01.indd 8 30/06/14 17:02


CAPTULO 1 Bem-vindo ao C# 9

2. Nessa nova linha, digite a palavra Console; esse o nome de outra classe forne-
cida pelos assemblies referenciados por seu aplicativo. Ela fornece os mtodos
para exibir mensagens na janela do console e ler entradas a partir do teclado.
Ao digitar a letra C no incio da palavra Console, uma lista IntelliSense aparecer.

Essa lista contm todas as palavras-chave vlidas do C# e os tipos de dados v-


lidos nesse contexto. Voc pode continuar digitando ou rolar pela lista e clicar
duas vezes no item Console com o mouse. Como alternativa, depois de digitar
Cons, a lista IntelliSense focalizar automaticamente o item Console e voc po-
der pressionar as teclas Tab ou Enter para selecion-lo.
Main deve se parecer com isto:
static void Main(string[] args)
{
Console
}

Nota Console uma classe interna.

3. Digite um ponto logo aps Console.


Outra lista IntelliSense aparece, exibindo os mtodos, propriedades e campos da
classe Console.
4. Role para baixo pela lista, selecione WriteLine e ento pressione Enter. Voc tam-
bm pode continuar a digitar os caracteres W, r, i, t, e, L, at WriteLine estar
selecionado e ento pressionar Enter.
A lista IntelliSense fechada e a palavra WriteLine adicionada ao arquivo-
-fonte. Main deve se parecer com isto:
static void Main(string[] args)
{
Console.WriteLine
}

Sharp_Visual_01.indd 9 30/06/14 17:02


10 PARTE I Introduo ao Microsoft Visual C# e ao Microsoft Visual Studio 2013

5. Digite um parntese de abertura, (. Outra dica do IntelliSense aparece.


Essa dica exibe os parmetros que o mtodo WriteLine pode receber. De fato,
WriteLine um mtodo sobrecarregado, ou seja, a classe Console contm mais de
um mtodo chamado WriteLine na verdade ela fornece 19 verses diferentes
desse mtodo. Cada verso do mtodo WriteLine pode ser utilizada para emitir
diferentes tipos de dados. (O Captulo 3 descreve mtodos sobrecarregados em
mais detalhes.) Main deve se parecer com isto:
static void Main(string[] args)
{
Console.WriteLine(
}

Dica Voc pode clicar nas setas para cima e para baixo na dica para rolar
pelas diferentes sobrecargas de WriteLine.

6. Digite um parntese de fechamento, ), seguido por um ponto e vrgula, ;.


Main deve se parecer com isto:
static void Main(string[] args)
{
Console.WriteLine();
}

7. Mova o cursor e digite a string Hello World!, incluindo as aspas, entre os pa-
rnteses esquerdo e direito depois do mtodo WriteLine.
Main deve se parecer com isto:
static void Main(string[] args)
{
Console.WriteLine("Hello World!");
}

Dica Adquira o hbito de digitar pares de caracteres correspondentes,


como parnteses ( e ) e chaves { e }, antes de preencher seus contedos.
fcil esquecer o caractere de fechamento se voc esperar para digit-lo
depois de inserir o contedo.

Sharp_Visual_01.indd 10 30/06/14 17:02


CAPTULO 1 Bem-vindo ao C# 11

cones IntelliSense
Quando voc digita um ponto depois do nome de uma classe, o IntelliSense exibe o
nome de cada membro dessa classe. esquerda de cada nome de membro h um
cone que representa o tipo de membro. Os cones mais comuns e seus tipos so:

cone Significado

Mtodo (Captulo 3)

Propriedade (Captulo 15, Implementao de propriedades para acessar campos)

Classe (Captulo 7)

Estrutura (Captulo 9)

Enumerao (Captulo 9)

Mtodo de extenso (Captulo 12)

Interface (Captulo 13, Como criar interfaces e definir classes abstratas)

Delegado (Captulo 17, Genricos)

Evento (Captulo 17)

Namespace (prxima seo deste captulo)

Outros cones IntelliSense aparecero medida que voc digitar o cdigo em


contextos diferentes.

Muitas vezes, voc ver linhas de cdigo contendo duas barras (//) seguidas por
um texto comum. Esses so comentrios ignorados pelo compilador, mas muito teis
para os desenvolvedores, porque ajudam a documentar o que um programa est fa-
zendo. Considere o seguinte exemplo:
Console.ReadLine(); // Espera o usurio pressionar a tecla Enter

O compilador pula todo o texto desde as duas barras at o fim da linha. Voc
tambm pode adicionar comentrios de vrias linhas, que iniciam com uma barra nor-
mal seguida por um asterisco (/*). O compilador pula tudo at localizar um asterisco
seguido por barra normal (*/), que pode estar vrias linhas abaixo. um estmulo para
documentar seu cdigo com o maior nmero possvel de comentrios significativos.

Compile e execute o aplicativo de console


1. No menu Build, clique em Build Solution.

Sharp_Visual_01.indd 11 30/06/14 17:02


12 PARTE I Introduo ao Microsoft Visual C# e ao Microsoft Visual Studio 2013

Essa ao compila o cdigo C#, resultando em um programa que pode ser exe-
cutado. A janela Output aparece abaixo da janela Code and Text Editor.

Dica Se a janela Output no aparecer no menu View, clique em Output para


exibi-la.

Nessa janela, voc deve ver mensagens semelhantes s seguintes, indicando


como o programa est sendo compilado.
1>------ Build started: Project: TestHello, Configuration: Debug Any CPU ------
1> TestHello -> C:\Users\John\Documents\Microsoft Press\Visual CSharp Step By
Step\Chapter
1\TestHello\TestHello\bin\Debug\TestHello.exe
========== Build: 1 succeeded, 0 failed, 0 up-to-date, 0 skipped ==========

Qualquer erro que voc cometer aparecer na janela Error List. A imagem a se-
guir mostra o que acontece se voc esquecer de digitar as aspas de fechamento
depois do texto Hello World na instruo WriteLine. Observe que um nico erro
s vezes pode causar vrios erros de compilador.

Sharp_Visual_01.indd 12 30/06/14 17:02


CAPTULO 1 Bem-vindo ao C# 13

Dica Para ir diretamente linha que causou o erro, clique duas vezes em um
item na janela Error List. Observe tambm que o Visual Studio exibe uma linha
vermelha ondulada sob qualquer linha de cdigo que no ser compilada quan-
do voc a inserir.

Se voc seguiu as instrues anteriores cuidadosamente, no haver erro ou


aviso algum, e o programa dever ser compilado com sucesso.

Dica No h necessidade de salvar o arquivo explicitamente antes de compil-


-lo, porque o comando Build Solution o salva automaticamente.
Um asterisco aps o nome do arquivo na guia acima da janela Code and Text
Editor indica que o arquivo foi alterado aps ter sido salvo pela ltima vez.

2. No menu Debug, clique em Start Without Debugging.


Uma janela de comandos aberta e o programa executado. A mensagem
Hello World! exibida; o programa espera o usurio pressionar uma tecla,
como mostra a ilustrao a seguir:

Nota O prompt Press any key to continue gerado pelo Visual Studio sem
que voc tenha escrito cdigo para fazer isso. Se executar o programa utilizando
o comando Start Debugging no menu Debug, o aplicativo ser executado, mas
a janela de comando fechar imediatamente sem esperar que voc pressione
uma tecla.

3. Verifique se a janela de comandos que exibe a sada do programa tem o foco


(significando que a janela correntemente ativa) e, em seguida, pressione Enter.
A janela de comandos fechada e voc retorna ao ambiente de programao
do Visual Studio 2013.
4. No Solution Explorer, clique no projeto TestHello (no na soluo) e depois, na
barra de ferramentas do Solution Explorer, clique no boto Show All Files. Ob-
serve que, para fazer esse boto aparecer, talvez seja necessrio clicar no boto
na margem direita da barra de ferramentas Solution Explorer.

Sharp_Visual_01.indd 13 30/06/14 17:02


14 PARTE I Introduo ao Microsoft Visual C# e ao Microsoft Visual Studio 2013

>>Boto
Show All Files

Entradas chamadas bin e obj aparecem acima do arquivo Program.cs. Essas en-
tradas correspondem diretamente s pastas chamadas bin e obj na pasta do pro-
jeto (Microsoft Press\ VisualCSharp Step By Step\Chapter 1\TestHello\TestHello).
O Visual Studio as cria quando voc compila seu aplicativo; elas contm a verso
executvel do programa e alguns outros arquivos utilizados para compilar e de-
purar o aplicativo.
5. No Solution Explorer, expanda a entrada bin.
Outra pasta chamada Debug exibida.

Nota Voc tambm poder ver uma pasta chamada Release.

6. No Solution Explorer, expanda a pasta Debug.


Aparecem diversos outros itens, incluindo um arquivo chamado TestHello.exe.
Esse o programa compilado, o qual o arquivo executado quando voc clica
em Start Without Debugging no menu Debug. Os outros dois arquivos con-
tm informaes que so utilizadas pelo Visual Studio 2013, se voc executar o
programa no modo de depurao (quando voc clica em Start Debugging no
menu Debug).

Namespaces
O exemplo que vimos at aqui o de um programa muito pequeno. Mas programas
pequenos podem crescer bastante. medida que o programa se desenvolve, duas
questes surgem. Primeiro, mais difcil entender e manter programas grandes do
que programas menores. Segundo, mais cdigo normalmente significa mais classes,

Sharp_Visual_01.indd 14 30/06/14 17:02


CAPTULO 1 Bem-vindo ao C# 15

com mais mtodos, exigindo o acompanhamento de mais nomes. Conforme o nme-


ro de nomes aumenta, tambm aumenta a probabilidade de a compilao do projeto
falhar porque dois ou mais nomes entram em conflito; por exemplo, voc poderia criar
duas classes com o mesmo nome. A situao se torna mais complicada quando um
programa faz referncia a assemblies escritos por outros desenvolvedores que tam-
bm utilizaram uma variedade de nomes.
Antigamente, os programadores tentavam resolver o conflito prefixando os no-
mes com algum tipo de qualificador (ou conjunto de qualificadores). Essa no uma
boa soluo, pois no expansvel; os nomes tornam-se maiores, e voc gasta menos
tempo escrevendo o software e mais tempo digitando (h uma diferena), e lendo e
relendo nomes longos e incompreensveis.
Os namespaces ajudam a resolver esse problema criando um continer para
itens, como classes. Duas classes com o mesmo nome no sero confundidas se elas
estiverem em namespaces diferentes. Voc pode criar uma classe chamada Greeting
em um namespace chamado TestHello, utilizando a palavra-chave namespace, como
mostrado a seguir:
namespace TestHello
{
class Greeting
{
...
}
}

Voc pode ento referenciar a classe Greeting como TestHello.Greeting em seus


programas. Se outro desenvolvedor tambm criar uma classe Greeting em um names-
pace diferente, como NewNamespace, e voc instalar o assembly que contm essa
classe no seu computador, seus programas ainda funcionaro conforme o esperado,
pois usaro a classe TestHello.Greeting. Se quiser referenciar a classe Greeting do outro
desenvolvedor, voc dever especific-la como NewNamespace.Greeting.
uma boa prtica definir todas as suas classes em namespaces, e o ambiente do
Visual Studio 2013 segue essa recomendao utilizando o nome do seu projeto como
o namespace de nvel mais alto. A biblioteca de classes do .NET Framework tambm
segue essa recomendao: toda classe no .NET Framework est situada em um names-
pace. Por exemplo, a classe Console reside no namespace System. Isso significa que seu
nome completo , na verdade, System.Console.
Porm, se voc tivesse que escrever o nome completo de uma classe sempre que
ela fosse utilizada, seria melhor prefixar qualificadores ou ento atribuir classe um
nome globalmente nico, como SystemConsole. Felizmente, possvel resolver esse
problema com uma diretiva using nos seus programas. Se voc retornar ao programa
TestHello no Visual Studio 2013 e examinar o arquivo Program.cs na janela Code and
Text Editor, notar as seguintes linhas no incio do arquivo:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

Sharp_Visual_01.indd 15 30/06/14 17:02


16 PARTE I Introduo ao Microsoft Visual C# e ao Microsoft Visual Studio 2013

Essas linhas so diretivas using. Uma diretiva using adiciona um namespace ao


escopo. No cdigo subsequente, no mesmo arquivo, voc no precisa mais qualifi-
car explicitamente os objetos com o namespace ao qual eles pertencem. Os cinco
namespaces mostrados contm classes utilizadas com tanta frequncia que o Visual
Studio 2013 adiciona essas instrues using automaticamente toda vez que voc cria
um novo projeto. Voc pode adicionar outras diretivas using no incio de um arquivo-
-fonte, caso precise referenciar outros namespaces.
O exerccio a seguir demonstra o conceito dos namespaces com mais detalhes.

Experimente os nomes longos


1. Na janela Code and Text Editor que exibe o arquivo Program.cs, transforme em
comentrio a primeira diretiva using na parte superior do arquivo, desta maneira:
//using System;

2. No menu Build, clique em Build Solution.


A compilao falha e a janela Error List exibe a seguinte mensagem de erro:
The name 'Console' does not exist in the current context.

3. Na janela Error List, clique duas vezes na mensagem de erro.


O identificador que causou o erro destacado no arquivo-fonte Program.cs.
4. Na janela Code and Text Editor, edite o mtodo Main para utilizar o nome com-
pleto System.Console.
Main deve se parecer com isto:
static void Main(string[] args)
{
System.Console.WriteLine("Hello World!");
}

Nota Quando voc digita o ponto final aps System, os nomes de todos os
itens no namespace System so exibidos pelo IntelliSense.

5. No menu Build, clique em Build Solution.


A compilao do projeto deve ser bem-sucedida desta vez. Se no for, certifi-
que-se de que o cdigo Main est exatamente como aparece no cdigo prece-
dente e, em seguida, tente recompilar outra vez.
6. Execute o aplicativo para verificar se ele ainda funciona, clicando em Start Wi-
thout Debugging no menu Debug.
7. Depois que o programa for executado e exibir Hello World!, na janela do con-
sole, pressione Enter para retornar ao Visual Studio 2013.

Sharp_Visual_01.indd 16 30/06/14 17:02


CAPTULO 1 Bem-vindo ao C# 17

Namespaces e assemblies
Uma diretiva using coloca em escopo os itens de um namespace, e voc no pre-
cisa qualificar completamente os nomes das classes no seu cdigo. As classes so
compiladas em assemblies. Um assembly um arquivo que tem, em geral, a ex-
tenso de nome de arquivo .dll, embora programas executveis com a extenso de
nome de arquivo .exe tambm sejam assemblies.
Um assembly pode conter muitas classes. As classes de biblioteca abrangidas
pela biblioteca de classes do .NET Framework, como System.Console, so fornecidas
nos assemblies instalados no seu computador junto com o Visual Studio. Voc des-
cobrir que a biblioteca de classes do .NET Framework contm milhares de classes.
Se todas fossem armazenadas nos mesmos assemblies, estes seriam enormes e dif-
ceis de manter. (Se a Microsoft atualizasse um nico mtodo em uma nica classe,
ela teria de distribuir toda a biblioteca de classes a todos os desenvolvedores!)
Por essa razo, a biblioteca de classes do .NET Framework dividida em al-
guns assemblies, agrupados de acordo com a rea funcional a que as classes esto
relacionadas. Por exemplo, um assembly bsico (na verdade, chamado mscorlib.
dll) contm todas as classes comuns, como System.Console, e outros assemblies
contm classes para manipular bancos de dados, acessar web services, compilar
GUIs e assim por diante. Se quiser utilizar uma classe em um assembly, voc deve
adicionar ao seu projeto uma referncia a ele. Ento, pode adicionar instrues
using ao seu cdigo, colocando em escopo os itens do namespace nesse assembly.
Observe que no h necessariamente uma equivalncia 1:1 entre um as-
sembly e um namespace. Um nico assembly pode conter classes definidas para
muitos namespaces e um nico namespace pode abranger vrios assemblies. Por
exemplo, as classes e itens do namespace System so, na verdade, implementados
por vrios assemblies, incluindo mscorlib.dll, System.dll e System.Core.dll, dentre
outros. Isso parece muito confuso agora, mas voc logo ir se acostumar.
Ao utilizar o Visual Studio para criar um aplicativo, o template que voc se-
leciona inclui automaticamente referncias aos assemblies adequados. Por exem-
plo, no Solution Explorer do projeto TestHello, expanda a pasta References. Voc
ver que um aplicativo de console contm automaticamente referncias a assem-
blies chamados Microsoft.CSharp, System, System.Core, System.Data, System.Data.
DataExtensions, System.Xml e System.Xml.Linq. Talvez voc fique surpreso ao ver
que mscorlib.dll no est nessa lista. Isso acontece porque todos os aplicativos do
.NET Framework devem usar esse assembly, pois ele contm a funcionalidade de
tempo de execuo fundamental. A pasta References lista somente os assemblies
opcionais; possvel adicionar ou remover assemblies dessa pasta, conforme for
necessrio.
Para acrescentar referncias para assemblies adicionais em um projeto, clique
com o boto direito do mouse na pasta References e ento, no menu de atalho
que aparece, clique em Add Reference voc far isso nos prximos exerccios.
Voc tambm pode remover um assembly, clicando nele com o boto direito do
mouse na pasta References e, ento, clicando em Remove.

Sharp_Visual_01.indd 17 30/06/14 17:02


18 PARTE I Introduo ao Microsoft Visual C# e ao Microsoft Visual Studio 2013

Crie um aplicativo grfico


At aqui, voc usou o Visual Studio 2013 para criar e executar um aplicativo de con-
sole bsico. O ambiente de programao do Visual Studio 2013 tambm contm tudo
que voc precisa para criar aplicativos grficos para Windows 7, Windows 8 e Windows
8.1. Voc pode projetar a interface de usurio (IU) de um aplicativo para Windows de
modo interativo. O Visual Studio 2013 ento gera as instrues do programa para
implementar a interface de usurio que voc projetou.
O Visual Studio 2013 fornece duas visualizaes de um aplicativo grfico: a vi-
sualizao de projeto (design view) e a visualizao de cdigo (code view). Utilize a
janela Code and Text Editor para modificar e manter o cdigo e a lgica do programa
para um aplicativo grfico, e a janela Design View para organizar sua interface do
usurio. Voc pode alternar entre as duas visualizaes sempre que quiser.
Nos exerccios a seguir, voc aprender a criar um aplicativo grfico utilizando o
Visual Studio 2013. Esse programa exibe um formulrio simples, contendo uma caixa
de texto em que voc pode inserir seu nome e um boto que, quando clicado, exibe
uma saudao personalizada.

Importante No Windows 7 e no Windows 8, O Visual Studio 2013 fornece


dois templates para compilar aplicativos grficos: o template Windows Forms
Application e o template WPF Application. Windows Forms uma tecnologia
que surgiu no .NET Framework verso 1.0. O WPF, ou Windows Presentation
Foundation, uma tecnologia aprimorada que apareceu na verso 3.0 do .NET
Framework. O WPF oferece muitos recursos adicionais em relao ao Windows
Forms, e voc deve considerar o seu uso no lugar do Windows Forms para todos
os novos desenvolvimentos para Windows 7.
Tambm possvel compilar aplicativos Windows Forms e WPF no Windows 8.1.
Contudo, o Windows 8 e o Windows 8.1 oferecem um novo tipo de interface
do usurio, denominado estilo Windows Store. Os aplicativos que utilizam esse
estilo de interface so chamados aplicativos Windows Store. O Windows 8 foi
projetado para funcionar em uma variedade de hardware, incluindo computado-
res com telas sensveis ao toque e tablets ou slates. Esses computadores permi-
tem aos usurios interagir com os aplicativos por meio de gestos baseados em
toques por exemplo, os usurios podem passar o dedo nos aplicativos para
mov-los na tela e gir-los ou apertar e alongar aplicativos para diminu-los e
ampli-los novamente. Alm disso, muitos tablets contm sensores que detectam
a orientao do dispositivo, e o Windows 8 pode passar essa informao para
um aplicativo, o qual pode ento ajustar a interface do usurio dinamicamente,
de acordo com a orientao (pode trocar do modo paisagem para retrato, por
exemplo). Se voc tiver instalado o Visual Studio 2013 em um computador Win-
dows 8.1, receber um conjunto adicional de templates para compilar aplicativos
Windows Store. Contudo, esses templates dependem dos recursos fornecidos pelo
Windows 8.1; portanto, se voc estiver usando o Windows 8, os templates do Win-
dows Store no estaro disponveis.

Sharp_Visual_01.indd 18 30/06/14 17:02


CAPTULO 1 Bem-vindo ao C# 19

Para satisfazer os desenvolvedores de Windows 7, de Windows 8 e de Windows


8.1, em muitos dos exerccios, forneci instrues para uso dos templates WPF. Se
estiver usando o Windows 7 ou o Windows 8, voc dever seguir as instrues do
Windows 7. Se quiser usar o estilo de interface de usurio Windows Store, voc
deve seguir as instrues do Windows 8.1. Evidentemente, voc pode seguir as
instrues para Windows 7 e para Windows 8 para usar os templates WPF no
Windows 8.1, se preferir.
Caso queira mais informaes sobre os pormenores de como escrever aplicativos
para Windows 8.1, os captulos finais da Parte IV deste livro fornecem mais deta-
lhes e orientaes.

Crie um aplicativo grfico no Visual Studio 2013


j Se estiver usando o Windows 8.1, execute as seguintes operaes para criar um
novo aplicativo grfico:
a. Inicie o Visual Studio 2013, se ele ainda no estiver em execuo.
b. No menu File, aponte para New e ento clique em Project.
A caixa de dilogo New Project se abre.
c. No painel da esquerda, na seo Installed Templates, expanda Visual C# (se
ainda no estiver expandido) e ento clique na pasta Windows Store.
d. No painel central, clique no cone Blank App (XAML).

Nota XAML significa Extensible Application Markup Language, que a lingua-


gem utilizada por aplicativos Windows Store para definir o layout de sua GUI.
Voc vai aprender mais sobre XAML medida que avanar nos exerccios do
livro.

e. Certifique-se de que o campo Location refere-se pasta \Microsoft Press\


Visual CSharp Step By Step\Chapter 1, na pasta Documentos.
f. Na caixa Name, digite Hello.
g. Na caixa Solution, assegure-se de que Create New Solution est selecionado.
Essa ao cria uma nova soluo para armazenar o projeto. A alterna-
tiva Add To Solution adiciona o projeto soluo TestHello, mas no
isso que voc quer para este exerccio.
h. Clique em OK.
Se essa for a primeira vez que voc criou um aplicativo Windows Store,
ser solicitado a apresentar uma licena de desenvolvedor. Voc deve
concordar com os termos e condies indicados na caixa de dilogo,

Sharp_Visual_01.indd 19 30/06/14 17:02


20 PARTE I Introduo ao Microsoft Visual C# e ao Microsoft Visual Studio 2013

antes de continuar a compilar aplicativos Windows Store. Se estiver


de acordo com essas condies, clique em I Agree, como mostrado
na ilustrao a seguir. Ser solicitado que voc entre no Windows Live
(nesse ponto, possvel criar uma nova conta, se necessrio) e uma
licena de desenvolvedor ser criada e reservada para voc.

i. Aps a criao do aplicativo, examine a janela Solution Explorer.


No se engane com o nome do template de aplicativo embora seja
chamado Blank App, na verdade esse template fornece vrios arqui-
vos e contm algum cdigo. Por exemplo, se voc expandir a pasta
MainPage.xaml, encontrar um arquivo C# chamado MainPage.xaml.
cs. Esse arquivo onde voc insere o cdigo executado quando a in-
terface do usurio definida pelo arquivo MainPage.xaml exibida.
j. No Solution Explorer, clique duas vezes em MainPage.xaml.
Esse arquivo contm o layout da interface do usurio. A janela Design
View mostra duas representaes desse arquivo:
Na parte superior est uma visualizao grfica representando a tela
de um computador tablet. O painel inferior contm uma descrio do
contedo dessa tela em XAML. XAML uma linguagem tipo XML utili-
zada por aplicativos Windows Store e WPF para definir o layout de um
formulrio e seu contedo. Se voc conhece XML, a XAML dever lhe
parecer familiar.
No prximo exerccio, voc vai usar a janela Design View para organi-
zar a interface do usurio do aplicativo e vai examinar o cdigo XAML
gerado por esse layout.

Sharp_Visual_01.indd 20 30/06/14 17:02


CAPTULO 1 Bem-vindo ao C# 21

j Se estiver usando o Windows 8 ou o Windows 7, execute as seguintes tarefas:


a. Inicie o Visual Studio 2013, se ele ainda no estiver em execuo.
b. No menu File, aponte para New e ento clique em Project.
A caixa de dilogo New Project se abre.
c. No painel da esquerda, na seo Installed Templates, expanda Visual C# (se
ainda no estiver expandido) e ento clique na pasta Windows.
d. No painel central, clique no cone WPF Application.
e. Certifique-se de que a caixa Location refere-se pasta \Microsoft Press\Vi-
sual CSharp Step By Step\Chapter 1, na pasta Documentos.
f. Na caixa Name, digite Hello.
g. Na caixa Solution, assegure-se de que Create New Solution est selecionado
e clique em OK.
O template WPF Application gera menos itens do que o template Win-
dows Store Blank App; ele no contm os estilos gerados pelo tem-
plate Blank App, pois a funcionalidade incorporada nesses estilos
especfica para o Windows 8.1. Contudo, o template WPF Application
gera uma janela padro para seu aplicativo. Como em um aplicativo
Windows Store, essa janela definida com XAML, mas, neste caso,
chamada MainWindow.xaml por padro.

Sharp_Visual_01.indd 21 30/06/14 17:02


22 PARTE I Introduo ao Microsoft Visual C# e ao Microsoft Visual Studio 2013

h. No Solution Explorer, clique duas vezes em MainWindow.xaml para exibir o


contedo desse arquivo na janela Design View.

Dica Feche as janelas Output e Error List para dar mais espao exibio da
janela Design View.
Nota Antes de prosseguirmos, importante explicarmos alguma terminologia.
Em um aplicativo WPF tpico, a interface do usurio consiste em uma ou mais ja-
nelas, mas em um aplicativo Windows Store os itens correspondentes so chama-
dos de pginas (rigorosamente falando, um aplicativo WPF tambm pode conter
pginas, mas no quero confundir as coisas neste ponto). Para no ficar repetindo
a frase bastante prolixa janela WPF ou pgina de aplicativo Windows Store no
livro, vou simplesmente me referir aos dois itens usando o termo geral formulrio.
Entretanto, continuarei usando a palavra janela para me referir aos itens do IDE
do Visual Studio 2013, como a janela Design View.

Nos prximos exerccios, voc vai utilizar a janela Design View para adicionar trs
controles ao formulrio exibido por seu aplicativo e examinar alguns dos cdigos C#
gerados automaticamente pelo Visual Studio 2013 para implementar esses controles.

Sharp_Visual_01.indd 22 30/06/14 17:02


CAPTULO 1 Bem-vindo ao C# 23

Nota Os passos dos prximos exerccios so comuns para o Windows 7, para o


Windows 8 e para o Windows 8.1, exceto onde quaisquer diferenas sejam expli-
citamente indicadas.

Crie a interface do usurio


1. Clique na guia Toolbox exibida esquerda do formulrio na janela Design View.
A Toolbox aparece, ocultando parcialmente o formulrio, e exibe os vrios com-
ponentes e controles que voc pode colocar em um formulrio.
2. Se estiver utilizando o Windows 8.1, expanda a seo Common XAML Controls.
Se estiver utilizando o Windows 7 ou o Windows 8, expanda a seo Common
WPF Controls.
Essa seo exibe uma lista de controles utilizados pela maioria dos aplicativos
grficos.

Dica A seo All XAML Controls (Windows 8.1) ou All WPF Controls (Windows
7 e Windows 8) exibe uma lista mais extensa de controles.

3. Na seo Common XAML Controls ou Common WPF Controls, clique em TextBlo-


ck e arraste o controle TextBlock para o formulrio exibido na janela Design View.

Dica Certifique-se de selecionar o controle TextBlock e no o controle TextBox.


Se acidentalmente voc colocar o controle errado em um formulrio, pode re-
mov-lo com facilidade, clicando no item no formulrio e pressionando Delete.
t

Um controle TextBlock adicionado ao formulrio (voc o mover para o local


correto mais adiante), e a Toolbox ocultada.

Dica Se quiser que a Toolbox permanea visvel, mas no oculte nenhuma


parte do formulrio, na extremidade direita da barra de ttulo da Toolbox, clique
no boto Auto Hide (ele parece um alfinete). A Toolbox aparece permanente-
mente no lado esquerdo da janela do Visual Studio 2013 e a janela Design View
reduzida para acomod-la. (Talvez voc perca muito espao se tiver uma tela
com baixa resoluo.) Clicar no boto Auto Hide mais uma vez far a Toolbox
desaparecer novamente.

4. provvel que o controle TextBlock no formulrio no esteja exatamente onde


voc quer. Voc pode clicar e arrastar os controles que adicionou a um formul-
rio para reposicion-los. Utilizando essa tcnica, mova o controle TextBlock para
posicion-lo prximo ao canto superior esquerdo do formulrio. (O local exato

Sharp_Visual_01.indd 23 30/06/14 17:02


24 PARTE I Introduo ao Microsoft Visual C# e ao Microsoft Visual Studio 2013

no importante para esse aplicativo.) Observe que talvez seja preciso clicar
longe do controle e, ento, clicar nele novamente, antes que voc possa mov-lo
na janela Design View.
No painel inferior, a descrio XAML do formulrio agora inclui o controle Text-
Block, junto com propriedades, como sua localizao no formulrio (controlada
pela propriedade Margin), o texto padro exibido por esse controle (na proprie-
dade Text), o alinhamento do texto exibido por esse controle (especificado pelas
propriedades HorizontalAlignment e VerticalAlignment) e se o texto deve passar
para a prxima linha se ultrapassar a largura do controle TextWrapping.
Se voc estiver usando Windows 8.1, o cdigo XAML do controle TextBlock ser
parecido com este (seus valores para a propriedade Margin podero ser um
pouco diferentes, dependendo de onde voc posicionou o controle TextBlock
no formulrio):
<TextBlock HorizontalAlignment="Left" Margin="400,200,0,0" TextWrapping="Wrap"
Text="TextBlock" VerticalAlignment="Top"/>

Se estiver usando Windows 7 ou Windows 8, o cdigo XAML ser praticamente o


mesmo, exceto que as unidades utilizadas pela propriedade Margin operam em
uma escala diferente, devido resoluo maior dos dispositivos Windows 8.1.
O painel XAML e a janela Design View tm uma relao bilateral entre si. Voc
pode editar os valores no painel XAML e as alteraes sero refletidas na janela
Design View. Por exemplo, voc pode mudar o local do controle TextBlock modi-
ficando os valores da propriedade Margin.
5. No menu View, clique em Properties Window.
Se j estava aberta, a janela Properties aparece no canto inferior direito da tela,
sob o Solution Explorer. possvel especificar as propriedades dos controles
usando o painel XAML sob a janela Design View, mas a janela Properties uma
maneira mais prtica de modificar as propriedades dos itens em um formulrio,
assim como outros itens em um projeto.
A janela Properties sensvel ao contexto, exibindo as propriedades do item
selecionado. Se clicar no formulrio exibido na janela Design View, fora do con-
trole TextBlock, voc ver que a janela Properties exibe as propriedades de um
elemento Grid. Se examinar o painel XAML, voc ver que o controle TextBlock
est contido em um elemento Grid. Todos os formulrios contm um elemento
Grid que controla o layout dos itens exibidos possvel definir layouts tabula-
res adicionando linhas e colunas ao elemento Grid, por exemplo.
6. Na janela Design View, clique no controle TextBlock. A janela Properties exibe
novamente as propriedades do controle TextBlock.
7. Na janela Properties, expanda a propriedade Text. Altere a propriedade FontSize
para 20 px e, em seguida, pressione Enter. Essa propriedade est localizada ao
lado da lista suspensa que contm o nome da fonte, o qual ser diferente para o
Windows 8.1 (Global User Interface) e para o Windows 7 ou Windows 8 (Segoe UI):

Sharp_Visual_01.indd 24 30/06/14 17:02


CAPTULO 1 Bem-vindo ao C# 25

Propriedade FontSize

Nota O sufixo px indica que o tamanho da fonte medido em pixels.

8. No painel XAML, abaixo da janela Design View, examine o texto que define o
controle TextBlock. Se voc fizer uma rolagem at o final da linha, dever ver o
texto FontSize = 20. Todas as alteraes feitas na janela Properties constaro
automaticamente nas definies do XAML e vice-versa.
Digite sobre o valor da propriedade FontSize no painel XAML, alterando-o para
24. O tamanho da fonte do texto do controle TextBlock na janela Design View e
na janela Properties muda.
9. Na janela Properties, examine as outras propriedades do controle TextBlock. Sin-
ta-se livre para fazer testes, alterando-as para ver seus efeitos.
Observe que, medida que voc altera os valores das propriedades, essas pro-
priedades so adicionadas definio do controle TextBlock no painel XAML.
Cada controle adicionado a um formulrio tem um conjunto de valores de pro-
priedade padro e esses valores no aparecem no painel XAML, a no ser que
voc os altere.
10. Altere o valor da propriedade Text do controle TextBlock, de TextBlock para
Please enter your name (Digite seu nome). Isso pode ser feito editando-se o
elemento Text no painel XAML ou alterando-se o valor na janela Properties (essa
propriedade est localizada na seo Common da janela Properties).
Observe que o texto exibido no controle TextBlock na janela Design View muda.
11. Clique no formulrio na janela Design View e exiba a Toolbox novamente.
12. Na Toolbox, clique e arraste o controle TextBox para o formulrio. Mova o con-
trole TextBox para posicion-lo imediatamente abaixo do controle TextBlock.

Sharp_Visual_01.indd 25 30/06/14 17:02


26 PARTE I Introduo ao Microsoft Visual C# e ao Microsoft Visual Studio 2013

Dica Ao se arrastar um controle em um formulrio, indicadores de alinhamen-


to aparecem automaticamente quando o controle torna-se alinhado vertical ou
horizontalmente a outros controles. uma dica visual rpida para voc se certifi-
car de que esses controles esto alinhados de modo correto.

13. Na janela Design View, posicione o mouse sobre a borda direita do controle Text-
Box. O cursor do mouse deve mudar para uma seta de duas pontas, indicando que
voc pode redimensionar o controle. Arraste a borda direita do controle TextBox
at que ele esteja alinhado com a borda direita do controle TextBlock acima; uma
guia dever aparecer quando as duas bordas estiverem alinhadas corretamente.
14. Com o controle TextBox ainda selecionado, altere o valor da propriedade Name
exibida na parte superior da janela Properties, de <No Name> para userName,
como ilustrado a seguir:

Propriedade Name

Nota Falaremos mais sobre as convenes de nomes para controles e variveis


no Captulo 2, Variveis, operadores e expresses.

15. Exiba a Toolbox novamente, depois clique e arraste um controle Button para o
formulrio. Posicione o controle Button direita da caixa do controle TextBox no
formulrio, de modo que a parte inferior do boto fique alinhada horizontal-
mente com a parte inferior da caixa de texto.
16. Na janela Properties, mude a propriedade Name do controle Button para ok,
mude a propriedade Content (na seo Common) de Button para OK e pressio-
ne Enter. Verifique que a legenda do controle Button no formulrio muda para
exibir o texto OK.
17. Se estiver usando Windows 7 ou Windows 8, clique na barra de ttulo do for-
mulrio na janela Design View. Na janela Properties, mude a propriedade Title
(novamente, na seo Common) de MainWindow para Hello.

Sharp_Visual_01.indd 26 30/06/14 17:02


CAPTULO 1 Bem-vindo ao C# 27

Nota Os aplicativos Windows Store no tm barra de ttulo.

18. Se estiver usando Windows 7 ou Windows 8, na janela Design View, clique na


barra de ttulo do formulrio Hello. Observe que uma ala de redimensiona-
mento (um pequeno quadrado) aparece no canto inferior direito do formulrio
Hello. Mova o cursor do mouse sobre a ala de redimensionamento. Quando o
cursor virar uma seta de duas pontas diagonal, arraste-o para redimensionar o
formulrio. Pare de arrastar e solte o boto do mouse quando o espaamento
em torno dos controles estiver igual.

Importante Clique na barra de ttulo do formulrio Hello e no no contorno da


grade dentro do formulrio, antes de redimension-lo. Se selecionar a grade, voc
modificar o layout dos controles no formulrio, mas no o tamanho do formulrio.

O formulrio Hello deve ficar parecido com a figura a seguir:

Nota Nos aplicativos Windows Store, as pginas no podem ser redimensiona-


das da mesma maneira que nos formulrios WPF; quando so executados, eles
ocupam automaticamente a tela inteira do dispositivo. Contudo, eles podem se
adaptar a diferentes resolues de tela e orientao do dispositivo, apresen-
tando diferentes visualizaes quando so encaixados. fcil ver como seu
aplicativo aparece em um dispositivo diferente, clicando em Device Window no
menu Design e, ento, selecionando as diferentes resolues de tela disponveis
na lista suspensa Display. Tambm possvel ver como seu aplicativo aparece no
modo retrato ou quando est encaixado, selecionando a orientao Portrait ou
a visualizao Snapped na lista de visualizaes disponveis.

19. No menu Build, clique em Build Solution e verifique se a compilao do projeto


foi bem-sucedida.
20. No menu Debug, clique em Start Debugging.
O aplicativo deve ser executado, exibindo seu formulrio. Se voc est usando
Windows 8.1, o formulrio ocupa a tela inteira e aparece deste modo:

Sharp_Visual_01.indd 27 30/06/14 17:02


28 PARTE I Introduo ao Microsoft Visual C# e ao Microsoft Visual Studio 2013

Nota Quando um aplicativo Windows Store executado no modo Debug no


Windows 8.1, aparecem dois pares de nmeros nos cantos superior esquerdo e
superior direito da tela. Esses nmeros controlam a taxa de redesenho (frame rate)
e os desenvolvedores podem utiliz-los para determinar quando um aplicativo co-
mea a demorar mais do que devia para responder (possivelmente uma indicao
de problemas de desempenho). Eles s aparecem quando um aplicativo executa-
do no modo Debug. Uma descrio completa do significado desses nmeros est
fora dos objetivos deste livro; portanto, voc pode ignor-los por enquanto.

Se voc est usando Windows 7 ou Windows 8, o formulrio aparece deste modo:

Na caixa de texto, voc pode digitar sobre o que est l, digitar seu nome e
clicar em OK, mas nada acontecer ainda. necessrio adicionar algum cdigo
para indicar o que deve acontecer quando o usurio clicar no boto OK, o que
faremos em seguida.
21. Retorne ao Visual Studio 2013. No menu DEBUG, clique em Stop Debugging.
Se voc est usando o Windows 8.1, pressione a tecla Windows+B. Isso deve
lev-lo de volta rea de Trabalho do Windows que est executando o Vi-
sual Studio, a partir do qual possvel acessar o menu Debug.

Sharp_Visual_01.indd 28 30/06/14 17:02


CAPTULO 1 Bem-vindo ao C# 29

Se voc est usando Windows 7 ou Windows 8, pode trocar diretamente para


o Visual Studio. Tambm possvel clicar no boto de fechamento (o X no
canto superior direito do formulrio) para fechar o formulrio, interromper a
depurao e retornar ao Visual Studio.

Como fechar um aplicativo Windows Store


Se voc est usando Windows 8.1 e clicou em Start Without Debugging no menu
Debug para executar o aplicativo, precisar fech-lo fora. Isso porque, ao con-
trrio dos aplicativos de console, a vida de um aplicativo Windows Store ge-
renciada pelo sistema operacional e no pelo usurio. O Windows 8.1 suspende
um aplicativo quando no est sendo exibido e o terminar quando o sistema
operacional precisar a liberartao dos recursos que ele consome. O modo mais
confivel de interromper o aplicativo Hello fora clicar (ou colocar o dedo,
caso voc tenha uma tela sensvel ao toque) na parte superior da tela e, ento,
clicar e arrastar (ou deslizar) o aplicativo para a parte inferior, e segur-lo at que
sua imagem se dobre (se voc soltar o aplicativo antes da imagem se dobrar, ele
continuar sendo executado em segundo plano). Essa ao fecha o aplicativo e o
leva de volta tela Iniciar do Windows, onde voc pode retornar ao Visual Studio.
Como alternativa, voc pode executar as seguintes tarefas:
1. Clique (ou coloque o dedo) no canto superior direito da tela e, ento, ar-
raste a imagem do Visual Studio para o meio da tela (ou pressione a tecla
Windows+B).
2. Na parte inferior da rea de trabalho, clique com o boto direito do mouse
na barra de tarefas do Windows e, ento, clique em Iniciar Gerenciador de
Tarefas.
3. Na janela Gerenciador de Tarefas do Windows, clique no aplicativo Hello e,
em seguida, clique em Finalizar Tarefa.

4. Feche a janela Gerenciador de Tarefas do Windows.

Sharp_Visual_01.indd 29 30/06/14 17:02


30 PARTE I Introduo ao Microsoft Visual C# e ao Microsoft Visual Studio 2013

Voc conseguiu criar um aplicativo grfico sem escrever uma nica linha de c-
digo em C#. Esse aplicativo ainda no faz muito (ser necessrio escrever algum cdi-
go), mas o Visual Studio 2013 gera uma grande quantidade de cdigo que trata das
tarefas de rotina que todos os aplicativos grficos devem realizar, como abrir e exibir
uma janela. Antes de adicionar seu prprio cdigo ao aplicativo, importante enten-
der o que Visual Studio produziu. A estrutura um pouco diferente entre um aplicati-
vo Windows Store e um aplicativo WPF, e as sees a seguir resumem esses estilos de
aplicativo separadamente.

Examine o aplicativo Windows Store


Se estiver usando Windows 8.1, no Solution Explorer, clique na seta adjacente ao ar-
quivo MainPage.xaml para expandir o n. O arquivo MainPage.xaml.cs aparece; clique
duas vezes nesse arquivo. O cdigo a seguir, do formulrio, exibido na janela Code
and Text Editor.
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Windows.Foundation;
using Windows.Foundation.Collections;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Navigation;

// O template do item Blank Page est documentado em http://go.microsoft.com/


fwlink/?LinkId=234238

namespace Hello
{
/// <summary>
/// Uma pgina vazia que pode ser usada sozinha ou acessada dentro de um Frame.
/// </summary>
public sealed partial class MainPage : Page
{
public MainPage()
{
this.InitializeComponent();
}
}
}

Alm de muitas diretivas using que colocam no escopo alguns namespaces que
a maioria dos aplicativos Windows Store utiliza, o arquivo contm apenas a definio
de uma classe chamada MainPage. H um pouco de cdigo para a classe MainPage,
conhecido como construtor, que chama um mtodo denominado InitializeComponent.
Um construtor um mtodo especial com o mesmo nome da classe. Ele executado
quando criada uma instncia da classe e pode conter um cdigo para inicializar a
instncia. Discutiremos sobre construtores no Captulo 7.

Sharp_Visual_01.indd 30 30/06/14 17:02


CAPTULO 1 Bem-vindo ao C# 31

Na realidade, a classe contm muito mais cdigo do que as poucas linhas mos-
tradas no arquivo MainPage.xaml.cs, mas grande parte dele gerada automaticamen-
te com base na descrio XAML do formulrio, e ocultada. Esse cdigo oculto realiza
operaes como criar e exibir o formulrio e tambm criar e posicionar os vrios con-
troles no formulrio.

Dica Voc tambm pode exibir o arquivo do cdigo C# para uma pgina em
um aplicativo Windows Store, clicando em Code no menu View quando a janela
Design View estiver exibida.

Voc deve estar se perguntando onde est o mtodo Main e como o formulrio
ser exibido quando o aplicativo for executado. Lembre-se de que, em um aplicativo
de console, Main define o ponto em que o programa inicia. Um aplicativo grfico
um pouco diferente.
No Solution Explorer deve aparecer outro arquivo-fonte chamado App.xaml. Se
expandir o n desse arquivo, voc ver outro arquivo, chamado App.xaml.cs. Em um
aplicativo Windows Store, o arquivo App.xaml fornece o ponto de entrada no qual o
aplicativo comea a executar. Se voc clicar duas vezes em App.xaml.cs no Solution
Explorer, ver cdigo semelhante a este:
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Windows.ApplicationModel;
using Windows.ApplicationModel.Activation;
using Windows.Foundation;
using Windows.Foundation.Collections;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Navigation;

// O template do item Blank Application est documentado em http://go.microsoft.com/


fwlink/?LinkId=234227

namespace Hello
{
/// <summary>
/// Fornece comportamento especfico do aplicativo para complementar a classe Application
padro.
/// </summary>
sealed partial class App : Application
{
/// <summary>
/// Inicializa o objeto aplicativo singleton. Esta a primeira linha executada
/// do cdigo escrito e, como tal, o equivalente lgico de main() ou WinMain().
/// </summary>
public App()
{
this.InitializeComponent();
this.Suspending += OnSuspending;

Sharp_Visual_01.indd 31 30/06/14 17:02


32 PARTE I Introduo ao Microsoft Visual C# e ao Microsoft Visual Studio 2013

/// <summary>
/// Executado quando o aplicativo chamado normalmente pelo usurio final. Outros pontos
/// de entrada sero usados quando o aplicativo for chamado para abrir um arquivo
/// especfico, para exibir resultados de pesquisa e assim por diante.
/// </summary>
/// <param name="args">Details about the launch request and process.</param>
protected override void OnLaunched(LaunchActivatedEventArgs e)
{

#if DEBUG
if (System.Diagnostics.Debugger.IsAttached)
{
this.DebugSettings.EnableFrameRateCounter = true;
}
#endif

Frame rootFrame = Window.Current.Content as Frame;

// No repete a inicializao do aplicativo quando a janela j tem contedo,


// apenas garante que ela esteja ativa
if (rootFrame == null)
{
// Cria um Frame para atuar como contexto de navegao e navega para a
primeira pgina
rootFrame = new Frame();

if (e.PreviousExecutionState == ApplicationExecutionState.Terminated)
{
//TODO: carregar estado do aplicativo suspenso anteriormente
}

// Coloca o frame na janela atual


Window.Current.Content = rootFrame;
}

if (rootFrame.Content == null)
{
// Quando a pilha de navegao no restaurada, navega para a primeira
// pgina, configurando a nova pgina passando as informaes exigidas
// como parmetro de navegao
if (!rootFrame.Navigate(typeof(MainPage), e.Arguments))
{
throw new Exception("Failed to create initial page");
}
}
// Garante que a janela atual esteja ativa
Window.Current.Activate();
}

/// <summary>
/// Chamado quando a execuo do aplicativo est sendo suspensa. O estado do aplicativo
/// salvo sem saber se ele ser terminado ou retomado com o contedo
/// da memria ainda intacto.

Sharp_Visual_01.indd 32 30/06/14 17:02


CAPTULO 1 Bem-vindo ao C# 33

/// </summary>
/// <param name="sender">The source of the suspend request.</param>
/// <param name="e">Details about the suspend request.</param>
private void OnSuspending(object sender, SuspendingEventArgs e)
{
var deferral = e.SuspendingOperation.GetDeferral();
//TODO: salvar o estado do aplicativo e interromper qualquer atividade de segundo
plano
deferral.Complete();
}
}
}

Grande parte desse cdigo consiste em comentrios (as linhas que comeam
com ///) e outras instrues que voc ainda no precisa entender, mas os principais
elementos esto localizados no mtodo OnLaunched, realado em negrito. Esse m-
todo executado quando o aplicativo comea e o cdigo presente nele faz com que
o aplicativo crie um novo objeto Frame, exiba o formulrio MainPage nesse quadro
(frame) e, ento, o ative. Neste estgio, no necessrio compreender completamente
o funcionamento desse cdigo ou a sintaxe de qualquer uma dessas instrues, mas
til reconhecer que assim que o aplicativo exibe o formulrio, quando comea a
ser executado.

Examine o aplicativo WPF


Se estiver usando o Windows 7 ou o Windows 8, no Solution Explorer, clique na seta
adjacente ao arquivo MainWindow.xaml para expandir o n. O arquivo MainWindow.
xaml.cs aparece; clique duas vezes nesse arquivo. O cdigo do formulrio aparece na
janela Code and Text Editor, como mostrado aqui:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace Hello
{
/// <summary>
/// Lgica de interao para MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
}
}

Sharp_Visual_01.indd 33 30/06/14 17:02


34 PARTE I Introduo ao Microsoft Visual C# e ao Microsoft Visual Studio 2013

Esse cdigo parece semelhante ao do aplicativo Windows Store, mas existem al-
gumas diferenas significativas muitos dos namespaces referenciados pelas diretivas
using no incio do arquivo so diferentes. Por exemplo, os aplicativos WPF utilizam obje-
tos definidos em namespaces que comeam com o prefixo System.Windows, enquanto
os aplicativos Windows Store utilizam objetos definidos em namespaces que comeam
com Windows.UI. Essa diferena no superficial. Esses namespaces so implementados
por diferentes assemblies e os controles e a funcionalidade oferecidos por eles so dife-
rentes entre os aplicativos WPF e Windows Store, embora possam ter nomes semelhan-
tes. Voltando ao exerccio anterior, voc adicionou controles TextBlock, TextBox e Button
ao formulrio WPF e ao aplicativo Windows Store. Embora esses controles tenham o
mesmo nome em cada estilo de aplicativo, eles so definidos em diferentes assemblies:
Windows.UI.Xaml.Controls para aplicativos Windows Store e System.Windows.Controls
para aplicativos WPF. Os controles de aplicativos Windows Store foram especificamente
projetados e otimizados para interfaces de toque, enquanto os controles WPF so des-
tinados, em especial, para uso em sistemas voltados para o mouse.
Assim como no cdigo do aplicativo Windows Store, o construtor da classe
MainWindow inicializa o formulrio WPF chamando o mtodo InitializeComponent.
Novamente, como antes, o cdigo desse mtodo fica oculto e realiza operaes como
criar e exibir o formulrio e tambm criar e posicionar os vrios controles no formulrio.
O modo pelo qual um aplicativo WPF especifica o formulrio inicial a ser exibi-
do diferente de um aplicativo Windows Store. Assim como um aplicativo Windows
Store, ele estipula um objeto App definido no arquivo App.xaml para fornecer o ponto
de entrada para o aplicativo, mas o formulrio a ser exibido especificado de forma
declarada como parte do cdigo XAML, em vez de em forma de programa. Se voc
clicar duas vezes no arquivo App.xaml no Solution Explorer (no em App.xaml.cs),
poder examinar a descrio XAML. H uma propriedade StartupUri no cdigo XAML
que se refere ao arquivo MainWindow.xaml, como mostrado em negrito no exemplo
de cdigo a seguir:
<Application x:Class="Hello.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com.winfx/2006/xaml"
StartupUri="MainWindow.xaml">
<Application.Resources>

</Application.Resources>
</Application>

Em um aplicativo WPF, a propriedade StartupUri do objeto App indica o formu-


lrio a ser exibido.

Adicione cdigo ao aplicativo grfico


Agora que voc conhece um pouco da estrutura de um aplicativo grfico, chegou a
hora de escrever cdigo para que seu aplicativo realmente faa alguma coisa.

Escreva o cdigo para o boto OK


1. Na janela Design View, abra o arquivo MainPage.xaml (Windows 8.1) ou o arqui-
vo MainWindow.xaml (Windows 7 ou Windows 8) para isso, clique duas vezes
em MainPage.xaml ou em MainWindow.xaml no Solution Explorer.

Sharp_Visual_01.indd 34 30/06/14 17:02


CAPTULO 1 Bem-vindo ao C# 35

2. Ainda na janela Design View, clique no boto OK do formulrio para selecion-lo.


3. Na janela Properties, clique no boto Event Handlers for the Selected Element.
Esse boto exibe um cone parecido com um relmpago, como demonstrado
aqui:

Propriedade Name

A janela Properties exibe uma lista de nomes de evento para o controle Button.
Um evento indica uma ao significativa que normalmente exige uma resposta,
e voc pode escrever seu cdigo para executar essa resposta.
4. Na caixa adjacente ao evento Click, digite okClick e, em seguida, pressione Enter.
O arquivo MainPage.xaml.cs (Windows 8.1) ou MainWindow.xaml.cs (Windows
7 ou Windows 8) aparece na janela Code and Text Editor e um novo mtodo
chamado okClick adicionado classe MainPage ou MainWindow. O mtodo
semelhante a este:
private void okClick(object sender, RoutedEventArgs e)
{

No se preocupe com a sintaxe desse cdigo ainda voc aprender tudo sobre
mtodos no Captulo 3.
5. Se estiver usando o Windows 8.1, execute as seguintes tarefas:
a. Adicione a seguinte diretiva using, mostrada em negrito, lista do incio do
arquivo (o caractere de reticncias [] indica instrues que foram omitidas
por brevidade):
using System;
...
using Windows.UI.Xaml.Navigation;
using Windows.UI.Popups;

b. Adicione o seguinte cdigo mostrado em negrito ao mtodo okClick:

Sharp_Visual_01.indd 35 30/06/14 17:02


36 PARTE I Introduo ao Microsoft Visual C# e ao Microsoft Visual Studio 2013

void okClick(object sender, RoutedEventArgs e)


{
MessageDialog msg = new MessageDialog("Hello " + userName.Text);
msg.ShowAsync();
}

Quando compilado, este cdigo ir exibir em "warning" a respeito do uso de um


mtodo assncrono. No se preocupe com a mensagem; os metodos assncronos
sero explicados no Captulo 24.
Esse cdigo ser executado quando o usurio clicar no boto OK. Novamente,
no se preocupe com a sintaxe. Apenas certifique-se de copiar o cdigo exa-
tamente como mostrado; voc vai descobrir o que essas instrues significam
nos prximos captulos. O mais importante a entender que a primeira instru-
o cria um objeto MessageDialog com a mensagem Hello <SeuNome>, onde
<SeuNome> o nome que voc digita no controle TextBox do formulrio. A
segunda instruo exibe o objeto MessageDialog, fazendo-o aparecer na tela.
A classe MessageDialog definida no namespace Windows.UI.Popups e esse o
motivo pelo qual voc o adicionou no passo a.
6. Se estiver usando Windows 7 ou Windows 8, basta adicionar ao mtodo okClick
a nica instruo mostrada em negrito:
void okClick(object sender, RoutedEventArgs e)
{
MessageBox.Show("Hello " + userName.Text);
}

Esse cdigo executa uma funo semelhante funo do aplicativo Windows


Store, exceto que utiliza uma classe diferente, chamada MessageBox. Essa classe
definida no namespace System.Windows, o qual j referenciado pelas direti-
vas using existentes no incio do arquivo; portanto, voc no precisa adicion-lo.
7. Clique na guia MainPage.xaml ou na guia MainWindow.xaml acima da janela
Code and Text Editor para exibir o formulrio na janela Design View novamente.
8. No painel inferior que exibe a descrio XAML do formulrio, examine o ele-
mento Button, mas tenha cuidado para no alterar nada. Observe que agora ele
contm um elemento chamado Click que se refere ao mtodo okClick:
<Button x:Name="ok" ... Click="okClick" />

9. No menu Debug, clique em Start Debugging.


10. Quando o formulrio aparecer, digite seu nome sobre o texto existente na caixa
de texto e ento clique em OK.
Se voc estiver usando o Windows 8.1, aparecer um dilogo de mensagem no
meio da tela, saudando-o pelo seu nome:

Sharp_Visual_01.indd 36 30/06/14 17:02


CAPTULO 1 Bem-vindo ao C# 37

Se estiver usando Windows 7 ou Windows 8, aparecer uma caixa de mensagem


exibindo a seguinte saudao:

11. Clique em Close no dilogo de mensagem (Windows 8.1) ou em OK (Windows 7


ou Windows 8) na caixa de mensagem.
12. Volte para o Visual Studio 2013 e, ento, no menu Debug, clique em Stop Debu-
gging.

Sharp_Visual_01.indd 37 30/06/14 17:02


38 PARTE I Introduo ao Microsoft Visual C# e ao Microsoft Visual Studio 2013

Resumo
Neste captulo, voc viu como possvel utilizar o Visual Studio 2013 para criar, cons-
truir e executar aplicativos. Voc criou um aplicativo de console que exibe sua sada
em uma janela de console e um aplicativo WPF com uma GUI simples.
j Se quiser continuar no prximo captulo, mantenha o Visual Studio 2013 execu-
tando e v para o Captulo 2.
j Se quiser encerrar o Visual Studio 2013 agora, no menu File, clique em Exit. Se vir
uma caixa de dilogo Save, clique em Yes para salvar o projeto.

Referncia rpida

Para Faa isto


Criar um novo aplicativo de console no No menu File, aponte para New e clique em Project
Visual Studio 2013 para abrir a caixa de dilogo New Project. No
painel esquerda, em Installed Templates, clique
em Visual C#. No painel central, clique em Console
Application. Na caixa Location, especifique um
diretrio para os arquivos de projeto. Digite um
nome para o projeto e clique em OK.
Criar um novo aplicativo grfico No menu File, aponte para New e clique em Project
Windows Store em branco para para abrir a caixa de dilogo New Project. No painel
Windows 8.1 no Visual Studio 2013 da esquerda, na seo Installed Templates, expanda
Visual C# e clique em Windows Store. No painel
central, clique em Blank App (XAML). Na caixa
Location, especifique um diretrio para os arquivos
de projeto. Digite um nome para o projeto e clique
em OK.
Criar um novo aplicativo grfico WPF No menu File, aponte para New e clique em Project
para Windows 7 ou Windows 8 no para abrir a caixa de dilogo New Project. No painel
Visual Studio 2013 da esquerda, na seo Installed Templates, expanda
Visual C# e clique em Windows. No painel central,
clique em WPF Application. Especifique um diretrio
para os arquivos do projeto na caixa Location. Digite
um nome para o projeto e clique em OK.
Compilar o aplicativo No menu Build, clique em Build Solution.
Executar o aplicativo no modo Debug No menu Debug, clique em Start Debugging.
Executar o aplicativo sem depurar No menu Debug, clique em Start Without
Debugging.

Sharp_Visual_01.indd 38 30/06/14 17:02


CAPTULO 2

Variveis, operadores
e expresses
Neste captulo, voc vai aprender a:
j Entender instrues, identificadores e palavras-chave.
j Utilizar variveis para armazenar informaes.
j Trabalhar com tipos de dados primitivos.
j Utilizar operadores aritmticos, como o sinal de adio (+) e o sinal de subtrao
().
j Incrementar e decrementar variveis.
O Captulo 1, Bem-vindo ao C#, mostrou como utilizar o ambiente de programao do
Microsoft Visual Studio 2013 para compilar e executar um programa de console e um
aplicativo grfico. Este captulo traz os elementos de sintaxe e semntica do Microsoft
Visual C#, como instrues, palavras-chave e identificadores. Voc vai estudar os tipos
primitivos compilados na linguagem C#, assim como as caractersticas dos valores arma-
zenados em cada tipo. Alm disso, este captulo tambm explica como declarar e utilizar
variveis locais (que somente existem dentro de uma funo ou outra pequena seo do
cdigo). Voc vai ser apresentado aos operadores aritmticos que o C# fornece, desco-
brindo como deve utilizar operadores para manipular valores e aprendendo a controlar
expresses com dois ou mais operadores.

Instrues
Instruo um comando que executa uma ao, como calcular um valor e armazenar
o resultado, ou exibir uma mensagem para o usurio. Voc combina instrues para
criar mtodos. Para aprender mais sobre mtodos, consulte o Captulo 3, Como escre-
ver mtodos e aplicar o escopo, mas, por enquanto, considere um mtodo como uma
sequncia nomeada de instrues. Main, que foi apresentado no captulo anterior,
um exemplo de mtodo.
As instrues em C# seguem um conjunto bem definido de regras que descre-
vem seu formato e sua construo. Estas so conhecidas coletivamente como sintaxe.
(Por outro lado, a especificao do que as instrues fazem conhecida coletivamente
como semntica.) Uma das regras de sintaxe mais simples e mais importantes do C#
diz que voc deve terminar todas as instrues com um ponto e vrgula. Por exemplo,
o Captulo 1 demonstrou que, sem o ponto e vrgula de terminao, a instruo a se-
guir no seria compilada:
Console.WriteLine(Hello, World!);

_Livro_Sharp_Visual.indb 39 30/06/14 15:03


40 PARTE I Introduo ao Microsoft Visual C# e ao Microsoft Visual Studio 2013

Dica C# uma linguagem de formato livre, assim, espaos em branco, como


um caractere de espao ou uma nova linha, no tm outro significado a no ser
o de serem separadores. Ou seja, voc pode dispor as instrues como quiser.
Mas deve adotar um estilo consistente e simples de layout para tornar seus pro-
gramas mais fceis de ler e entender.

O truque para programar bem em qualquer linguagem aprender sua sintaxe e


semntica e ento utiliz-la de maneira natural e idiomtica. Essa estratgia facilita a
manuteno dos seus programas. medida que avanar neste livro, voc ver exem-
plos das instrues mais importantes do C#.

Identificadores
Identificadores so os nomes utilizados para distinguir os elementos nos seus progra-
mas, como namespaces, classes, mtodos e variveis. (Discutiremos as variveis em bre-
ve.) No C#, voc deve seguir as regras de sintaxe abaixo ao escolher os identificadores:
j Voc pode utilizar apenas letras (maisculas ou minsculas), dgitos e o caractere
de sublinhado.
j Um identificador deve iniciar com uma letra (ou um sublinhado).
Por exemplo, resultado, _placar, timeDeFutebol e plano9 so identificadores vli-
dos, enquanto resultado%, timeDeFutebol$ e 9plano no so.

Importante O C# uma linguagem que diferencia maisculas de minsculas:


timeDeFutebol e TimeDeFutebol so dois identificadores diferentes.

Identifique palavras-chave
A linguagem C# reserva, para uso prprio, 77 identificadores, os quais no podem ser
reutilizados para outros propsitos. Eles so denominados palavras-chave, e cada um
tem um significado especfico. Exemplos de palavras-chave so class, namespace e
using. Voc aprender o significado da maioria das palavras-chave do C# ao longo da
leitura deste livro. A seguir est a lista de palavras-chave:

abstract do in protected true


as double int public try
base else interface readonly typeof
bool enum internal ref uint
break event is return ulong
byte explicit lock sbyte unchecked
case extern long sealed unsafe

_Livro_Sharp_Visual.indb 40 30/06/14 15:03


CAPTULO 2 Variveis, operadores e expresses 41

catch false namespace short ushort


char finally new sizeof using
checked fixed null stackalloc virtual
class float object static void
const for operator string volatile
continue foreach out struct while
decimal goto override switch
default if params this
delegate implicit private throw

O C# tambm utiliza os identificadores a seguir. Eles no so especficos ao C#,


ou seja, voc pode utiliz-los como identificadores em seus prprios mtodos, vari-
veis e classes, mas isso deve ser evitado sempre que possvel.

add get remove


alias global select
ascending group set
async into value
await join var
descending let where
dynamic orderby yield
from partial

Variveis
Varivel um local de armazenamento que contm um valor. Voc pode considerar
uma varivel como uma caixa na memria do computador que contm informaes
temporrias. Voc deve atribuir a cada varivel em um programa um nome no am-
bguo que a identifique de forma nica no contexto em que utilizada. Um nome de
varivel utilizado para referenciar o valor que ela armazena. Por exemplo, se quiser
armazenar o valor do custo de um item em uma loja, voc deve criar uma varivel
chamada custo e armazenar o custo do item nela. Se voc referenciar a varivel custo,
o valor recuperado ser o custo do item armazenado anteriormente.

Nomeie variveis
Adote uma conveno de nomes que torne claras as variveis definidas. Isso espe-
cialmente importante se voc faz parte de uma equipe de projeto com vrios desen-
volvedores trabalhando em diferentes partes de um aplicativo; uma conveno de
nomes consistente ajuda a evitar confuso e pode reduzir a extenso de erros. A lista a
seguir contm algumas recomendaes gerais:

_Livro_Sharp_Visual.indb 41 30/06/14 15:03


42 PARTE I Introduo ao Microsoft Visual C# e ao Microsoft Visual Studio 2013

j No inicie um identificador com um sublinhado. Embora isso seja vlido em C#,


pode limitar a interoperabilidade de seu cdigo com aplicativos compilados em
outras linguagens, como Microsoft Visual Basic.
j No crie identificadores cuja nica diferena seja entre maisculas e minsculas.
Por exemplo, no crie uma varivel chamada minhaVariavel e outra chamada
MinhaVariavel para serem utilizadas ao mesmo tempo, porque ser muito fcil
confundi-las. Alm disso, a definio de identificadores cuja nica diferena seja
a distino entre maisculas e minsculas pode limitar a reutilizao das classes
nos aplicativos desenvolvidos com outras linguagens que no diferem maiscu-
las e minsculas, como o Visual Basic.
j Comece o nome com uma letra minscula.
j Em um identificador com vrias palavras, comece a segunda palavra e as pala-
vras subsequentes com uma letra maiscula. Isso chamado de notao camelo
ou camelCase.
j No utilize notao hngara. (Se voc for desenvolvedor de Microsoft Visual
C++, provavelmente j conhece a notao hngara. Se no souber o que isso,
no se preocupe!)
Por exemplo, placar, timeDeFutebol, _placar e TimeDeFutebol so nomes de va-
riveis vlidos, mas apenas os dois primeiros so recomendados.

Declare variveis
As variveis armazenam valores. O C# pode armazenar e processar muitos tipos di-
ferentes de valores inteiros, nmeros de ponto flutuante e sequncias de caractere
(strings), entre outros. Ao declarar uma varivel, voc deve especificar o tipo de dado
que ela armazenar.
Voc declara o tipo e o nome de uma varivel em uma instruo de declara-
o. Por exemplo, a instruo a seguir declara que a varivel chamada age armazena
valores int (inteiros). Como sempre, a instruo deve ser terminada com um ponto e
vrgula.
int age;

O tipo de varivel int o nome de um dos tipos primitivos do C# inteiro, que,


como o nome j diz, um nmero inteiro. (Voc vai aprender sobre os diversos tipos
de dados primitivos mais adiante neste captulo.)

Nota Se voc for programador de Visual Basic, deve observar que o C# no


permite declaraes implcitas de varivel. Voc deve declarar explicitamente
todas as variveis antes de utiliz-las.

Aps ter declarado sua varivel, voc pode atribuir-lhe um valor. A instruo
a seguir atribui o valor de 42 a age. Novamente, observe que o ponto e vrgula
obrigatrio.
age = 42;

_Livro_Sharp_Visual.indb 42 30/06/14 15:03


CAPTULO 2 Variveis, operadores e expresses 43

O sinal de igual (=) o operador de atribuio, que atribui o valor que est a sua
direita varivel que est a sua esquerda. Depois dessa atribuio, a varivel age pode
ser utilizada no seu cdigo para referenciar o valor armazenado. A instruo a seguir
escreve o valor da varivel age (42) no console:
Console.WriteLine(age);

Dica Se voc deixar o cursor do mouse sobre uma varivel na janela Visual
Studio 2013 Code and Text Editor, aparecer uma dica de tela indicando o tipo
da varivel.

Tipos de dados primitivos


O C# tem vrios tipos predefinidos denominados tipos de dados primitivos. A tabela a
seguir lista os mais utilizados no C# e o intervalo de valores que podem ser armaze-
nados neles.

Tipo de dado Descrio Tamanho (bits) Intervalo Exemplo de uso


31 31
int Nmeros inteiros 32 2 a 2 1 int count;
count = 42;
long Nmeros inteiros (intervalo 64 263 a 263 1 long wait;
maior) wait = 42L;
float Nmeros de ponto flutuante 32 1.5 1045 a float away;
3.4 1038 away = 0.42F;
double Nmeros de ponto flutuante de 64 5.0 10324 a double trouble;
preciso dupla (mais precisos) 1.7 10308 trouble = 0.42;
decimal Valores monetrios 128 28 valores decimal coin;
significativos coin = 0.42M;
string Sequncia de caracteres 16 bits por No aplicvel string vest;
caractere vest = forty two;
char Caractere nico 16 0 a 216 1 char grill;
grill = x;
bool Valor booleano 8 Verdadeiro ou bool teeth;
falso teeth = false;

Variveis locais no atribudas


Quando voc declara uma varivel, ela contm um valor aleatrio at que lhe seja
atribudo um valor. Esse comportamento era uma grande fonte de erros nos progra-
mas C e C++ que criavam uma varivel e a utilizavam acidentalmente como fonte de
informaes antes de ela receber um valor. O C# no permite utilizar uma varivel no
atribuda. necessrio atribuir um valor a uma varivel antes de us-la; caso contrrio,
o programa no compilar. Essa exigncia chamada regra de atribuio definitiva.

_Livro_Sharp_Visual.indb 43 30/06/14 15:03


44 PARTE I Introduo ao Microsoft Visual C# e ao Microsoft Visual Studio 2013

Por exemplo, as instrues a seguir geram a mensagem de erro de tempo de compila-


o Use of unassigned local variable age porque a instruo Console.WriteLine tenta
exibir o valor de uma varivel no inicializada:
int age;
Console.WriteLine(age); // compile-time error

Exiba valores de tipos de dados primitivos


No exerccio a seguir, voc vai utilizar um programa em C# chamado PrimitiveData-
Types para demonstrar como os vrios tipos de dados primitivos funcionam.

Exiba os valores dos tipos de dados primitivos


1. Inicie o Visual Studio 2013, se ele ainda no estiver em execuo.
2. No menu File, aponte para Open e ento clique em Project/Solution.
A caixa de dilogo Open Project aparece.
3. Se estiver usando o Windows 8.1, v at a pasta \Microsoft Press\Visual CSharp
Step By Step\Chapter 2\Windows 8.1\PrimitiveDataTypes na sua pasta Docu-
mentos. Se estiver usando o Windows 7 ou o Windows 8, v at a pasta \Micro-
soft Press\Visual CSharp Step By Step\Chapter 2\Windows 7\PrimitiveDataTypes
na sua pasta Documentos.

Nota Para no ser repetitivo e economizar espao, nos exerccios subsequentes


vou simplesmente me referir aos caminhos de solues usando uma frase da
forma \Microsoft Press\Visual CSharp Step By Step\Chapter 2\Windows X\Primi-
tiveDataTypes, onde X 7 ou 8.1, dependendo do sistema operacional que voc
estiver usando.

Importante Se voc estiver executando o Windows 8, lembre-se de usar os


projetos e solues para Windows 7 em todos os exerccios do livro.

4. Selecione o arquivo de soluo PrimitiveDataTypes e clique em Open.


A soluo carregada e o Solution Explorer exibe o projeto PrimitiveDataTypes.

Nota Os nomes dos arquivos de soluo tm o sufixo .sln, como em Primitive-


DataTypes.sln. Uma soluo pode conter um ou mais projetos. Os arquivos de
projeto tm o sufixo .csproj. Se um projeto for aberto em vez de uma soluo,
o Visual Studio 2013 criar para ele, automaticamente, um novo arquivo de
soluo. Essa situao pode ser confusa, se voc no estiver informado desse de-
talhe, pois pode resultar na gerao acidental de vrias solues para o mesmo
projeto.

_Livro_Sharp_Visual.indb 44 30/06/14 15:03


CAPTULO 2 Variveis, operadores e expresses 45

Dica Certifique-se de abrir o arquivo de soluo da pasta correta para seu sis-
tema operacional. Se voc tentar abrir uma soluo para um aplicativo Windows
Store com o Visual Studio 2013 no Windows 7 ou no Windows 8, o projeto no
ser carregado. Se voc expandir o n do projeto, o Solution Explorer marcar o
projeto como indisponvel e exibir a mensagem This project requires a higher
version of Windows to load, como mostrado na imagem a seguir:

Se isso acontecer, feche a soluo e abra a verso da pasta correta.

5. No menu Debug, clique em Start Debugging.


Talvez sejam exibidos alguns avisos no Visual Studio. Voc pode ignor-los sem
perigo. (Voc os corrigir no prximo exerccio.)
Se voc est usando o Windows 8.1, a seguinte pgina ser exibida:

Se voc est usando o Windows 7 ou o Windows 8, a seguinte janela aparecer:

_Livro_Sharp_Visual.indb 45 30/06/14 15:03


46 PARTE I Introduo ao Microsoft Visual C# e ao Microsoft Visual Studio 2013

6. Na lista Choose A Data Type, clique em string.


O valor forty two aparece na caixa Sample Value.
7. Novamente, na lista Choose A Data Type, clique no tipo string.
O valor to do (a fazer) aparece na caixa Sample Value, indicando que as ins-
trues para exibir um valor int ainda precisam ser escritas.
8. Clique em cada tipo de dado na lista. Confirme que o cdigo para os tipos dou-
ble e bool ainda no est implementado.
9. Volte para o Visual Studio 2013 e, ento, no menu Debug, clique em Stop
Debugging.

Nota Lembre-se de que, no Windows 8.1, voc pode pressionar a tecla


Windows+B para voltar rea de trabalho do Windows que exibe o Visual Stu-
dio 2013.
Se estiver usando o Windows 7 ou o Windows 8, voc tambm pode clicar em
Quit para fechar a janela e interromper o programa.

Utilize tipos de dados primitivos no cdigo


1. No Solution Explorer, expanda o projeto PrimitiveDataTypes (se ainda no estiver
expandido) e, em seguida, clique duas vezes em MainWindow.xaml.

_Livro_Sharp_Visual.indb 46 30/06/14 15:03


CAPTULO 2 Variveis, operadores e expresses 47

Nota Para manter as instrues do exerccio simples, os formulrios nas ver-


ses para Windows 8.1 e para Windows 7 do cdigo tm os mesmos nomes.

O formulrio do aplicativo aparece na janela Design View.

Sugesto Se sua tela no for grande o suficiente para exibir o formulrio in-
teiro, voc pode ampliar e reduzir a janela Design View usando Ctrl+Alt+= e
Ctrl+Alt+ ou selecionando o tamanho na lista suspensa de zoom, no canto
inferior esquerdo da janela Design View.

2. No painel XAML, role para baixo para localizar a marcao do controle ListBox.
Esse controle exibe a lista de tipos de dados na parte esquerda do formulrio e
parecida com isto (algumas das propriedades foram removidas desse texto):
<ListBox x:Name="type" ... SelectionChanged="typeSelectionChanged">
<ListBoxItem>int</ListBoxItem>
<ListBoxItem>long</ListBoxItem>
<ListBoxItem>float</ListBoxItem>
<ListBoxItem>double</ListBoxItem>
<ListBoxItem>decimal</ListBoxItem>
<ListBoxItem>string</ListBoxItem>
<ListBoxItem>char</ListBoxItem>
<ListBoxItem>bool</ListBoxItem>
</ListBox>

O controle ListBox exibe cada tipo de dado como um ListBoxItem separado.


Quando o aplicativo est em execuo, se um usurio clicar em um item na lista,
o evento SelectionChanged ocorrer (isso um pouco como o evento Clicked
que ocorre quando o usurio clica em um boto, o qual foi demonstrado no
Captulo 1). Voc pode ver que, neste caso, o controle ListBox chama o mtodo
typeSelectionChanged. Esse mtodo definido no arquivo MainWindow.xaml.cs.
3. No menu View, clique em Code.
A janela Code and Text Editor abre, exibindo o arquivo MainWindow.xaml.cs.

Nota Lembre-se de que tambm possvel usar o Solution Explorer para


acessar o cdigo. Clique na seta esquerda do arquivo MainWindow.xaml para
expandir o n e, ento, clique duas vezes em MainWindow.xaml.cs.

4. Na janela Code and Text Editor, localize o mtodo typeSelectionChanged.

_Livro_Sharp_Visual.indb 47 30/06/14 15:03


48 PARTE I Introduo ao Microsoft Visual C# e ao Microsoft Visual Studio 2013

Dica Para localizar um item no seu projeto, no menu Edit, aponte para Find
And Replace e clique em Quick Find. Um menu se abre no canto superior es-
querdo da janela Code and Text Editor. Na caixa de texto desse menu de atalho,
digite o nome do item que voc est procurando e, ento, clique em Find Next
(o smbolo de seta para a direita ao lado da caixa de texto):

Boto
Menu Find
Find Next

Por padro, a pesquisa no diferencia maisculas de minsculas. Se quiser fazer


uma pesquisa que diferencie letras maisculas de minsculas, clique na seta para
baixo ao lado do texto a ser pesquisado, clique na seta suspensa direita da caixa
de texto no menu de atalho para exibir as opes adicionais e marque a caixa de
seleo Match Case. Se tiver tempo, voc pode experimentar as outras opes.
Voc tambm pode pressionar Ctrl+F para exibir a caixa de dilogo Quick Find
em vez de utilizar o menu Edit. Da mesma forma, voc pode pressionar Ctrl+H
para exibir a caixa de dilogo Quick Replace.
Como alternativa ao uso da funcionalidade Quick Find, voc tambm pode locali-
zar os mtodos em uma classe utilizando a caixa de lista suspensa de membros da
classe, posicionada acima da janela Code and Text Editor, direita.

_Livro_Sharp_Visual.indb 48 30/06/14 15:03


CAPTULO 2 Variveis, operadores e expresses 49

A lista suspensa de membros da classe exibe todos os mtodos da classe e as


variveis e outros itens que a classe contm. (Voc conhecer mais detalhes sobre
esses itens em captulos posteriores.) Na lista suspensa, clique no mtodo type-
SelectionChanged e o cursor saltar imediatamente para o mtodo typeSelection-
Changed na classe.

Se voc j programou em outra linguagem, provavelmente pode imaginar como


o mtodo typeSelectionChanged funciona; caso contrrio, o Captulo 4, Instru-
es de deciso, esclarecer esse cdigo. No momento, basta entender que,
quando o usurio clica em um item no controle ListBox, o valor do item pas-
sado para esse mtodo, o qual ento utiliza esse valor para determinar o que
acontece em seguida. Por exemplo, se o usurio clica no valor float, esse mtodo
chama outro mtodo, denominado showFloatValue.
5. Percorra o cdigo e localize o mtodo showFloatValue, que como este:
private void showFloatValue()
{
float floatVar;
floatVar = 0.42F;
value.Text = floatVar.ToString();
}

O corpo desse mtodo contm trs instrues. A primeira declara uma varivel
chamada floatVar do tipo float.
A segunda instruo atribui o valor 0.42F a floatVar.

_Livro_Sharp_Visual.indb 49 30/06/14 15:03


50 PARTE I Introduo ao Microsoft Visual C# e ao Microsoft Visual Studio 2013

Importante O F um tipo de sufixo especificando que 0.42 deve ser tratado


como um valor float. Se voc esquecer o F, o valor 0.42 ser tratado como um
double e seu programa no compilar, porque um valor de um tipo no pode
ser atribudo a uma varivel de outro tipo sem se escrever cdigo adicional C#
muito rgido nesse aspecto.

A terceira instruo exibe o valor dessa varivel na caixa de texto Value no for-
mulrio. Essa expresso exige sua ateno. Conforme ilustrado no Captulo 1, a
maneira de exibir um item em uma caixa de texto configurando a propriedade
Text (no Captulo 1, voc fez isso usando XAML). Tambm possvel executar
essa tarefa por meio de programa, que o que est acontecendo aqui. Observe
que a propriedade de um objeto acessada utilizando a mesma notao de
ponto que vimos para executar um mtodo. (Lembra-se de Console.WriteLine
do Captulo 1?) Alm disso, os dados adicionados propriedade Text devem ser
uma string e no um nmero. Se voc tentar atribuir um nmero propriedade
Text, seu programa no compilar. Felizmente, o .NET Framework d alguma
ajuda na forma do mtodo ToString.
Cada tipo de dado no .NET Framework tem um mtodo ToString. A finalidade
de ToString converter um objeto na sua representao de string. O mtodo
showFloatValue utiliza o mtodo ToString do objeto floatVar da varivel float
para gerar uma verso de string do valor dessa varivel. Essa string pode ento
ser atribuda com segurana propriedade Text da caixa de texto Value. Ao criar
seus prprio tipos de dados e classes, voc pode definir uma implementao
prpria do mtodo ToString para especificar a maneira como sua classe deve ser
representada como uma string. Veja como criar suas prprias classes no Captulo
7, Criao e gerenciamento de classes e objetos.
6. Na janela Code and Text Editor, localize o mtodo showIntValue:
private void showIntValue()
{
value.Text = "to do";
}

O mtodo showIntValue chamado quando voc clica no tipo int na caixa de


listagem.
7. Digite as duas instrues a seguir no incio do mtodo showIntValue, em uma
nova linha depois da chave de abertura, como mostrado em negrito no cdigo
a seguir:
private void showIntValue()
{
int intVar;
intVar = 42;
value.Text = "to do";
}

A primeira instruo cria uma varivel chamada intVar que pode conter um valor
int. A segunda instruo atribui o valor a essa varivel.
8. A instruo original nesse mtodo altera a string to do para intVar.ToString();

_Livro_Sharp_Visual.indb 50 30/06/14 15:03


CAPTULO 2 Variveis, operadores e expresses 51

O mtodo agora deve estar exatamente como este:


private void showIntValue()
{
int intVar;
intVar = 42;
value.Text = intVar.ToString();
}

9. No menu Debug, clique em Start Debugging.


O formulrio aparece novamente.
10. Na lista Choose A Data Type, selecione o tipo int. Confirme se o valor 42 est
sendo exibido na caixa de texto Sample Value.
11. Volte para o Visual Studio e, ento, no menu Debug, clique em Stop Debugging.
12. Na janela Code and Text Editor, localize o mtodo showDoubleValue.
13. Edite o mtodo showDoubleValue exatamente como mostrado em negrito no
seguinte cdigo:
private void showDoubleValue()
{
double doubleVar;
doubleVar = 0.42;
value.Text = doubleVar.ToString();
}

Esse cdigo semelhante ao mtodo showIntValue, exceto que cria uma varivel
chamada doubleVar que contm valores double e recebe o valor 0.42.
14. Na janela Code and Text Editor, localize o mtodo showBoolValue.
15. Edite o mtodo showBoolValue exatamente assim:
private void showBoolValue()
{
bool boolVar;
boolVar = false;
value.Text = boolVar.ToString();
}

Novamente, esse cdigo semelhante aos exemplos anteriores, exceto que bo-
olVar s pode conter um valor booleano, verdadeiro ou falso. Nesse caso, o valor
atribudo falso.
16. No menu Debug, clique em Start Debugging.
17. Na lista Choose A Data Type, selecione os tipos int, double e bool. Em cada um
dos casos, verifique se o valor correto exibido na caixa de texto Sample Value.
18. Volte para o Visual Studio e, ento, no menu Debug, clique em Stop Debugging.

_Livro_Sharp_Visual.indb 51 30/06/14 15:03


52 PARTE I Introduo ao Microsoft Visual C# e ao Microsoft Visual Studio 2013

Operadores aritmticos
O C# suporta as operaes aritmticas que voc aprendeu na escola: o sinal de mais
(+) para adio, o sinal de menos () para subtrao, o asterisco (*) para multiplica-
o e a barra (/) para diviso. Os smbolos +, , * e / so denominados operadores
porque operam em valores para criar novos valores. No exemplo abaixo, a varivel
moneyPaidToConsultant termina armazenando o produto de 750 (a diria) e de 20 (o
nmero de dias que o consultor trabalhou):
long moneyPaidToConsultant;
moneyPaidToConsultant = 750 * 20;

Nota Os valores nos quais um operador efetua sua funo chamam-se operan-
dos. Na expresso 750 * 20, o * o operador e 750 e 20 so os operandos.

Operadores e tipos
Nem todos os operadores so aplicveis a todos os tipos de dados. Aqueles que po-
dem ser utilizados em um valor dependem do tipo do valor. Por exemplo, voc pode
usar todos os operadores aritmticos em valores de tipo char, int, long, float, double ou
decimal. Contudo, com exceo do operador de adio, +, os operadores aritmticos
no podem ser usados em valores de tipo string e nenhum deles pode ser usado com
valores de tipo bool. Portanto, a instruo a seguir no permitida porque o tipo string
no suporta o operador de subtrao (no h sentido em subtrair uma string de outra):
// compile-time error
Console.WriteLine("Gillingham" - "Forest Green Rovers");

Contudo, voc pode utilizar o operador + para concatenar valores de string.


preciso ter bastante cuidado, pois isso pode produzir resultados inesperados. Por
exemplo, a seguinte instruo escreve 431 (e no 44) no console:
Console.WriteLine("43" + "1");

Dica O .NET Framework fornece um mtodo chamado Int32.Parse que pode


ser utilizado para converter um valor de string em um inteiro, se voc precisar
efetuar clculos aritmticos em valores armazenados em strings.

Voc deve estar ciente de que o tipo de resultado de uma operao aritmtica
depende do tipo dos operandos utilizados. Por exemplo, o valor da expresso 5.0/2.0
2.5; o tipo dos dois operandos double, de modo que o tipo do resultado tambm
double. (No C#, os nmeros literais com pontos decimais so sempre double, no
float, para manter o mximo de preciso possvel.) Mas o valor da expresso 5/2 2.
Nesse caso, o tipo de ambos os operandos int; assim, o tipo do resultado tambm
int. O C# sempre arredonda para zero em casos assim. A situao se torna um pouco
mais complicada se voc misturar os tipos de operandos. Por exemplo, a expresso
5/2.0 consiste em um int e um double. O compilador do C# detecta a incompatibili-

_Livro_Sharp_Visual.indb 52 30/06/14 15:03


CAPTULO 2 Variveis, operadores e expresses 53

dade e gera um cdigo que converte o int em double antes de executar a operao.
O resultado da operao , portanto, um double (2.5). Embora funcione, essa prtica
considerada ruim.
O C# tambm suporta um operador aritmtico menos conhecido: o operador
resto ou mdulo, que representado pelo sinal de porcentagem (%). O resultado de x
% y o resto da diviso do valor x pelo valor y. Assim, por exemplo, 9%2 1, porque
9 dividido por 2 4, resto 1.

Nota Se voc j conhece C ou C++, sabe que nessas linguagens no poss-


vel utilizar o operador resto nos valores float ou double. Entretanto, C# afrouxa
essa regra. O operador resto vlido para todos os tipos numricos, e o resul-
tado no necessariamente um inteiro. Por exemplo, o resultado da expresso
7.0%2.4 2.2.

Tipos numricos e valores infinitos


H uma ou duas outras caractersticas dos nmeros em C# que voc precisa
conhecer. Por exemplo, o resultado da diviso de qualquer nmero por zero
infinito, estando fora do intervalo dos tipos int, long e dos tipos decimais; conse-
quentemente, avaliar uma expresso como 5/0 resulta em um erro. Mas os tipos
double e float tm um valor especial que pode representar valores infinitos, e o
valor da expresso 5.0/0.0 Infinity. A nica exceo a essa regra o valor da
expresso 0.0/0.0. Em geral, se dividir zero por qualquer nmero, o resultado ser
zero, mas se dividir algo por zero o resultado ser um nmero infinito. A expres-
so 0.0/0.0 resulta em um paradoxo o valor deve ser zero e infinito ao mesmo
tempo. O C# tem outro valor especial para essa situao, chamado NaN, que
significa not a number (no um nmero). Portanto, se 0.0/0.0 for avaliada, o
resultado ser NaN.
NaN e Infinity so propagados pelas expresses. Se 10 + NaN for avaliado,
o resultado ser NaN, e se 10 + Infinity for avaliado, o resultado ser Infinity. A
nica exceo a essa regra quando Infinity multiplicado por 0. O valor da ex-
presso Infinity * 0 0, embora o valor de NaN * 0 seja NaN.

Examine operadores aritmticos


O exerccio a seguir demonstra como utilizar os operadores aritmticos em valores int.

Execute o projeto MathsOperators


1. Inicie o Visual Studio 2013, se ele ainda no estiver em execuo.
2. Abra o projeto MathsOperators, localizado na pasta \Microsoft Press\Visual
CSharp Step By Step\Chapter 2\Windows X\MathsOperators na sua pasta Docu-
mentos.
3. No menu Debug, clique em Start Debugging.

_Livro_Sharp_Visual.indb 53 30/06/14 15:03


54 PARTE I Introduo ao Microsoft Visual C# e ao Microsoft Visual Studio 2013

Se voc est usando o Windows 8.1, a seguinte pgina aparecer:

Se est usando o Windows 7 ou o Windows 8, o seguinte formulrio aparecer:

4. Na caixa Left Operand, digite 54.


5. Na caixa Right Operand, digite 13.
Agora voc pode aplicar qualquer um dos operadores aos valores das caixas de
texto.
6. Clique na opo Subtraction e, em seguida, clique em Calculate.
O texto na caixa Expression muda para 54 13, mas o valor 0 aparece na caixa
Result; claramente, isso est errado.

_Livro_Sharp_Visual.indb 54 30/06/14 15:03


CAPTULO 2 Variveis, operadores e expresses 55

7. Clique na opo / Division e, em seguida, clique em Calculate.


O texto na caixa Expression muda para 54/13 e, novamente, o nmero 0 aparece
na caixa Result.
8. Clique no boto % Remainder e ento em Calculate.
O texto na caixa Expression muda para 54 % 13; porm, mais uma vez, o nmero
0 aparece na caixa Result. Teste as outras combinaes de nmeros e operado-
res; voc vai descobrir que atualmente todas produzem o valor 0.

Nota Se voc digitar um valor no inteiro em uma das caixas de operando,


o aplicativo detectar um erro e exibir a mensagem Input string was not in a
correct format. Voc aprender mais sobre como capturar e tratar de erros e
excees no Captulo 6, Gerenciamento de erros e excees.

9. Quando tiver terminado, volte ao Visual Studio e, no menu Debug, clique em


Stop Debugging (se estiver usando o Windows 7 ou o Windows 8, tambm pode
clicar em Quit no formulrio MathsOperators).
Conforme voc pode ter adivinhado, nenhum dos clculos est atualmente imple-
mentado pelo aplicativo MathsOperators. No prximo exerccio, voc vai corrigir isso.

Efetue clculos no aplicativo MathsOperators


1. Exiba o formulrio MainWindow.xaml na janela Design View. (No Solution Explo-
rer, no projeto MathsOperators, clique duas vezes no arquivo MainWindow.xaml.)
2. No menu View, aponte para Other Windows e clique em Document Outline.
A janela Document Outline exibida, mostrando os nomes e tipos de controles
do formulrio. A janela Document Outline uma maneira simples de localizar e
selecionar controles em um formulrio complexo. Os controles so organizados
hierarquicamente, comeando pela pgina (Windows 8.1) ou janela (Windows
7 ou Windows 8) que constitui o formulrio. Como mencionado no Captulo 1,
uma pgina de aplicativo Windows Store ou um formulrio WPF contm um
controle Grid, e os outros controles so colocados dentro desse Grid. Se voc
expandir o n Grid na janela Document Outline, os outros controles aparecero,
comeando com outro Grid (o Grid externo atua como uma moldura e o interno
contm os controles que voc v no formulrio). Se voc expandir o Grid inter-
no, poder ver cada um dos controles existentes no formulrio.

Nota Na verso para Windows 8.1 do aplicativo, o controle Grid externo est
envolto em um controle ScrollViewer. Esse controle fornece uma barra de rola-
gem horizontal com a qual o usurio pode rolar a janela que exibe o aplicativo,
caso redimensione a janela de exibio.

_Livro_Sharp_Visual.indb 55 30/06/14 15:03


56 PARTE I Introduo ao Microsoft Visual C# e ao Microsoft Visual Studio 2013

Se voc clicar em qualquer um desses controles, o elemento correspondente


ser realado na janela Design View. Do mesmo modo, se voc selecionar um
controle na janela Design View, o controle correspondente ser selecionado na
janela Document Outline (para ver isso em ao, fixe a janela Document Outline,
cancelando a seleo do boto Auto Hide no canto superior direito da janela
Document Outline).
3. No formulrio, clique nos dois controles TextBox em que o usurio digita os n-
meros. Na janela Document Outline, verifique que seus nomes so lhsOperand e
rhsOperand.
Quando o formulrio executado, a propriedade Text de cada um desses con-
troles armazena os valores digitados pelo usurio.
4. Na parte inferior do formulrio, verifique se o controle TextBlock utilizado para
exibir a expresso que est sendo avaliada tem o nome expression e se o contro-
le TextBlock utilizado para exibir o resultado do clculo tem o nome result.
5. Feche a janela Document Outline.
6. No menu View, clique em Code para exibir o cdigo do arquivo MainWindow.
xaml.cs na janela Code and Text Editor.
7. Na janela Code and Text Editor, localize o mtodo addValues. Ele se parece com
este:
private void addValues()
{
int lhs = int.Parse(lhsOperand.Text);
int rhs = int.Parse(rhsOperand.Text);
int outcome = 0;
// TODO: somar rhs e lhs e armazenar o resultado em outcome

expression.Text = lhsOperand.Text + " + " + rhsOperand.Text;


result.Text = outcome.ToString();
}

_Livro_Sharp_Visual.indb 56 30/06/14 15:03


CAPTULO 2 Variveis, operadores e expresses 57

A primeira instruo nesse mtodo declara uma varivel int chamada lhs e a
inicializa com o inteiro que corresponde ao valor digitado pelo usurio na caixa
lhsOperand. Lembre-se de que a propriedade Text de um controle TextBox con-
tm uma string, mas lhs int; portanto, preciso converter essa string em um
inteiro antes que ela seja atribuda a lhs. O tipo de dado int fornece o mtodo
int.Parse, que faz precisamente isso.
A segunda instruo declara uma varivel int chamada rhs e a inicializa com o
valor da caixa rhsOperand depois de convert-lo em um int.
A terceira instruo declara uma varivel int chamada outcome.
Em seguida, aparece um comentrio dizendo que voc precisa somar rhs a lhs
e armazenar o resultado em outcome. Esse o cdigo ausente que precisa ser
implementado, o que voc vai fazer no prximo passo.
A quinta instruo concatena trs strings que indicam o clculo que est sendo
efetuado (utilizando o operador de adio, +) e atribui o resultado proprieda-
de expression.Text. Isso faz a string aparecer na caixa Expression no formulrio.
A ltima instruo exibe o resultado do clculo atribuindo-o propriedade Text
da caixa Result. Lembre-se de que a propriedade Text uma string e de que o re-
sultado do clculo um int; portanto, voc precisa converter o int em uma string
antes de atribu-lo propriedade Text. Lembre-se de que isso que o mtodo
ToString do tipo int faz.
8. Abaixo do comentrio no meio do mtodo addValues, adicione a instruo a
seguir (mostrada em negrito):
private void addValues()
{
int lhs = int.Parse(lhsOperand.Text);
int rhs = int.Parse(rhsOperand.Text);
int outcome = 0;
// TODO: somar rhs e lhs e armazenar o resultado em outcome
outcome = lhs + rhs;
expression.Text = lhsOperand.Text + " + " + rhsOperand.Text;
result.Text = outcome.ToString();
}

Essa instruo avalia a expresso lhs + rhs e armazena o resultado em outcome.


9. Examine o mtodo subtractValues. Voc ver que ele segue um padro seme-
lhante e preciso adicionar a instruo para calcular o resultado da subtrao
de lhs por rhs, armazenando-o em outcome. Adicione a esse mtodo a seguinte
instruo (em negrito):
private void subtractValues()
{
int lhs = int.Parse(lhsOperand.Text);
int rhs = int.Parse(rhsOperand.Text);
int outcome = 0;
// TODO: subtrair rhs de lhs e armazenar o resultado em outcome
outcome = lhs - rhs;
expression.Text = lhsOperand.Text + " - " + rhsOperand.Text;
result.Text = outcome.ToString();
}

_Livro_Sharp_Visual.indb 57 30/06/14 15:03


58 PARTE I Introduo ao Microsoft Visual C# e ao Microsoft Visual Studio 2013

10. Examine os mtodos mutiplyValues, divideValues e remainderValues. Novamen-


te, todos eles tm a instruo crucial que efetua o clculo ausente especificado.
Adicione as instrues apropriadas a esses mtodos (mostradas em negrito).
private void multiplyValues()
{
int lhs = int.Parse(lhsOperand.Text);
int rhs = int.Parse(rhsOperand.Text);
int outcome = 0;
// TODO: multiplicar lhs por rhs e armazenar o resultado em outcome
outcome = lhs * rhs;
expression.Text = lhsOperand.Text + " * " + rhsOperand.Text;
result.Text = outcome.ToString();
}

private void divideValues()


{
int lhs = int.Parse(lhsOperand.Text);
int rhs = int.Parse(rhsOperand.Text);
int outcome = 0;
// TODO: dividir lhs por rhs e armazenar o resultado em outcome
outcome = lhs / rhs;
expression.Text = lhsOperand.Text + " / " + rhsOperand.Text;
result.Text = outcome.ToString();
}

private void remainderValues()


{
int lhs = int.Parse(lhsOperand.Text);
int rhs = int.Parse(rhsOperand.Text);
int outcome = 0;
// TODO: calcular o resto aps a diviso de lhs por rhs e armazenar o
resultado em outcome
outcome = lhs % rhs;
expression.Text = lhsOperand.Text + " % " + rhsOperand.Text;
result.Text = outcome.ToString();
}

Teste o aplicativo MathsOperators


1. No menu Debug, clique em Start Debugging para compilar e executar o aplica-
tivo.
2. Digite 54 na caixa Left Operand, digite 13 na caixa Right Operand, clique no
boto + Addition e ento clique em Calculate.
O valor 67 deve aparecer na caixa Result.
3. Clique na opo Subtraction e, em seguida, clique em Calculate. Verifique que
o resultado agora 41.
4. Clique na opo * Multiplication e, em seguida, clique em Calculate. Verifique
que o resultado agora 702.
5. Clique na opo / Division e, em seguida, clique em Calculate. Verifique que o
resultado agora 4.

_Livro_Sharp_Visual.indb 58 30/06/14 15:03


CAPTULO 2 Variveis, operadores e expresses 59

Em uma situao real, 54/13 d uma dzima peridica (4,153846...); no entanto,


aqui o C# est efetuando uma diviso de inteiros. Quando um inteiro divido
por outro inteiro, a resposta que voc obtm um inteiro, como explicado
anteriormente.
6. Clique na opo % Remainder e, em seguida, clique em Calculate. Verifique que
o resultado agora 2.
Ao se lidar com inteiros, o resto, aps a diviso de 54 por 13, 2; (54 ((54/13)
* 13)) 2. Isso acontece porque, em cada estgio, o clculo arredonda para um
inteiro abaixo. (Meu professor de matemtica na escola secundria ficaria horro-
rizado se soubesse que (54/13) * 13 no igual a 54!)
7. Volte ao Visual Studio e interrompa a depurao (ou clique em Quit, se estiver
usando o Windows 7 ou o Windows 8).

Controle a precedncia
A precedncia (ou prioridade) controla a ordem em que os operadores da expresso
so avaliados. Considere a expresso a seguir, que utiliza os operadores + e *:
2 + 3 * 4

Essa expresso potencialmente ambgua: qual deve ser efetuada primeiro, a


adio ou a multiplicao? A ordem das operaes importa porque muda o resultado:
j Se efetuar primeiro a adio e depois a multiplicao, o resultado da adio (2 +
3) formar o operando esquerdo do operador *, e o resultado de toda a expres-
so ser 5 * 4 = 20.
j Se efetuar primeiro a multiplicao e depois a adio, o resultado da multiplica-
o (3 * 4) formar o operando direito do operador +, e o resultado da expres-
so inteira ser 2 + 12 = 14.
No C#, os operadores multiplicativos (*, / e %) tm precedncia sobre os ope-
radores aditivos (+ e ), portanto, em expresses como 2 + 3 * 4, a multiplicao
efetuada primeiro, seguida pela adio. Portanto, a resposta para 2 + 3 * 4 14.
Parnteses podem ser utilizados para anular a precedncia e forar os operandos
a vincular-se aos operadores de maneira diferente. Por exemplo, na expresso a seguir,
os parnteses foram o 2 e o 3 a se vincular ao operador + (produzindo o valor 5), e o
resultado dessa soma o operando esquerdo do operador *, produzindo o valor 20:
(2 + 3) * 4

Nota O termo parnteses refere-se a ( ). O termo chaves refere-se a { }. O ter-


mo colchetes refere-se a [ ].

_Livro_Sharp_Visual.indb 59 30/06/14 15:03


60 PARTE I Introduo ao Microsoft Visual C# e ao Microsoft Visual Studio 2013

Utilize a associatividade para avaliar expresses


A precedncia dos operadores apenas metade da histria. O que acontece quando
uma expresso contm operadores diferentes que tm a mesma precedncia? a que
a associatividade se torna importante. Associatividade a direo (esquerda ou direita)
em que os operandos de um operador so avaliados. Considere a expresso a seguir
que utiliza os operadores / e *:
4 / 2 * 6

primeira vista, essa expresso potencialmente ambgua. Qual deve ser efe-
tuada primeiro, a diviso ou a multiplicao? A precedncia dos dois operadores a
mesma (so ambos multiplicativos), mas a ordem em que so aplicados na expresso
importante, pois dois resultados diferentes podem ser obtidos:
j Se efetuar primeiro a diviso, o resultado da diviso (4/2) formar o operando
esquerdo do * operador, e o resultado da expresso inteira ser (4/2) * 6 ou 12.
j Se efetuar primeiro a multiplicao, o resultado da multiplicao (2 * 6) formar
o operando direito do operador /, e o resultado da expresso inteira ser 4 /(2
* 6) ou 4/12.
Nesse caso, a associatividade dos operadores determina como a expresso
avaliada. Ambos os operadores, * e /, associam-se esquerda, assim, os operandos so
calculados da esquerda para a direita. Nesse caso, 4/2 ser avaliado antes da multipli-
cao por 6, que resulta em 12.

A associatividade e o operador de atribuio


No C#, o sinal de igual (=) um operador. Todos os operadores retornam um valor
com base nos seus operandos. O operador de atribuio = no diferente. Ele aceita
dois operandos: o operando direita avaliado e ento armazenado no operando
esquerda. O valor do operador de atribuio o valor que foi atribudo para o ope-
rando esquerdo. Por exemplo, na seguinte instruo de atribuio, o valor retornado
pelo operador de atribuio 10, que tambm o valor atribudo varivel myInt:
int myInt;
myInt = 10; // o valor da expresso de atribuio 10

Voc pode estar pensando que tudo isso interessante e esotrico, mas e da?
Bem, como o operador de atribuio retorna um valor, voc pode utilizar esse mesmo
valor em outra ocorrncia da instruo de atribuio, desta maneira:
int myInt;
int myInt2;
myInt2 = myInt = 10;

O valor atribudo varivel myInt2 o valor que foi atribudo a myInt. A instru-
o de atribuio atribui o mesmo valor a ambas as variveis. Essa tcnica til se voc
quer inicializar diferentes variveis com o mesmo valor. Torna-se claro para qualquer
leitor do seu cdigo que todas as variveis devem ter o mesmo valor:
myInt5 = myInt4 = myInt3 = myInt2 = myInt = 10;

_Livro_Sharp_Visual.indb 60 30/06/14 15:03


CAPTULO 2 Variveis, operadores e expresses 61

A partir dessa discusso, voc provavelmente pode deduzir que o operador de


atribuio associado da direita para a esquerda. A atribuio mais direita ocorre
primeiro, e o valor atribudo se propaga pelas variveis da direita para a esquerda. Se
uma das variveis j tivesse um valor, esse seria sobrescrito pelo valor que est sendo
atribudo.
Entretanto, trate essa construo com cautela. Um erro frequentemente come-
tido por novos programadores de C# tentar combinar esse uso do operador de atri-
buio com declaraes de variveis. Por exemplo, voc poderia esperar que o cdigo
a seguir criasse e inicializasse trs variveis com o mesmo valor (10):
int myInt, myInt2, myInt3 = 10;

Esse um cdigo vlido do C# (porque compilado). Ele declara as variveis


myInt, myInt2 e myInt3, e inicializa myInt3 com o valor 10. Contudo, ele no inicializa
myInt nem myInt2. Se voc tentar utilizar myInt ou myInt2 em uma expresso como
myInt3 = myInt / myInt2;

o compilador gerar os seguintes erros:


Use of unassigned local variable 'myInt'
Use of unassigned local variable 'myInt2'

Incremente e decremente variveis


Se quiser somar 1 a uma varivel, pode utilizar o operador +, como demonstrado aqui:
count = count + 1;

Mas adicionar 1 a uma varivel to comum que o C# fornece um operador


somente para essa finalidade: o operador ++. Para incrementar a varivel count por 1,
voc pode escrever a instruo a seguir:
count++;

Da mesma forma, o C# fornece o operador --, que pode ser utilizado para sub-
trair 1 de uma varivel, desta maneira:
count--;

Os operadores ++ e -- so unrios, ou seja, eles tm um nico operando. Eles


compartilham a mesma precedncia e ambos so associativos esquerda.

Prefixo e sufixo
Os operadores de incremento (++) e decremento (--) fogem do comum, porque voc
pode coloc-los antes ou depois da varivel. Quando o smbolo do operador coloca-
do antes da varivel, chamamos de forma prefixada do operador, e quando colocado
depois, chamamos de forma ps-fixada ou sufixada do operador. Eis alguns exemplos:

_Livro_Sharp_Visual.indb 61 30/06/14 15:03


62 PARTE I Introduo ao Microsoft Visual C# e ao Microsoft Visual Studio 2013

count++; // incremento ps-fixado


++count; // incremento prefixado
count--; // decremento ps-fixado
--count; // decremento prefixado

Utilizar a forma prefixada ou sufixada do operador ++ ou -- no faz a menor


diferena para a varivel que est sendo incrementada ou decrementada. Por exem-
plo, se voc escreve count++, o valor de count aumenta por 1, e se escreve ++count,
o valor de count tambm aumenta por 1. Sabendo isso, voc provavelmente poderia
perguntar por que h duas maneiras de escrever a mesma coisa. Para entender a res-
posta, voc precisa lembrar que ++ e -- so operadores e que todos os operadores
so utilizados para avaliar uma expresso que tem um valor. O valor retornado por
count++ o valor de count antes do incremento, enquanto o valor retornado por
++count o valor de count depois que o incremento ocorre. Veja um exemplo:
int x;
x = 42;
Console.WriteLine(x++); // x agora 43, 42 escrito
x = 42;
Console.WriteLine(++x); // x agora 43, 43 escrito

A maneira de lembrar o que cada operando faz examinar a ordem dos elemen-
tos (o operando e o operador) em uma expresso prefixada ou sufixada. Na expresso
x++, a varivel x ocorre primeiro; portanto, seu valor utilizado como o valor da
expresso antes de x ser incrementada. Na expresso ++x, o operador ocorre primei-
ro; portanto, sua operao executada antes de o valor de x ser calculado como o
resultado.
Esses operadores so mais utilizados nas instrues while e do, que sero apre-
sentadas no Captulo 5, Atribuio composta e instrues de iterao. Caso esteja uti-
lizando os operadores de incremento e decremento isoladamente, fique com a forma
ps-fixada e seja coerente.

Declare variveis locais implicitamente tipadas


Vimos anteriormente neste captulo que uma varivel declarada especificando um
tipo de dado e um identificador, assim:
int myInt;

Tambm foi mencionado que um valor deve ser atribudo a uma varivel antes
de se tentar utiliz-la. Voc pode declarar e inicializar uma varivel na mesma instru-
o, como ilustrado a seguir:
int myInt = 99;

Ou assim, supondo que myOtherInt seja uma varivel do tipo inteiro j inicializada:
int myInt = myOtherInt * 99;

Agora, lembre-se de que o valor atribudo a uma varivel deve ser do mesmo
tipo da varivel. Por exemplo, voc pode atribuir um valor int apenas a uma varivel
int. O compilador C# pode calcular rapidamente o tipo de uma expresso utilizada

_Livro_Sharp_Visual.indb 62 30/06/14 15:03


CAPTULO 2 Variveis, operadores e expresses 63

para inicializar uma varivel e indicar se no corresponde ao tipo da varivel. Tambm


possvel instruir o compilador C# a deduzir o tipo de uma varivel a partir de uma
expresso e utiliz-lo ao declarar a varivel com a palavra-chave var no lugar do tipo,
como demonstrado aqui:
var myVariable = 99;
var myOtherVariable = "Hello";

As variveis myVariable e myOtherVariable so conhecidas como variveis impli-


citamente tipadas. A palavra-chave var faz o compilador deduzir o tipo das variveis a
partir dos tipos das expresses utilizadas para inicializ-las. Nesses exemplos, myVaria-
ble um int e myOtherVariable uma string. Contudo, importante entender que essa
uma convenincia apenas para declarar variveis e que, depois que uma varivel foi
declarada, voc s pode atribuir valores do tipo inferido a ela valores float, double
ou string no podem ser atribudos a myVariable em um ponto posterior no seu pro-
grama, por exemplo. Voc tambm deve entender que s possvel utilizar a palavra-
-chave var quando fornecer uma expresso para inicializar uma varivel. A declarao
a seguir ilegal e causar um erro de compilao:
var yetAnotherVariable; // Erro o compilador no pode inferir o tipo

Importante Se voc j programou em Visual Basic, talvez conhea o tipo Va-


riant, que pode ser utilizado para armazenar qualquer tipo de valor em uma
varivel. importante frisar que voc deve esquecer tudo que j aprendeu so-
bre variveis Variant ao programar em Visual Basic. Embora as palavras-chave
paream semelhantes, var e Variant so totalmente diferentes. Ao declarar uma
varivel em C# utilizando a palavra-chave var, o tipo de valor que voc atribui
varivel no pode mudar em relao quele utilizado para inicializar a varivel.

Se voc for purista, provavelmente est cerrando os dentes agora e se pergun-


tando por que cargas dgua os projetistas de uma linguagem elegante como C#
permitem a infiltrao de um componente como var. Afinal, parece uma desculpa
para a extrema preguia dos programadores e pode tornar mais difcil entender o que
um programa est fazendo ou rastrear bugs (e pode at mesmo introduzir novos bugs
em seu cdigo facilmente). Mas confie no fato de que var tem um lugar vlido no C#,
como veremos ao trabalhar nos captulos a seguir. Por enquanto, vamos nos ater ao
uso de variveis explicitamente tipadas, exceto quando a tipagem implcita tornar-se
uma necessidade.

Resumo
Neste captulo, voc viu como criar e utilizar variveis e aprendeu sobre alguns tipos
de dados comuns, disponveis para as variveis no C#. Voc conheceu os identifica-
dores e, alm disso, usou alguns operadores para construir expresses e aprendeu
que a precedncia e a associatividade dos operadores determinam o modo como as
expresses so avaliadas.
j Se quiser continuar no prximo captulo, mantenha o Visual Studio 2013 execu-
tando e v para o Captulo 3.

_Livro_Sharp_Visual.indb 63 30/06/14 15:03


64 PARTE I Introduo ao Microsoft Visual C# e ao Microsoft Visual Studio 2013

j Se quiser encerrar o Visual Studio 2013 agora, no menu File, clique em Exit. Se vir
uma caixa de dilogo Save, clique em Yes e salve o projeto.

Referncia rpida

Para Faa isto


Declarar uma varivel Escreva o nome do tipo de dado, seguido pelo
nome da varivel, seguido por um ponto e
vrgula. Por exemplo:
int outcome;

Declarar uma varivel e atribuir a ela um Escreva o nome do tipo de dado, seguido pelo
valor inicial nome da varivel, seguido pelo operador de
atribuio e o valor inicial. Finalize com um ponto
e vrgula. Por exemplo:
int outcome = 99;

Alterar o valor de uma varivel Escreva o nome da varivel esquerda, seguido


pelo operador de atribuio, seguido pela
expresso que calcula o novo valor, seguido por
um ponto e vrgula. Por exemplo:
outcome = 42;

Gerar uma representao de string do Chame o mtodo ToString da varivel. Por


valor de uma varivel exemplo:
int intVar = 42;

string stringVar = intVar.ToString();

Converter uma string em um int Chame o mtodo System.Int32.Parse. Por


exemplo:
string stringVar = 42;

int intVar = System.Int32.Parse(stringVar);

Anular a precedncia de um operador Utilize parnteses na expresso para explicitar a


ordem de avaliao. Por exemplo:
(3 + 4) * 5

Atribuir o mesmo valor a diversas variveis Use uma instruo de atribuio que liste todas
as variveis. Por exemplo:
myInt4 = myInt3 = myInt2 = myInt = 10;

Incrementar ou decrementar uma varivel Utilize o operador ++ ou --. Por exemplo:


count++;

_Livro_Sharp_Visual.indb 64 30/06/14 15:03


CAPTULO 3

Como escrever mtodos e


aplicar escopo
Neste captulo, voc vai aprender a:
j Declarar e chamar mtodos.
j Passar informaes para um mtodo.
j Retornar as informaes de um mtodo.
j Definir o escopo de classe e local.
j Utilizar o depurador integrado para entrar e sair dos mtodos medida que eles
so executados.
No Captulo 2, Variveis, operadores e expresses, voc aprendeu como declarar
variveis e tambm como criar expresses utilizando operadores. Viu ainda como a
precedncia e a associatividade controlam a maneira pela qual so avaliadas as ex-
presses com mltiplos operadores. Os mtodos so o tema deste captulo. Voc
aprender como declarar e chamar mtodos e tambm como utilizar os argumentos e
parmetros para transferir informaes para um mtodo, e o modo como deve retor-
n-las com o emprego de uma instruo return. Voc tambm saber, neste captulo,
como entrar e sair dos mtodos usando o depurador integrado do Microsoft Visual
Studio 2013. Quando for preciso rastrear a execuo dos seus mtodos, essas infor-
maes sero extremamente teis caso eles no funcionem como o esperado. Por fim,
este captulo ensina a declarar mtodos que aceitam parmetros opcionais e a chamar
mtodos por meio de argumentos nomeados.

Crie mtodos
Um mtodo uma sequncia nomeada de instrues. Se voc j programou com uma
linguagem como C, C++ ou Microsoft Visual Basic, perceber que um mtodo mui-
to semelhante a uma funo ou a uma sub-rotina. Um mtodo tem um nome e um
corpo. O nome do mtodo deve ser um identificador significativo que indique sua
finalidade geral (calcularImpostoDeRenda, por exemplo). O corpo do mtodo contm
as instrues reais a serem executadas quando o mtodo for chamado. Alm disso, os
mtodos podem receber alguns dados para serem processados e retornar informa-
es, que normalmente so o resultado do processamento. Os mtodos caracterizam-
-se como um mecanismo poderoso e fundamental.

_Livro_Sharp_Visual.indb 65 30/06/14 15:03


66 PARTE I Introduo ao Microsoft Visual C# e ao Microsoft Visual Studio 2013

Declare um mtodo
A sintaxe para declarar um mtodo C# :
tipoDeRetorno nomeDoMtodo ( listaDeParmetros )
{
// as instrues do corpo do mtodo ficam aqui
}

Elementos que constituem uma declarao:


j O tipoDeRetorno o nome de um tipo e especifica a informao que o mto-
do retorna como resultado do seu processamento. Ele pode ser qualquer tipo,
como int ou string. Se voc est escrevendo um mtodo que no retorna um
valor, deve utilizar a palavra-chave void no lugar do tipo de retorno.
j O nomeDoMtodo o nome utilizado para chamar o mtodo. Os nomes de
mtodo seguem as mesmas regras de identificador dos nomes de variveis. Por
exemplo, addValues um nome de mtodo vlido, mas add$Values no . Por
enquanto, voc deve seguir a conveno camelo para nomes de mtodos; por
exemplo, exibirClientes.
j A listaDeParmetros opcional e descreve os tipos e nomes das informaes
que voc pode passar para o mtodo processar. Escreva os parmetros entre
parnteses de abertura e fechamento, (), como se estivesse declarando variveis,
com o nome do tipo seguido pelo nome do parmetro. Se o mtodo que estiver
escrevendo tiver dois ou mais parmetros, separe-os com vrgulas.
j As instrues do corpo do mtodo so as linhas de cdigo executadas quando
o mtodo chamado. Elas ficam entre chaves de abertura e de fechamento, { }.

Importante Se voc programa em C, C++ e Microsoft Visual Basic, deve notar


que o C# no suporta mtodos globais. Voc deve escrever todos os seus mto-
dos dentro de uma classe; caso contrrio, seu cdigo no compilar.

Aqui est a definio de um mtodo chamado addValues que retorna um resul-


tado int e tem dois parmetros int chamados leftHandSide e rightHandSide:
int addValues(int leftHandSide, int rightHandSide)
{
// ...
// as instrues do corpo do mtodo ficam aqui
// ...
}

Nota Voc deve especificar explicitamente os tipos de quaisquer parmetros e


o tipo de retorno de um mtodo. A palavra-chave var no pode ser utilizada.

_Livro_Sharp_Visual.indb 66 30/06/14 15:03


CAPTULO 3 Como escrever mtodos e aplicar escopo 67

A seguir, a definio de um mtodo chamado showResult que no retorna um


valor e tem um nico parmetro int chamado answer:
void showResult(int answer)

{
// ...
}

Observe o uso da palavra-chave void para indicar que o mtodo nada retorna.

Importante Caso esteja familiarizado com Visual Basic, observe que o C# no


utiliza palavras-chave diferentes para distinguir entre um mtodo que retorna
um valor (uma funo) e um mtodo que no retorna um valor (um procedi-
mento ou sub-rotina). Voc sempre deve especificar um tipo de retorno ou a
palavra-chave void.

Retorne dados de um mtodo


Para que um mtodo retorne uma informao (ou seja, seu tipo de retorno no void),
voc deve incluir uma instruo return no final do processamento do mtodo. Uma
instruo return consiste na palavra-chave return, seguida por uma expresso especifi-
cando o valor retornado e um ponto e vrgula. O tipo da expresso deve ser o mesmo
tipo especificado pela declarao do mtodo. Por exemplo, se um mtodo retorna um
int, a instruo return deve retornar um int; caso contrrio, o programa no compilar.
Aqui est um exemplo de mtodo com uma instruo return:
int addValues(int leftHandSide, int rightHandSide)
{
// ...
return leftHandSide + rightHandSide;
}

A instruo return, em geral, fica no final do mtodo porque o faz terminar e


controla os retornos para a instruo que chamou o mtodo, como descrito poste-
riormente neste captulo. As instrues que ocorrerem aps a instruo return no
sero executadas (embora o compilador avise sobre esse problema, caso voc coloque
instrues depois da instruo return).
Se no quiser que o mtodo retorne informaes (ou seja, seu tipo de retorno
void), voc pode utilizar uma variao da instruo return para causar uma sada
imediata do mtodo. Escreva a palavra-chave return, seguida imediatamente por um
ponto e vrgula. Por exemplo:
void showResult(int answer)
{
// exibe a resposta
...
return;
}

_Livro_Sharp_Visual.indb 67 30/06/14 15:03


68 PARTE I Introduo ao Microsoft Visual C# e ao Microsoft Visual Studio 2013

Se o mtodo no retornar coisa alguma, voc tambm pode omitir a instruo


return, porque o mtodo finaliza automaticamente quando a execuo chega chave
de fechamento no fim do mtodo. Embora essa prtica seja comum, ela nem sempre
considerada um bom estilo de programao.
No exerccio a seguir, examinaremos outra verso do projeto MathsOperators do
Captulo 2. Essa verso foi aprimorada pela utilizao cuidadosa de alguns pequenos
mtodos. Dividir cdigo dessa maneira ajuda a torn-lo mais fcil de entender e de
manter.

Examine as definies de mtodo


1. Inicie o Visual Studio 2013, se ele ainda no estiver em execuo.
2. Abra o projeto Methods, que est na pasta \Microsoft Press\Visual CSharp Step
By Step\Chapter 3\Methods na sua pasta Documentos.
3. No menu Debug, clique em Start Debugging.
O Visual Studio 2013 compila e executa o aplicativo. Ele deve parecer igual ao
aplicativo do Captulo 2.
4. Explore o aplicativo e o modo como ele funciona; em seguida, volte ao Visual
Studio. No menu Debug, clique em Stop Debugging (ou clique em Quit na jane-
la Methods, se estiver usando o Windows 7 ou o Windows 8).
5. Exiba o cdigo de MainWindow.xaml.cs na janela Code and Text Editor (no Solu-
tion Explorer, expanda o arquivo MainWindow.xaml e, ento, clique duas vezes
em MainWindow.xaml.cs).
6. Na janela Code and Text Editor, localize o mtodo addValues, que como este:
private int addValues(int leftHandSide, int rightHandSide)
{
expression.Text = leftHandSide.ToString() + + + rightHandSide.ToString();
return leftHandSide + rightHandSide;
}

Nota No se preocupe com a palavra-chave private no incio da defini-


o desse mtodo, por enquanto; voc vai aprender o significado dela no
Captulo 7, Criao e gerenciamento de classes e objetos.

O mtodo addValues contm duas instrues. A primeira exibe o clculo exe-


cutado na caixa expression do formulrio. Os valores dos parmetros leftHand-
Side e rightHandSide so convertidos em strings (utilizando o mtodo ToString
descrito no Captulo 2) e concatenados com a verso de string do operador de
adio (+).
A segunda instruo utiliza a verso int do operador + para somar os valores das
variveis int leftHandSide e rightHandSide e retorna o resultado dessa operao.
Lembre-se de que somar dois valores int cria outro valor int; portanto, o tipo de
retorno do mtodo addValues int.

_Livro_Sharp_Visual.indb 68 30/06/14 15:03


CAPTULO 3 Como escrever mtodos e aplicar escopo 69

Se examinar os mtodos subtractValues, multiplyValues, divideValues e remain-


derValues, voc ver que eles seguem um padro semelhante.
7. Na janela Code and Text Editor, localize o mtodo showResult, que como este:
private void showResult(int answer)
{
result.Text = answer.ToString();
}

Esse mtodo contm uma instruo que exibe uma representao em string do
parmetro answer na caixa result. Ele no retorna um valor, de modo que o tipo
desse mtodo void.

Dica No h um comprimento mnimo para um mtodo. Se um mtodo ajuda


a evitar a repetio e a tornar seu programa mais fcil de entender, ele ser til,
independentemente do seu tamanho.
No h tambm um tamanho mximo para um mtodo, mas uma boa prtica
de programao mant-lo com o menor tamanho possvel. Se o mtodo ocupar
mais de uma tela, considere a possibilidade de dividi-lo em mtodos menores
para torn-lo mais legvel.

Chame mtodos
Os mtodos existem para serem chamados! Voc chama um mtodo pelo nome para
pedir a ele que execute sua tarefa. Se o mtodo precisar de informaes (conforme
especificado pelos seus parmetros), voc deve fornec-las. Se o mtodo retorna in-
formaes (conforme especificado pelo seu tipo de retorno), voc deve providenciar
sua captura de alguma maneira.

Especifique a sintaxe de chamada de mtodo


A sintaxe de uma chamada de mtodo em C# :
resultado = nomeDoMtodo (listaDeArgumentos)

Descrio dos elementos que constituem uma chamada de mtodo:


j O nomeDoMtodo deve corresponder exatamente ao nome do mtodo que
voc est chamando. Lembre-se, o C# uma linguagem que faz distino entre
maisculas e minsculas.
j A clusula resultado = opcional. Se especificada, a varivel identificada como
resultado conter o valor retornado pelo mtodo. Se o mtodo for void (no
retorna um valor), voc deve omitir a clusula resultado = da instruo. Se voc
no especificar a clusula resultado = e o mtodo retornar um valor, o mtodo
ser executado, mas o valor de retorno ser descartado.

_Livro_Sharp_Visual.indb 69 30/06/14 15:03


70 PARTE I Introduo ao Microsoft Visual C# e ao Microsoft Visual Studio 2013

j A listaDeArgumentos fornece as informaes que o mtodo aceita. Voc deve


fornecer um argumento para cada parmetro, e o valor de cada argumento deve
ser compatvel com o tipo do seu parmetro correspondente. Se o mtodo que
voc est chamando tiver dois ou mais parmetros, separe os argumentos com
vrgulas.

Importante Voc deve incluir os parnteses em cada chamada de mtodo,


mesmo quando estiver chamando um mtodo sem argumentos.

Para esclarecer esses pontos, examine o mtodo addValues novamente:


int addValues(int leftHandSide, int rightHandSide)
{
// ...
}

O mtodo addValues tem dois parmetros int; portanto, voc deve cham-lo
com dois argumentos int separados por vrgulas:
addValues(39, 3); // ok

Voc tambm pode substituir os valores literais 39 e 3 pelos nomes de variveis


int. Os valores dessas variveis so ento passados para o mtodo como seus argu-
mentos, como a seguir:
int arg1 = 99;
int arg2 = 1;
addValues(arg1, arg2);

Se voc tentar chamar addValues de alguma outra maneira, provavelmente no


ser bem-sucedido, pelas razes descritas nos exemplos abaixo:
addValues; // erro de tempo de compilao, nenhum parntese
addValues(); // erro de tempo de compilao, falta de argumentos
addValues(39); // erro de tempo de compilao, falta de argumentos
addValues("39", "3"); // erro de tempo de compilao, tipos de argumentos errados

O mtodo addValues retorna um valor int. Esse valor int poder ser utilizado
sempre que um valor int puder ser utilizado. Considere estes exemplos:
int result = addValues(39, 3); // no lado direito de uma atribuio
showResult(addValues(39, 3)); // como argumento para outra chamada de mtodo

O exerccio a seguir continua com o aplicativo Methods. Desta vez, voc vai exa-
minar algumas chamadas de mtodo.

_Livro_Sharp_Visual.indb 70 30/06/14 15:03


CAPTULO 3 Como escrever mtodos e aplicar escopo 71

Examine as chamadas de mtodo


1. Retorne ao projeto Methods. (Esse projeto j estar aberto no Visual Studio
2013, se voc estiver continuando do exerccio anterior. Se no, abra-o na pasta
\Microsoft Press\Visual CSharp Step By Step\Chapter 3\Windows X\Methods na
sua pasta Documentos.)
2. Exiba o cdigo de MainWindow.xaml.cs, na janela Code and Text Editor.
3. Localize o mtodo calculateClick e examine as duas primeiras instrues desse
mtodo aps a instruo try e uma chave de abertura. (Voc vai aprender sobre
as instrues try no Captulo 6, Gerenciamento de erros e excees.)
Essas instrues devem se parecer com isto:
int leftHandSide = System.Int32.Parse(lhsOperand.Text);
int rightHandSide = System.Int32.Parse(rhsOperand.Text);

Essas duas instrues declaram duas variveis int denominadas leftHandSide e


rightHandSide. Observe como as variveis so inicializadas. Em ambos os casos
chamado o mtodo Parse do tipo System.Int32. (System um namespace e
Int32 o nome do tipo nesse namespace.) Vimos esse mtodo anteriormente
ele recebe um nico parmetro string e o converte em um valor int. Essas duas
linhas de cdigo recebem as entradas do usurio nos controles caixa de texto
lhsOperand e rhsOperand do formulrio e as converte em valores int.
4. Examine a quarta instruo no mtodo calculateClick (aps a instruo if e outra
chave de abertura):
calculatedValue = addValues(leftHandSide, rightHandSide);

Essa instruo chama o mtodo addValues, passando os valores das variveis


leftHandSide e rightHandSide como argumentos. O valor retornado pelo mtodo
addValues armazenado na varivel calculatedValue.
5. Examine a prxima instruo:
showResult(calculatedValue);

Essa instruo chama o mtodo showResult, passando o valor da varivel calcu-


latedValue como argumento. O mtodo showResult no retorna um valor.
6. Na janela Code and Text Editor, localize o mtodo showResult examinado ante-
riormente.
A nica instruo desse mtodo esta:
result.Text = answer.ToString();

Observe que a chamada ao mtodo ToString utiliza parnteses embora no haja


argumentos.

_Livro_Sharp_Visual.indb 71 30/06/14 15:03


72 PARTE I Introduo ao Microsoft Visual C# e ao Microsoft Visual Studio 2013

Dica Voc pode chamar os mtodos que pertencem a outros objetos prefixan-
do o mtodo com o nome do objeto. No exemplo anterior, a expresso answer.
ToString() chama o mtodo denominado ToString pertencente ao objeto deno-
minado answer.

Aplique escopo
Para criar mtodos, voc combina instrues. Voc pode criar variveis facilmente
em vrios pontos de seu aplicativo. Por exemplo, o mtodo calculateClick do projeto
Methods cria uma varivel int chamada calculatedValue e atribui a ela o valor inicial
zero, como segue:
private void calculateClick(object sender, RoutedEventArgs e)
{
int calculatedValue = 0;
...
}

Essa varivel passa a existir a partir do ponto em que definida, e as instrues


subsequentes no mtodo calculateClick podem ento utiliz-la. Esse ponto impor-
tante: uma varivel s pode ser utilizada depois de ser criada. Quando o mtodo ter-
mina, essa varivel desaparece e no pode ser usada em outro lugar.
Quando uma varivel pode ser acessada em um local especfico em um progra-
ma, dizemos que ela est no escopo desse local. A varivel calculatedValue tem escopo
de mtodo; ela pode ser acessada por todo o mtodo calculateClick, mas no fora
dele. Tambm possvel definir variveis com escopo diferente; por exemplo, definir
uma varivel fora de um mtodo, mas dentro de uma classe essa varivel pode ser
acessada por qualquer mtodo dentro dessa classe. Diz-se que essa varivel tem es-
copo de classe.
Ou seja, o escopo de uma varivel simplesmente a regio do programa na qual
essa varivel utilizada. O escopo se aplica aos mtodos e s variveis. O escopo de
um identificador (de uma varivel ou mtodo) est vinculado ao local da declarao
que introduz o identificador no programa, como voc vai aprender a seguir.

Defina o escopo local


As chaves de abertura e fechamento que formam o corpo de um mtodo definem
o escopo desse mtodo. Todas as variveis que voc declara dentro do corpo de um
mtodo esto no seu escopo; elas desaparecem quando o mtodo termina e s po-
dem ser acessadas pelo cdigo executado dentro desse mtodo. Essas variveis so
denominadas variveis locais porque so locais para o mtodo em que so declaradas;
elas no esto no escopo de nenhum outro mtodo.
O escopo das variveis locais significa que no possvel utiliz-las para com-
partilhar informaes entre mtodos. Considere este exemplo:

_Livro_Sharp_Visual.indb 72 30/06/14 15:03


CAPTULO 3 Como escrever mtodos e aplicar escopo 73

class Example
{
void firstMethod()
{
int myVar;
...
}
void anotherMethod()
{
myVar = 42; // erro varivel fora de escopo
...
}
}

Ocorrer uma falha na compilao desse cdigo porque anotherMethod est


tentando utilizar a varivel myVar que no est no escopo. A varivel myVar s est
disponvel para as instrues em firstMethod que ocorrem depois da linha do cdigo
que a declara.

Defina o escopo de classe


As chaves de abertura e fechamento que formam o corpo de uma classe definem
o escopo dessa classe. Todas as variveis que voc declara dentro do corpo de uma
classe (mas no dentro de um mtodo) esto no escopo dela. O termo apropriado do
C# para uma varivel definida por uma classe field (campo). Conforme mencionado
anteriormente, ao contrrio das variveis locais, os campos podem ser utilizados para
compartilhar informaes entre mtodos. Veja um exemplo:
class Example
{
void firstMethod()
{
myField = 42; // ok
...
}
void anotherMethod()
{
myField++; // ok
...
}

int myField = 0;
}

A varivel myField definida dentro da classe, mas fora dos mtodos firstMethod
e anotherMethod. Portanto, myField tem escopo de classe e est disponvel para uso
por todos os mtodos dessa classe.
H outro ponto a ser observado nesse exemplo. Em um mtodo, voc deve de-
clarar uma varivel antes de poder utiliz-la. Os campos so um pouco diferentes. Um
mtodo pode utilizar um campo antes da instruo que define o campo o compila-
dor resolve os detalhes para voc.

_Livro_Sharp_Visual.indb 73 30/06/14 15:03


74 PARTE I Introduo ao Microsoft Visual C# e ao Microsoft Visual Studio 2013

Sobrecarregue mtodos
Se dois identificadores tm o mesmo nome e so declarados no mesmo escopo, dize-
mos que eles esto sobrecarregados. Um identificador sobrecarregado costuma ser um
erro capturado como um erro de tempo de compilao. Por exemplo, se voc declarar
duas variveis locais com o mesmo nome no mesmo mtodo, o compilador informar
um erro. Da mesma forma, se declarar dois campos com o mesmo nome na mesma
classe ou dois mtodos idnticos na mesma classe, tambm receber um erro de tem-
po de compilao. Talvez no valha a pena mencionar isso, uma vez que tudo que
vimos at aqui resulta em um erro de tempo de compilao. Mas h uma maneira til
e importante pela qual voc pode sobrecarregar um identificador para um mtodo.
Considere o mtodo WriteLine da classe Console. Voc j utilizou esse mtodo
para escrever uma string na tela. Mas ao digitar WriteLine na janela Code and Text Edi-
tor escrevendo em C#, note que o Microsoft IntelliSense oferece 19 opes diferentes!
Cada verso do mtodo WriteLine tem um conjunto de parmetros diferente; uma
verso no tem parmetros e simplesmente gera uma linha em branco; outra aceita
um parmetro bool e gera uma representao em string desse valor (True ou False);
ainda outra, aceita um parmetro decimal e gera uma string, e assim por diante. Em
tempo de compilao, o compilador examina os tipos de argumentos que voc est
passando e ento providencia para que seu aplicativo chame a verso do mtodo que
tem o conjunto de parmetros correspondente. Veja um exemplo:
static void Main()
{
Console.WriteLine(The answer is );
Console.WriteLine(42);
}

A sobrecarga til principalmente quando voc precisa executar a mesma ope-


rao em diferentes tipos de dados ou grupos variados de informaes. Voc pode so-
brecarregar um mtodo quando as diferentes implementaes tm diferentes conjun-
tos de parmetros isto , quando elas tm o mesmo nome, mas um nmero diferente
de parmetros, ou quando os tipos de parmetro forem diferentes. Quando chama um
mtodo, voc fornece uma lista de argumentos separados por vrgula; e o nmero e o
tipo dos argumentos so utilizados pelo compilador para selecionar um dos mtodos
sobrecarregados. Mas lembre-se de que, embora possa sobrecarregar os parmetros de
um mtodo, voc no pode sobrecarregar o tipo de retorno de um mtodo. Ou seja,
voc no pode declarar dois mtodos com o mesmo nome cuja diferena seja apenas o
seu tipo de retorno. (O compilador inteligente, mas no to inteligente.)

Escreva mtodos
Nos exerccios a seguir, voc vai criar um mtodo que calcula quanto um consultor
ganhar por um determinado nmero de dias de consultoria a uma dada remunera-
o por dia. Voc comear desenvolvendo a lgica do aplicativo e ento utilizar o
assistente Generate Method Stub para ajudar a escrever os mtodos que sero utiliza-
dos por essa lgica. Em seguida, voc executar esses mtodos em um aplicativo de
console para ter uma ideia do programa. Por fim, voc vai explorar o depurador do
Visual Studio 2013 para entrar e sair das chamadas de mtodo medida que elas so
executadas.

_Livro_Sharp_Visual.indb 74 30/06/14 15:03


CAPTULO 3 Como escrever mtodos e aplicar escopo 75

Desenvolva a lgica do aplicativo


1. Utilizando o Visual Studio 2013, abra o projeto DailyRate, que est na pasta
\Microsoft Press\Visual CSharp Step By Step\Chapter 3\Windows X\DailyRate na
sua pasta Documentos.
2. No Solution Explorer, no projeto DailyRate, clique duas vezes no arquivo Pro-
gram.cs para exibir o cdigo do programa na janela Code and Text Editor.
Esse programa simplesmente um teste para experimentar seu cdigo. Quando
o aplicativo comea a executar, ele chama o mtodo run. Voc pode adicionar o
mtodo run ao cdigo que deseja testar. (A maneira como o mtodo chamado
exige entendimento das classes, o que veremos no Captulo 7.)
3. Adicione as seguintes instrues mostradas em negrito ao corpo do mtodo run,
entre as chaves de abertura e de fechamento:
void run()
{
double dailyRate = readDouble(Enter your daily rate: );
int noOfDays = readInt(Enter the number of days: );
writeFee(calculateFee(dailyRate, noOfDays));
}

O bloco de cdigo que voc adicionou ao mtodo run chama o mtodo rea-
dDouble (que voc vai escrever em breve) para pedir ao usurio que informe a
taxa diria do consultor. A prxima instruo chama o mtodo readInt (que voc
tambm vai escrever) para obter o nmero de dias. Por fim, o mtodo writeFee
(a ser escrito) chamado para exibir os resultados na tela. Observe que o valor
passado para writeFee o valor retornado pelo mtodo calculateFee (o ltimo
que precisar ser escrito), ao qual informado o preo por dia e o nmero de
dias, e calcula a taxa total a ser paga.

Nota Voc ainda no escreveu os mtodos readDouble, readInt, writeFee e


calculateFee; portanto, o IntelliSense no exibir esses mtodos quando voc
digitar esse cdigo. No tente compilar o aplicativo ainda ele falhar.

Escreva os mtodos utilizando o assistente Generate Method Stub


1. Na janela Code and Text Editor, no mtodo run, clique com o boto direito do
mouse na chamada de mtodo readDouble.
Um menu de atalho aparece, contendo comandos teis para gerar e editar c-
digo, como mostrado aqui:

_Livro_Sharp_Visual.indb 75 30/06/14 15:03


76 PARTE I Introduo ao Microsoft Visual C# e ao Microsoft Visual Studio 2013

2. Nesse menu de atalho, aponte para Generate e clique em Method Stub.


O assistente Generate Method Stub examina a chamada ao mtodo readDouble,
verifica o tipo dos seus parmetros e do valor de retorno e gera um mtodo com
uma implementao padro, como mostrado a seguir:
private double readDouble(string p)
{
throw new NotImplementedException();
}

O novo mtodo criado com o qualificador private, descrito no Captulo 7.


Atualmente o corpo do mtodo simplesmente lana uma exceo NotImple-
mentedException. (As excees sero descritas no Captulo 6.) Voc vai substituir
o corpo pelo seu prprio cdigo no prximo passo.
3. Exclua a instruo throw new NotImplementedException(); do mtodo readDou-
ble e a substitua pelas linhas de cdigo em negrito a seguir:
private double readDouble(string p)
{
Console.Write(p);
string line = Console.ReadLine();
return double.Parse(line);
}

_Livro_Sharp_Visual.indb 76 30/06/14 15:03


CAPTULO 3 Como escrever mtodos e aplicar escopo 77

Esse bloco de cdigo exibe a string da varivel p na tela. Essa varivel o pa-
rmetro de string que passado quando o mtodo chamado; ele contm a
mensagem solicitando que o usurio digite a taxa diria.

Nota O mtodo Console.Write semelhante instruo Console.WriteLi-


ne j utilizada nos exerccios anteriores, exceto pelo fato de no gerar um
caractere de nova linha depois da mensagem.

O usurio digita um valor, o qual lido em um tipo string utilizando o mtodo


ReadLine e convertido em um tipo double utilizando o mtodo double.Parse. O
resultado passado de volta como o valor de retorno da chamada de mtodo.

Nota O mtodo ReadLine companheiro do mtodo WriteLine; ele l a


entrada do usurio no teclado, terminando quando o usurio pressiona a
tecla Enter. O texto digitado pelo usurio passado de volta como o valor
de retorno. O texto retornado como um valor de string.

4. No mtodo run, clique com o boto direito do mouse na chamada ao mtodo


readInt, aponte para Generate e clique em Method Stub para gerar o mtodo
readInt.
O mtodo readInt gerado desta maneira:
private int readInt(string p)
{
throw new NotImplementedException();
}

5. Substitua a instruo throw new NotImplementedException(); no corpo do mto-


do readInt pelo cdigo em negrito a seguir:
private int readInt(string p)
{
Console.Write(p);
string line = Console.ReadLine();
return int.Parse(line);
}

Esse bloco de cdigo semelhante ao cdigo do mtodo readDouble. A nica


diferena que o mtodo retorna um valor int; portanto, a string digitada pelo
usurio convertida em um nmero, utilizando o mtodo int.Parse.
6. Clique com o boto direito do mouse na chamada ao mtodo calculateFee den-
tro do mtodo run, aponte para Generate e clique em Method Stub.

_Livro_Sharp_Visual.indb 77 30/06/14 15:03


78 PARTE I Introduo ao Microsoft Visual C# e ao Microsoft Visual Studio 2013

O mtodo calculateFee gerado desta maneira:


private object calculateFee(double dailyRate, int noOfDays)
{
throw new NotImplementedException();
}

Nesse caso, observe que o Visual Studio utiliza os nomes dos argumentos passa-
dos para gerar os nomes dos parmetros. (Evidentemente, voc pode alterar os
nomes dos parmetros se eles no forem adequados.) O mais intrigante o tipo
retornado pelo mtodo, que object. O Visual Studio incapaz de determinar
exatamente que tipo de valor deve ser retornado pelo mtodo a partir do con-
texto em que ele chamado. O tipo object significa apenas uma coisa, e voc
deve alter-lo para o tipo necessrio quando adicionar o cdigo ao mtodo. O
Captulo 7 abordar o tipo object com mais detalhes.
7. Mude a definio do mtodo calculateFee para que ele retorne um double, como
mostrado em negrito aqui:
private double calculateFee(double dailyRate, int noOfDays)
{
throw new NotImplementedException();
}

8. Substitua o corpo do mtodo calculateFee pela instruo em negrito a seguir,


que calcula e retorna a remunerao a ser paga, multiplicando os dois parme-
tros:
private double calculateFee(double dailyRate, int noOfDays)
{
return dailyRate * noOfDays;
}

9. Clique com o boto direito do mouse na chamada ao mtodo writeFee dentro


do mtodo run, clique em Generate e clique em Method Stub.
Observe que o Visual Studio utiliza a definio do mtodo calculateFee para
concluir que seu parmetro deve ser double. Alm disso, a chamada do mtodo
no utiliza um valor de retorno, portanto, o tipo do mtodo void:
private void writeFee(double p)
{
...
}

Dica Se voc se sentir vontade com a sintaxe, tambm pode escrever


os mtodos digitando-os diretamente na janela Code and Text Editor. No
necessrio utilizar sempre a opo de menu Generate.

_Livro_Sharp_Visual.indb 78 30/06/14 15:03


CAPTULO 3 Como escrever mtodos e aplicar escopo 79

10. Substitua o cdigo do corpo do mtodo writeFee pela instruo a seguir, que
calcula a taxa e adiciona 10% de comisso:
Console.WriteLine("The consultants fee is: {0}", p * 1.1);

Nota Essa verso do mtodo WriteLine demonstra o uso de uma string


de formato simples. O texto {0} na string utilizada como o primeiro argu-
mento para o mtodo WriteLine um espao reservado que substitudo
pelo valor da expresso depois da string (p * 1.1), quando ela avaliada
em tempo de execuo. O uso dessa tcnica prefervel s alternativas,
como converter o valor da expresso p * 1.1 em uma string e utilizar o
operador + para concaten-la mensagem.

11. No menu Build, clique em Build Solution.

Refatorao de cdigo
Um recurso muito til do Visual Studio 2013 a capacidade de refatorar o cdigo.
Ocasionalmente, voc perceber que est escrevendo o mesmo cdigo (ou
semelhante) em mais de um lugar em um aplicativo. Quando isso ocorrer, realce e
clique com o boto direito do mouse no bloco de cdigo que voc acabou de di-
gitar e, ento, no menu Refactor que aparece, clique em Extract Method. A caixa
de dilogo Extract Method se abre, solicitando o nome de um novo mtodo que
conter esse cdigo. Digite um nome e clique em OK. O novo mtodo criado
contendo seu cdigo, e o cdigo que voc digitou substitudo por uma chama-
da a esse mtodo. Extract Method tambm capaz de identificar se o mtodo
deve ter algum parmetro e retornar um valor.

Teste o programa
1. No menu Debug, clique em Start Without Debugging.
O Visual Studio 2013 compila o programa e o executa. Uma janela de console
aparece.
2. No prompt Enter Your Daily Rate, digite 525 e pressione Enter.
3. No prompt Enter the Number of Days, digite 17 e pressione Enter.
O programa escreve a seguinte mensagem na janela de console:
The consultants fee is: 9817.5

4. Pressione a tecla Enter para finalizar o programa e retornar ao Visual Studio


2013.
No prximo exerccio, voc vai utilizar o depurador do Visual Studio 2013 para
executar seu programa lentamente. Voc vai ver quando cada mtodo chamado (o
que citado como stepping into the method) e como cada instruo return transfere o
controle de volta ao chamador (tambm conhecido como stepping out of the method

_Livro_Sharp_Visual.indb 79 30/06/14 15:03


80 PARTE I Introduo ao Microsoft Visual C# e ao Microsoft Visual Studio 2013

ou sair do mtodo). Ao entrar e sair dos mtodos, voc pode utilizar as ferramentas
da barra de ferramentas Debug. Mas os mesmos comandos tambm esto disponveis
no menu Debug quando um aplicativo est sendo executado no modo de depurao.

Inspecione os mtodos passo a passo utilizando o depurador do


Visual Studio 2013
1. Na janela Code and Text Editor, localize o mtodo run.
2. Mova o cursor para a primeira instruo do mtodo run.
double dailyRate = readDouble(Enter your daily rate: );

3. Clique com o boto direito do mouse em qualquer lugar dessa linha e, no menu
de atalho que aparece, clique em Run To Cursor.
O programa inicia e executado at chegar primeira instruo do mtodo run
e, ento, faz uma pausa. Uma seta amarela na margem esquerda da janela Code
and Text Editor indica a instruo atual, e a instruo em si realada com um
fundo amarelo.

4. No menu View, aponte para Toolbars e verifique se a barra de ferramentas De-


bug est selecionada.
Se ela ainda no estiver visvel, a barra de ferramentas Debug aberta. Ela pode
aparecer encaixada com as outras barras de ferramentas. Se no puder ver a bar-
ra de ferramentas, tente utilizar o comando Toolbars no menu View para ocult-
-la e observe quais botes desaparecem. Ento, exiba a barra de ferramentas
novamente. A barra de ferramentas Debug parecida com esta:

_Livro_Sharp_Visual.indb 80 30/06/14 15:03


CAPTULO 3 Como escrever mtodos e aplicar escopo 81

Continue Step over

Step into Step out

5. Na barra de ferramentas Debug, clique no boto Step Into. ( o stimo boto a


partir da esquerda na barra de ferramentas Debug.)
Essa ao faz o depurador entrar no mtodo chamado. O cursor amarelo pula
para a chave de abertura no incio do mtodo readDouble.
6. Clique em Step Into novamente para avanar o cursor at a primeira instruo:
Console.Write(p);

Dica Voc tambm pode pressionar F11 em vez de clicar vrias vezes em
Step Into na barra de ferramentas Debug.

7. Na barra de ferramentas Debug, clique em Step Over. ( o oitavo boto a partir


da esquerda.)
Essa ao faz o mtodo executar a prxima instruo sem depur-la (sem entrar
nela). A ao til principalmente se a instruo chama um mtodo, mas voc
no quer passar por cada instruo desse mtodo. O cursor amarelo se move
para a segunda instruo do mtodo e o programa exibe o prompt Enter Your
Daily Rate em uma janela de console, antes de retornar ao Visual Studio 2013. (A
janela de console pode estar oculta atrs do Visual Studio.)

Dica Voc tambm pode pressionar F10 em vez de clicar em Step Over
na barra de ferramentas Debug.

8. Na barra de ferramentas Debug, clique novamente em Step Over.


Desta vez, o cursor amarelo desaparece e a janela de console recebe o foco por-
que o programa est executando o mtodo Console.ReadLine e esperando que
voc digite algo.
9. Digite 525 na janela de console e pressione Enter.
O controle retorna ao Visual Studio 2013. O cursor amarelo aparece na terceira
linha do mtodo.
10. Posicione o mouse sobre a referncia varivel line na segunda ou na terceira
linha do mtodo. (No importa qual delas.)
Uma dica de tela aparece, exibindo o valor atual da varivel line (525). Voc
pode utilizar esse recurso para verificar se uma varivel foi definida com um
valor esperado durante a execuo passo a passo dos mtodos.

_Livro_Sharp_Visual.indb 81 30/06/14 15:03


82 PARTE I Introduo ao Microsoft Visual C# e ao Microsoft Visual Studio 2013

11. Na barra de ferramentas Debug, clique em Step Out. ( o nono boto a partir da
esquerda.)
Essa ao faz o mtodo atual continuar executando ininterruptamente at o
fim. O mtodo readDouble termina e o cursor amarelo colocado de volta na
primeira instruo do mtodo run. Agora terminou a execuo dessa instruo.

Dica Voc tambm pode pressionar Shift+F11 em vez de clicar em Step


Out na barra de ferramentas Debug.

12. Na barra de ferramentas Debug, clique em Step Into.


O cursor amarelo se move para a segunda instruo no mtodo run:
int noOfDays = readInt(Enter the number of days: );

13. Na barra de ferramentas Debug, clique em Step Over.


Desta vez, voc optou por executar o mtodo sem entrar nele. A janela de con-
sole aparece novamente solicitando o nmero de dias.
14. Na janela de console, digite 17 e pressione Enter.
O controle volta para o Visual Studio 2013 (talvez seja necessrio trazer o Visual
Studio para o primeiro plano). O cursor amarelo se move para a terceira instru-
o do mtodo run:
writeFee(calculateFee(dailyRate, noOfDays));

15. Na barra de ferramentas Debug, clique em Step Into.


O cursor amarelo pula para a chave de abertura no incio do mtodo calculate-
Fee. Esse mtodo o primeiro a ser chamado, antes de writeFee, porque o valor
retornado por esse mtodo utilizado como o parmetro para writeFee.
16. Na barra de ferramentas Debug, clique em Step Out.
A chamada do mtodo calculateFee termina e o cursor amarelo salta para a ter-
ceira instruo do mtodo run.
17. Na barra de ferramentas Debug, clique em Step Into.
Desta vez, o cursor amarelo pula para a chave de abertura no incio do mtodo
writeFee.
18. Coloque o mouse sobre o parmetro p na definio do mtodo.
O valor de p, 8925.0, aparece em uma dica de tela.

_Livro_Sharp_Visual.indb 82 30/06/14 15:03


CAPTULO 3 Como escrever mtodos e aplicar escopo 83

19. Na barra de ferramentas Debug, clique em Step Out.


A mensagem The consultants fee is: 9817.5 aparece na janela de console. (Tal-
vez seja necessrio trazer a janela de console para o primeiro plano para exibi-
-la, caso esteja atrs do Visual Studio 2013.) O cursor amarelo retorna terceira
instruo do mtodo run.
20. No menu Debug, clique em Continue para fazer o programa continuar execu-
tando sem parar em cada instruo.

Dica Se o boto Continue no estiver visvel, clique no menu suspenso


Add or Remove Buttons que aparece na extremidade da barra de ferra-
mentas Debug e, ento, selecione Continue. Agora o boto Continue de-
ver aparecer. Como alternativa, voc pode pressionar F5 para continuar a
execuo do aplicativo sem depurar.

O aplicativo termina e para de executar. Observe que a barra de ferramentas


Debug desaparece quando o aplicativo termina por padro, ela s aparece
quando um aplicativo est sendo executado no modo de depurao.

Parmetros opcionais e argumentos nomeados


Voc j sabe que, ao definir mtodos sobrecarregados, possvel implementar diversas
verses de um mtodo, que aceitam diferentes parmetros. Quando voc constri um
aplicativo que utiliza mtodos sobrecarregados, o compilador determina quais instn-
cias especficas de cada mtodo deve usar para atender chamada de cada mtodo.
Esse um recurso comum de vrias linguagens orientadas a objetos, no apenas do C#.
Entretanto, os desenvolvedores podem utilizar outras linguagens e tecnologias
que no seguem essas regras para construir aplicativos Windows e componentes. Um
recurso importante do C# e de outras linguagens elaboradas para o .NET Framework
a possibilidade de interagir com aplicativos e componentes escritos em outras tec-
nologias. Uma das principais tecnologias que servem de base para muitos aplicativos
Microsoft Windows e servios executados fora do .NET Framework o Component
Object Model (COM). Na verdade, o Common Language Runtime (CLR) utilizado pelo
.NET Framework tambm fortemente dependente do COM, assim como o Windows
Runtime do Windows 8 e do Windows 8.1. O COM no aceita mtodos sobrecarrega-
dos; em vez disso, utiliza mtodos que admitem parmetros opcionais. Para facilitar
ainda mais a incorporao de bibliotecas COM e componentes em uma soluo do
C#, esta linguagem tambm dispe de suporte para parmetros opcionais.
Os parmetros opcionais tambm so teis em outras situaes. Eles represen-
tam uma soluo compacta e simples, quando no possvel utilizar sobrecarga por-
que os tipos dos parmetros no variam o bastante para permitir que o compilador
possa distinguir entre as implementaes. Por exemplo, considere o seguinte mtodo:
public void DoWorkWithData(int intData, float floatData, int moreIntData)
{
...
}

_Livro_Sharp_Visual.indb 83 30/06/14 15:03


84 PARTE I Introduo ao Microsoft Visual C# e ao Microsoft Visual Studio 2013

O mtodo DoWorkWithData aceita trs parmetros: dois int e um float. Vamos


supor que voc queira fornecer uma implementao do mtodo DoWorkWithData
que aceite apenas dois parmetros: intData e floatData. Voc pode sobrecarregar o
mtodo, como demonstrado a seguir:
public void DoWorkWithData(int intData, float floatData)
{
...
}

Se voc escrever uma instruo que chama o mtodo DoWorkWithData, poder


fornecer dois ou trs parmetros dos tipos adequados, e o compilador usar a infor-
mao do tipo para determinar a sobrecarga a ser chamada:
int arg1 = 99;
float arg2 = 100.0F;
int arg3 = 101;

DoWorkWithData(arg1, arg2, arg3); // Chama a sobrecarga com trs parmetros


DoWorkWithData(arg1, arg2); // Chama a sobrecarga com dois parmetros

Entretanto, vamos supor que voc queira implementar duas outras verses do
mtodo DoWorkWithData, que aceitem apenas o primeiro e o terceiro parmetros.
Voc poderia experimentar o seguinte:
public void DoWorkWithData(int intData)
{
...
}

public void DoWorkWithData(int moreIntData)


{
...
}

O problema aqui que, para o compilador, essas duas sobrecargas parecem


idnticas. A compilao de seu cdigo falhar e gerar o erro Type typename already
defines a member called DoWorkWithData with the same parameter types (o tipo
nome_do_tipo j define um membro chamado DoWorkWithData com os mesmos
tipos de parmetro). Para entender por que isso acontece, se esse cdigo fosse vlido,
considere as seguintes instrues:
int arg1 = 99;
int arg3 = 101;

DoWorkWithData(arg1);
DoWorkWithData(arg3);

Que sobrecarga ou sobrecargas as chamadas ao mtodo DoWorkWithData acio-


nariam? O uso de parmetros opcionais e argumentos nomeados pode ajudar a solu-
cionar esse problema.

_Livro_Sharp_Visual.indb 84 30/06/14 15:03


CAPTULO 3 Como escrever mtodos e aplicar escopo 85

Defina parmetros opcionais


Ao definir um mtodo, voc especifica que um parmetro opcional fornecendo um
valor padro para o parmetro. Para indicar um valor padro, utilize um operador de
atribuio. No mtodo optMethod mostrado a seguir, o parmetro first obrigatrio
porque no especifica um valor padro, mas os parmetros second e third so opcionais:
void optMethod(int first, double second = 0.0, string third = Hello)
{
...
}

Voc deve especificar todos os parmetros obrigatrios antes de qualquer pa-


rmetro opcional.
Chame um mtodo que aceita parmetros opcionais da mesma maneira como
voc chama qualquer outro mtodo: especifique o nome do mtodo e inclua os ar-
gumentos necessrios. A diferena em relao aos mtodos que aceitam parmetros
opcionais a possibilidade de omitir os argumentos correspondentes o mtodo
usar o valor padro quando for executado. No exemplo de cdigo a seguir, a pri-
meira chamada ao mtodo optMethod fornece os valores dos trs parmetros. A se-
gunda chamada especifica apenas dois argumentos, e esses valores so aplicados aos
parmetros first e second. O parmetro third recebe o valor padro Hello quando o
mtodo executado.
optMethod(99, 123.45, World); // Argumentos fornecidos para os trs parmetros
optMethod(100, 54.321); // Argumentos fornecidos apenas para os dois
primeiros parmetros

Passe argumentos nomeados


Por padro, o C# utiliza a posio de cada argumento na chamada a um mtodo para
determinar os parmetros aos quais eles se aplicam. Portanto, o segundo exemplo de
mtodo mostrado na seo anterior passa os dois argumentos para os parmetros first
e second no mtodo optMethod, porque essa a sequncia na qual eles ocorrem na
declarao do mtodo. No C# tambm possvel especificar parmetros pelo nome.
Esse recurso permite passar os argumentos em uma sequncia diferente. Para passar
um argumento como um parmetro nomeado, especifique o nome do parmetro, se-
guido por um caractere de dois-pontos e o valor a ser utilizado. Os exemplos a seguir
desempenham a mesma funo daqueles apresentados na seo anterior, exceto pelo
fato de que os parmetros so especificados por nome:
optMethod(first : 99, second : 123.45, third : World);
optMethod(first : 100, second : 54.321);

Os argumentos nomeados permitem que voc passe os argumentos em qual-


quer ordem. Voc pode reescrever o cdigo que chama o mtodo optMethod, como
mostrado aqui:
optMethod(third : World, second : 123.45, first : 99);
optMethod(second : 54.321, first : 100);

_Livro_Sharp_Visual.indb 85 30/06/14 15:03


86 PARTE I Introduo ao Microsoft Visual C# e ao Microsoft Visual Studio 2013

Esse recurso tambm torna possvel omitir os argumentos. Por exemplo, voc
pode chamar o mtodo optMethod e especificar apenas os valores dos parmetros first
e third e utilizar o valor padro para o parmetro second, como a seguir:
optMethod(first : 99, third : World);

Alm disso, possvel mesclar argumentos posicionais e nomeados. Entretanto,


ao utilizar essa tcnica, voc deve especificar todos os argumentos posicionais antes
do primeiro argumento nomeado.
optMethod(99, third : World); // O primeiro argumento posicional

Resolva ambiguidades com parmetros opcionais e


argumentos nomeados
O uso de parmetros opcionais e argumentos nomeados pode gerar algumas ambi-
guidades em seu cdigo. Voc deve saber como o compilador resolve essas ambigui-
dades; caso contrrio, seus aplicativos podero se comportar de modo imprevisto. Va-
mos supor que voc defina o mtodo optMethod como um mtodo sobrecarregado,
como mostra o exemplo a seguir:
void optMethod(int first, double second = 0.0, string third = Hello)
{
...
}

void optMethod(int first, double second = 1.0, string third = Goodbye, int fourth
= 100 )
{
...
}

Esse um cdigo do C# perfeitamente vlido que segue as regras dos mtodos


sobrecarregados. O compilador pode diferenciar entre os mtodos porque eles tm
listas de parmetros diferentes. Entretanto, como demonstrado no exemplo a seguir,
pode ocorrer um problema se voc tentar chamar o mtodo optMethod e omitir al-
gum dos argumentos correspondentes a um ou mais parmetros opcionais:
optMethod(1, 2.5, "World");

Mais uma vez, um cdigo vlido, mas ele executa qual verso do mtodo opt-
Method? A resposta que ele executa a verso que mais se aproxima da chamada ao
mtodo, de modo que ele chama o mtodo que aceita trs parmetros, e no a verso
que aceita quatro. Isso justificvel; portanto, considere o seguinte:
optMethod(1, fourth : 101);

Nesse cdigo, a chamada ao mtodo optMethod omite os argumentos dos pa-


rmetros second e third, mas especifica o parmetro fourth pelo nome. Apenas uma
verso do mtodo optMethod corresponde a essa chamada, de modo que no ocorre
qualquer problema. Entretanto, o prximo cdigo vai deix-lo intrigado:
optMethod(1, 2.5);

_Livro_Sharp_Visual.indb 86 30/06/14 15:03


CAPTULO 3 Como escrever mtodos e aplicar escopo 87

Desta vez, nenhuma das verses do mtodo optMethod combina exatamente


com a lista de argumentos fornecida. Ambas as verses desse mtodo tm parmetros
opcionais para o segundo, terceiro e quarto argumentos. Ento, essa instruo chama
a verso do mtodo optMethod que aceita trs parmetros e utiliza o valor padro
para o parmetro third ou chama a verso do optMethod que aceita quatro par-
metros e utiliza o valor padro para os parmetros third e fourth? A resposta : nem
uma coisa, nem outra. Essa uma ambiguidade insolvel e o compilador no permite
a compilao do aplicativo. A mesma situao ocorrer, com o mesmo resultado, se
voc tentar chamar o mtodo optMethod como mostrado em qualquer uma das se-
guintes instrues:
optMethod(1, third : World);
optMethod(1);
optMethod(second : 2.5, first : 1);

No ltimo exerccio deste captulo, voc vai praticar a implementao de m-


todos que aceitam parmetros opcionais e vai cham-los por meio de argumentos
nomeados. Voc tambm testar exemplos comuns de como o compilador do C#
resolve as chamadas a mtodos que englobam parmetros opcionais e argumentos
nomeados.

Defina e chame um mtodo que aceita parmetros opcionais


1. No Visual Studio 2013, abra o projeto DailyRate, que est na pasta \Microsoft
Press\Visual CSharp Step By Step\Chapter 3\Windows X\DailyRate Using Optio-
nal Parameters na pasta Documentos.
2. No Solution Explorer, no projeto DailyRate, clique duas vezes no arquivo Pro-
gram.cs para exibir o cdigo do programa na janela Code and Text Editor.
Essa verso do aplicativo est vazia, a no ser pelo mtodo Main e o esqueleto
da verso do mtodo run.
3. Na classe Program, adicione o mtodo calculateFee abaixo do mtodo run. Essa
a mesma verso do mtodo implementado no conjunto anterior de exerc-
cios, exceto pelo fato de aceitar dois parmetros opcionais com valores padro.
O mtodo tambm imprime uma mensagem que indica a verso chamada do
mtodo calculateFee. (Nas etapas a seguir, voc adicionar as verses sobrecar-
regadas desse mtodo.)
private double calculateFee(double dailyRate = 500.0, int noOfDays = 1)
{
Console.WriteLine(calculateFee using two optional parameters);
return dailyRate * noOfDays;
}

4. Adicione outra implementao do mtodo calculateFee classe Program, como


mostrado a seguir. Essa verso aceita um nico parmetro, chamado dailyRate,
do tipo double. O corpo do mtodo calcula e retorna a taxa de um nico dia.
private double calculateFee(double dailyRate = 500.0)
{
Console.WriteLine(calculateFee using one optional parameter);
int defaultNoOfDays = 1;

_Livro_Sharp_Visual.indb 87 30/06/14 15:03


88 PARTE I Introduo ao Microsoft Visual C# e ao Microsoft Visual Studio 2013

return dailyRate * defaultNoOfDays;


}

5. Adicione uma terceira implementao do mtodo calculateFee classe Program.


Essa verso no aceita parmetros e utiliza os valores codificados para a taxa
diria e o nmero de dias.
private double calculateFee()
{
Console.WriteLine(calculateFee using hardcoded values);
double defaultDailyRate = 400.0;
int defaultNoOfDays = 1;
return defaultDailyRate * defaultNoOfDays;
}

6. No mtodo run, adicione as seguintes instrues em negrito, que chamam cal-


culateFee e exibem os resultados:
public void run()
{
double fee = calculateFee();
Console.WriteLine(Fee is {0}, fee);
}

Dica possvel ver rapidamente a definio de um mtodo a partir da instru-


o que o chama. Para isso, clique com o boto direito do mouse na chamada
do mtodo e, ento, no menu de atalho que aparece, clique em Peek Definition.
A imagem a seguir mostra a janela Peek Definition para o mtodo calculateFee.

Esse recurso extremamente til se seu cdigo est dividido em vrios arquivos
ou mesmo se est no mesmo arquivo, mas este muito longo.

_Livro_Sharp_Visual.indb 88 30/06/14 15:03


CAPTULO 3 Como escrever mtodos e aplicar escopo 89

7. No menu Debug, clique em Start Without Debugging para compilar e executar


o aplicativo.
O programa executado em uma janela de console e exibe as seguintes
mensagens:
calculateFee using hardcoded values
Fee is 400

O mtodo run chamou a verso de calculateFee que no aceita parmetros e


no as implementaes que aceitam parmetros opcionais, pois a verso mais
compatvel com a chamada do mtodo.
Pressione qualquer tecla para fechar a janela do console e retornar ao Visual
Studio.
8. No mtodo run, modifique a instruo que chama calculateFee, de acordo com
o cdigo mostrado em negrito neste exemplo:
public void run()
{
double fee = calculateFee(650.0);
Console.WriteLine(Fee is {0}, fee);
}

9. No menu Debug, clique em Start Without Debugging para compilar e executar


o aplicativo.
O programa exibe as seguintes mensagens:
calculateFee using one optional parameter
Fee is 650

Desta vez, o mtodo run chamou a verso de calculateFee que aceita um nico
parmetro opcional. Como antes, isso acontece porque essa a verso que mais
se aproxima da chamada do mtodo.
Pressione qualquer tecla para fechar a janela do console e retornar ao Visual Studio.
10. No mtodo run, modifique novamente a instruo que chama calculateFee:
public void run()
{
double fee = calculateFee(500.0, 3);
Console.WriteLine(Fee is {0}, fee);
}

11. No menu Debug, clique em Start Without Debugging para compilar e executar
o aplicativo.
O programa exibe as seguintes mensagens:
calculateFee using two optional parameters
Fee is 1500

Como voc j previa, com base nos dois casos anteriores, o mtodo run chamou
a verso de calculateFee que aceita dois parmetros opcionais.
Pressione qualquer tecla para fechar a janela do console e retornar ao Visual
Studio.

_Livro_Sharp_Visual.indb 89 30/06/14 15:03


90 PARTE I Introduo ao Microsoft Visual C# e ao Microsoft Visual Studio 2013

12. No mtodo run, modifique a instruo que chama calculateFee e especifique o


parmetro dailyRate pelo nome:
public void run()
{
double fee = calculateFee(dailyRate : 375.0);
Console.WriteLine(Fee is {0}, fee);
}

13. No menu Debug, clique em Start Without Debugging para compilar e executar
o aplicativo.
O programa exibe as seguintes mensagens:
calculateFee using one optional parameter
Fee is 375

Como antes, o mtodo run chama a verso de calculateFee que aceita um nico
parmetro opcional. Mudar o cdigo para utilizar um argumento nomeado no
altera o modo como o compilador resolve a chamada ao mtodo neste exemplo.
Pressione qualquer tecla para fechar a janela do console e retornar ao Visual
Studio.
14. No mtodo run, modifique a instruo que chama calculateFee e especifique o
parmetro noOfDays pelo nome:
public void run()
{
double fee = calculateFee(noOfDays : 4);
Console.WriteLine(Fee is {0}, fee);
}

15. No menu Debug, clique em Start Without Debugging para compilar e executar
o aplicativo.
O programa exibe as seguintes mensagens:
calculateFee using two optional parameters
Fee is 2000

Desta vez, o mtodo run chamou a verso de calculateFee que aceita dois pa-
rmetros opcionais. A chamada do mtodo omitiu o primeiro parmetro (dai-
lyRate) e especificou o segundo parmetro pelo nome. Essa verso do mtodo
calculateFee que aceita dois parmetros opcionais a nica que coincide com
a chamada.
Pressione qualquer tecla para fechar a janela do console e retornar ao Visual
Studio.
16. Modifique a implementao do mtodo calculateFee que aceita dois parmetros
opcionais. Mude o nome do primeiro parmetro para theDailyRate e atualize a
instruo return, como mostrado em negrito no cdigo a seguir:
private double calculateFee(double theDailyRate = 500.0, int noOfDays = 1)
{
Console.WriteLine(calculateFee using two optional parameters);
return theDailyRate * noOfDays;
}

_Livro_Sharp_Visual.indb 90 30/06/14 15:03


CAPTULO 3 Como escrever mtodos e aplicar escopo 91

17. No mtodo run, modifique a instruo que chama calculateFee e especifique o


parmetro theDailyRate pelo nome:
public void run()
{
double fee = calculateFee(theDailyRate : 375.0);
Console.WriteLine(Fee is {0}, fee);
}

18. No menu Debug, clique em Start Without Debugging para compilar e executar
o aplicativo.
O programa exibe as seguintes mensagens:
calculateFee using two optional parameters
Fee is 375

Quando voc especificou a taxa, mas no a diria (passo 13), o mtodo run cha-
mou a verso de calculateFee que aceita um nico parmetro opcional. Desta
vez, o mtodo run chamou a verso de calculateFee que aceita dois parmetros
opcionais. Nesse caso, o uso de um argumento nomeado mudou o modo como
o compilador resolve a chamada do mtodo. Se voc especificar um argumento
nomeado, o compilador vai comparar o nome do argumento com os nomes dos
parmetros especificados nas declaraes de mtodos e selecionar o mtodo
que possui um parmetro com um nome correspondente. Se voc tivesse espe-
cificado o argumento como aDailyRate: 375.0 na chamada ao mtodo calculate-
Fee, o programa no seria compilado, pois nenhuma verso do mtodo tem um
parmetro que combine com esse nome.
Pressione qualquer tecla para fechar a janela do console e retornar ao Visual
Studio.

Resumo
Neste captulo, voc aprendeu a definir mtodos para implementar um bloco de cdi-
go nomeado e examinou como passar parmetros para os mtodos e como retornar
dados dos mtodos. Viu tambm como chamar um mtodo, passar argumentos e
obter um valor de retorno. Alm disso, aprendeu a definir mtodos sobrecarregados
com diferentes listas de parmetros e constatou que o escopo de uma varivel deter-
mina onde ela pode ser acessada. Depois, voc utilizou o depurador do Visual Studio
2013 para passar pelo cdigo ao longo de sua execuo. Por fim, aprendeu a escrever
mtodos que aceitam parmetros opcionais e a chamar mtodos por meio de par-
metros nomeados.
j Se quiser continuar no prximo captulo, mantenha o Visual Studio 2013 execu-
tando e v para o Captulo 4, Instrues de deciso.
j Se quiser encerrar o Visual Studio 2013 agora, no menu File, clique em Exit. Se vir
uma caixa de dilogo Save, clique em Yes e salve o projeto.

_Livro_Sharp_Visual.indb 91 30/06/14 15:03


92 PARTE I Introduo ao Microsoft Visual C# e ao Microsoft Visual Studio 2013

Referncia rpida

Para Faa isto


Declarar um mtodo Escreva o mtodo dentro de uma classe. Especifique o
nome do mtodo, a lista de parmetros e o tipo de retorno,
seguidos do corpo do mtodo entre chaves. Por exemplo:
int addValues(int leftHandSide, int rightHandSide)
{
...
}

Retornar um valor de dentro de Escreva uma instruo return dentro do mtodo. Por
um mtodo exemplo:
return leftHandSide + rightHandSide;

Retornar de um mtodo antes Escreva uma instruo return dentro do mtodo. Por
do seu final exemplo:
return;

Chamar um mtodo Escreva o nome do mtodo, junto com os argumentos entre


parnteses. Por exemplo:
addValues(39, 3);

Utilizar o assistente Generate D um clique com o boto direito em uma chamada para
Method Stub o mtodo e, ento, no menu de atalho, clique em Generate
Method Stub.
Exibir a barra de ferramentas No menu View, aponte para Toolbars e clique em Debug.
Debug
Entrar em um mtodo Na barra de ferramentas Debug, clique em Step Into.
ou
No menu Debug, clique em Step Into.
Sair de um mtodo Na barra de ferramentas Debug, clique em Step Out.
ou
No menu Debug, clique em Step Out.
Especificar um parmetro Fornea um valor padro para o parmetro na declarao
opcional para um mtodo do mtodo. Por exemplo:
void optMethod(int first, double second = 0.0,
string third = Hello)
{
...
}

Passar um argumento de Especifique o nome do parmetro na chamada do mtodo.


mtodo como parmetro Por exemplo:
nomeado
optMethod(first : 100, third : World);

_Livro_Sharp_Visual.indb 92 30/06/14 15:03


CAPTULO 4

Instrues de deciso
Neste captulo, voc vai aprender a:
j Declarar variveis booleanas.
j Utilizar os operadores booleanos para criar expresses cujo resultado verda-
deiro ou falso.
j Escrever instrues if para tomar decises baseadas no resultado de uma expres-
so booleana.
j Escrever instrues switch para tomar decises mais complexas.
O Captulo 3, Como escrever mtodos e aplicar escopo, mostrou como agrupar
instrues relacionadas em mtodos. Tambm ensinou como utilizar parmetros para
passar informaes para um mtodo e como fazer uso das instrues return para
passar informaes a partir de um mtodo. Considera-se uma estratgia necessria
a diviso de um programa em um conjunto de mtodos distintos, cada um deles
projetado para a execuo de uma tarefa ou clculo especfico. Uma quantidade con-
sidervel de programas precisa resolver problemas complexos. Dividir um programa
em mtodos auxilia no entendimento desses problemas e ajuda a focar a soluo de
uma parte a cada vez.
Os mtodos do Captulo 3 so muito diretos, em que cada instruo executada
sequencialmente aps o trmino da anterior. No entanto, para a resoluo de diversos
problemas do mundo real, tambm necessrio que voc escreva um cdigo que exe-
cute diferentes aes e que tomem diferentes caminhos em um mtodo, dependendo
das circunstncias. Este captulo mostra como realizar essa tarefa.

Declare variveis booleanas


No mundo da programao em C#, tudo preto ou branco, certo ou errado, verda-
deiro ou falso. Por exemplo, se voc criar uma varivel inteira chamada x, atribuir o va-
lor 99 a x e ento perguntar se x contm o valor 99, a resposta ser verdadeiro. Se voc
perguntar se x menor que 10, a resposta ser falso. Esses so exemplos de expresses
booleanas. Uma expresso booleana sempre avaliada como verdadeira ou falsa.

_Livro_Sharp_Visual.indb 93 30/06/14 15:03


94 PARTE I Introduo ao Microsoft Visual C# e ao Microsoft Visual Studio 2013

Nota As respostas a essas perguntas no so necessariamente definitivas para


todas as outras linguagens de programao. Uma varivel no atribuda contm
um valor indefinido e voc no pode, por exemplo, afirmar com preciso que
ela menor que 10. Questes como essas so uma fonte comum de erros nos
programas em C e C++. O compilador do Microsoft Visual C# resolve esse pro-
blema assegurando que um valor seja sempre atribudo a uma varivel antes de
examin-la. Se voc tentar examinar o contedo de uma varivel no atribuda,
o programa no compilar.

O Visual C# fornece um tipo de dado chamado bool. Uma varivel bool pode
armazenar um dos dois valores: verdadeiro ou falso. Por exemplo, as trs instrues a
seguir declaram uma varivel bool chamada areYouReady, atribuem o valor true a essa
varivel e ento escrevem seu valor no console:
bool areYouReady;
areYouReady = true;
Console.WriteLine(areYouReady); // escreve True no console

Operadores booleanos
Um operador booleano um operador que faz um clculo cujo resultado verdadeiro
ou falso. O C# tem vrios operadores booleanos muito teis, e o mais simples deles
o operador NOT, representado pelo ponto de exclamao (!). O operador ! nega um
valor booleano, resultando em valor oposto a esse. No exemplo anterior, se o valor da
varivel areYouReady fosse true, o valor da expresso !areYouReady seria falso.

Entenda os operadores de igualdade e relacionais


Dois operadores booleanos utilizados com frequncia so os operadores de igualdade
(==) e desigualdade (!=). Esses so operadores binrios, os quais permitem determinar
se um valor igual a outro valor de mesmo tipo, produzindo um resultado booleano.
A tabela a seguir resume como esses operadores funcionam, utilizando uma varivel
int chamada age como exemplo.

Operador Significado Exemplo O resultado se age for 42


== Igual a age == 100 falso
!= Diferente de age = 0 verdadeiro

No confunda o operador de igualdade == com o operador de atribuio =. A


expresso x==y compara x com y e tem o valor true se os valores forem idnticos. A
expresso x=y atribui o valor de y a x e retorna o valor de y como resultado.
Os operadores relacionais esto intimamente ligados aos operadores == e != .
Voc utiliza esses operadores para descobrir se um valor menor ou maior que outro
do mesmo tipo. A tabela a seguir mostra como utilizar esses operadores.

_Livro_Sharp_Visual.indb 94 30/06/14 15:03


CAPTULO 4 Instrues de deciso 95

Operador Significado Exemplo O resultado se age for 42


< Menor que age < 21 falso
<= Menor ou igual a age <= 18 falso
> Maior que age > 16 verdadeiro
>= Maior ou igual a age >= 30 verdadeiro

Entenda os operadores lgicos condicionais


O C# tambm fornece dois outros operadores booleanos binrios: o operador lgico
AND, representado pelo smbolo &&, e o operador lgico OR, representado pelo sm-
bolo ||. Coletivamente, eles so conhecidos como os operadores lgicos condicionais.
Seu propsito combinar duas expresses ou valores booleanos em um nico resul-
tado booleano. Esses operadores so semelhantes aos operadores relacionais e de
igualdade pelo fato de que o valor das expresses em que eles aparecem verdadeiro
ou falso, mas diferem pelo fato de que os valores em que eles operam tambm devem
ser verdadeiros ou falsos.
O resultado do operador && ser true se e somente se as duas expresses boole-
anas que est avaliando forem true. Por exemplo, a instruo a seguir atribuir o valor
true a validPercentage se e somente se o valor de percent for maior ou igual a 0 e o
valor de percent for menor ou igual a 100:
bool validPercentage;
validPercentage = (percent >= 0) && (percent <= 100);

Dica Um erro comum dos iniciantes tentar combinar os dois testes nomean-
do a varivel percent somente uma vez, como abaixo:
percent >= 0 && <= 100 // essa instruo no compilar

O uso de parnteses ajuda a evitar esse tipo de erro e tambm esclarece o objeti-
vo da expresso. Por exemplo, compare
validPercentage = percent >= 0 && percent <= 100;

e:
validPercentage = (percent >= 0) && (percent <= 100)

Ambas as expresses retornam o mesmo valor, porque a precedncia do ope-


rador && menor que a precedncia dos operadores >= e <=. Mas a segunda
expresso passa seu sentido de maneira mais legvel.

O resultado do operador || ser true se pelo menos uma das expresses boolea-
nas que avalia for true. O operador || utilizado para determinar se uma expresso de
uma combinao de expresses booleanas true. Por exemplo, a instruo a seguir
atribuir o valor true a invalidPercentage se o valor de percent for menor que 0 ou se o
valor de percent for maior que 100:
bool invalidPercentage;
invalidPercentage = (percent < 0) || (percent > 100);

_Livro_Sharp_Visual.indb 95 30/06/14 15:03


96 PARTE I Introduo ao Microsoft Visual C# e ao Microsoft Visual Studio 2013

Curto-circuito
Os operadores && e || exibem um recurso chamado curto-circuito. s vezes, no ne-
cessrio avaliar os dois operandos ao determinar o resultado de uma expresso lgica
condicional. Por exemplo, se o operando esquerdo do operador && for avaliado como
false, ento o resultado da expresso inteira deve ser false, independentemente do
valor do operando direito. De maneira semelhante, se o valor do operando esquerdo
do operador || for avaliado como true, o resultado da expresso inteira dever ser true,
independentemente do valor do operando direito. Nesses casos, os operadores && e
|| pulam a avaliao do operando direito. Eis alguns exemplos:
(percent >= 0) && (percent <= 100)

Nessa expresso, se o valor de percent for menor que 0, a expresso booleana


do lado esquerdo de && ser avaliada como false. Esse valor significa que o resultado
de toda a expresso deve ser false, e a expresso booleana direita do operador &&
no avaliada.
(percent < 0) || (percent > 100)

Nessa expresso, se o valor de percent for menor que 0, a expresso booleana no


lado esquerdo de || ser avaliada como true. Esse valor significa que o resultado da expres-
so inteira deve ser true e a expresso booleana direita do operador || no avaliada.
Se projetar cuidadosamente as expresses que usam os operadores lgicos
condicionais, voc poder aumentar o desempenho do seu cdigo evitando traba-
lho desnecessrio. Coloque expresses booleanas simples que possam ser avaliadas
facilmente no lado esquerdo de um operador lgico condicional e as expresses mais
complexas no lado direito. Em muitos casos, voc perceber que o programa no pre-
cisar avaliar as expresses mais complexas.

Um resumo da precedncia e da associatividade


dos operadores
A tabela a seguir resume a precedncia e a associatividade de todos os operadores so-
bre os quais voc aprendeu at aqui. Os operadores da mesma categoria tm a mesma
precedncia. Os operadores nas primeiras categorias da tabela tm precedncia sobre
os operadores nas ltimas categorias.

Categoria Operadores Descrio Associatividade


Primrios () Anula a precedncia Esquerda
++ Prefixo de incremento
-- Prefixo de decremento
Unrios ! NOT lgico Esquerda
+ Retorna o valor do operando inalterado
- Retorna o valor do operando negado
++ Sufixo de incremento
-- Sufixo de decremento
Multiplicativos * Multiplicao Esquerda
/ Diviso
% Resto da diviso

_Livro_Sharp_Visual.indb 96 30/06/14 15:03


CAPTULO 4 Instrues de deciso 97

Categoria Operadores Descrio Associatividade


Aditivos + Adio Esquerda
- Subtrao
Relacionais < Menor que Esquerda
<= Menor ou igual a
> Maior que
>= Maior ou igual a
Igualdade == Igual a Esquerda
!= Diferente de
AND condicional && AND condicional Esquerda
OR condicional || OR condicional Esquerda
Atribuio = Atribui o operando da direta ao da esquerda Direita
e retorna o valor que foi atribudo

Observe que o operador && e o operador || tm precedncia diferente: &&


maior que ||.

Instrues if para tomar decises


Em um mtodo, se voc quiser escolher entre executar duas instrues diferentes com
base no resultado de uma expresso booleana, utilize uma instruo if.

Entenda a sintaxe da instruo if


A sintaxe de uma instruo if a seguinte (if e else so palavras-chave do C#):
if ( booleanExpression )
statement-1;
else
statement-2;

Se a expressoBoolena for avaliada como true, a instruo-1 ser executada; caso


contrrio, a instruo-2 ser executada. A palavra-chave else e a instruo-2 subse-
quente so opcionais. Se no houver uma clusula else e a expressoBoolena for false,
a execuo continuar com o cdigo que vem depois da instruo if. Alm disso, ob-
serve que a expresso booleana deve ser colocada entre parnteses; caso contrrio, o
cdigo no compilar.
Por exemplo, aqui est uma instruo if que incrementa uma varivel represen-
tando o ponteiro de segundos de um cronmetro. (Os minutos so ignorados por
enquanto.) Se o valor da varivel seconds for 59, ela ser redefinida para 0; caso con-
trrio, ser incrementada pelo operador ++:
int seconds;
...
if (seconds == 59)
seconds = 0;
else
seconds++;

_Livro_Sharp_Visual.indb 97 30/06/14 15:03


98 PARTE I Introduo ao Microsoft Visual C# e ao Microsoft Visual Studio 2013

Somente expresses booleanas, por favor!


A expresso em uma instruo if deve estar entre parnteses. Alm disso, ela deve
ser uma expresso booleana. Em algumas outras linguagens principalmente C
e C++ , voc pode escrever uma expresso do tipo inteiro, e o compilador dis-
cretamente converter o valor inteiro em true (no zero) ou false (0). O C# no
suporta esse tipo de comportamento, e o compilador reporta um erro se uma
expresso desse tipo for escrita.
Se voc especificar acidentalmente o operador de atribuio (=) em vez do
operador de teste de igualdade (==) em uma instruo if, o compilador C# per-
ceber seu erro e no compilar seu cdigo, como no exemplo a seguir:
int seconds;
...
if (seconds = 59) // erro de tempo de compilao
...
if (seconds == 59) // ok

As atribuies acidentais so outra fonte de erros comum em programas


C e C++, que convertem discretamente o valor atribudo (59) a uma expresso
booleana (tudo diferente de zero considerado verdadeiro), resultando na exe-
cuo do cdigo aps a instruo if todas as vezes.
Ocasionalmente, uma varivel booleana pode ser utilizada como a expres-
so para uma instruo if, embora ela ainda deva ser includa entre parnteses,
como mostrado neste exemplo:
bool inWord;
...
if (inWord == true) // ok, mas no usado comumente
...
if (inWord) // mais comum e considerado um estilo melhor

Utilize blocos para agrupar instrues


Observe que a sintaxe da instruo if mostrada anteriormente especifica uma nica
instruo depois do if (expressoBoolena) e uma nica instruo depois da palavra-
-chave else. s vezes voc vai querer executar mais de uma instruo quando uma
expresso booleana for verdadeira. Voc poderia agrupar as instrues dentro de um
novo mtodo e ento chamar o novo mtodo, mas uma soluo mais simples agru-
par as instrues dentro de um bloco. Um bloco simplesmente uma sequncia de
instrues agrupadas entre uma chave de abertura e uma de fechamento.
No exemplo a seguir, duas instrues que definem a varivel seconds como 0 e
incrementam a varivel minutes esto agrupadas em um bloco, e o bloco inteiro ser
executado se o valor de seconds for igual a 59:
int seconds = 0;
int minutes = 0;
...

_Livro_Sharp_Visual.indb 98 30/06/14 15:03


CAPTULO 4 Instrues de deciso 99

if (seconds == 59)
{
seconds = 0;
minutes++;
}
else
{
seconds++;
}

Importante Se as chaves forem omitidas, o compilador do C# associar ape-


nas a primeira instruo (seconds = 0;) instruo if. A instruo subsequente
(minutes++;) no ser reconhecida pelo compilador como parte da instruo if
quando o programa for compilado. Alm disso, quando o compilador alcanar
a palavra-chave else, ele no a associar instruo if anterior; em vez disso,
informar um erro de sintaxe. Portanto, uma boa prtica sempre definir as ins-
trues de cada desvio de uma instruo if dentro de um bloco, mesmo que o
bloco consista em apenas uma instruo. Isso pode evitar sofrimento posterior-
mente, caso voc queira adicionar mais cdigo.

Um bloco tambm inicia um novo escopo. As variveis podem ser definidas den-
tro de um bloco, mas elas desaparecero no final do bloco. O fragmento de cdigo a
seguir ilustra esse ponto:
if (...)
{
int myVar = 0;
// myVar pode ser usada aqui
...
} // myVar desaparece aqui
else
{
// myVar no pode ser usada aqui
...
}
// myVar no pode ser usada aqui

Instrues if em cascata
Voc pode aninhar instrues if dentro de outras instrues if. Assim, pode encadear
uma sequncia de expresses booleanas, que so testadas uma aps a outra at que
uma delas seja avaliada como true. No exemplo a seguir, se o valor de day for 0, o pri-
meiro teste ser avaliado como true e dayName receber a string Sunday. Se o valor
de day no for 0, o primeiro teste falhar e o controle passar para a clusula else, que
executa a segunda instruo if e compara o valor de day com 1. A segunda instruo if
executada somente se o primeiro teste for false. Da mesma forma, a terceira instru-
o if s ser executada se o primeiro e o segundo testes forem false.
if (day == 0)
{
dayName = "Sunday";

_Livro_Sharp_Visual.indb 99 30/06/14 15:03


100 PARTE I Introduo ao Microsoft Visual C# e ao Microsoft Visual Studio 2013

}
else if (day == 1)
{
dayName = "Monday";
}
else if (day == 2)
{
dayName = "Tuesday";
}
else if (day == 3)
{
dayName = "Wednesday";
}
else if (day == 4)
{
dayName = "Thursday";
}
else if (day == 5)
{
dayName = "Friday";
}
else if (day == 6)
{
dayName = "Saturday";
}
else
{
dayName = "unknown";
}

No exerccio a seguir, voc escrever um mtodo que utiliza uma instruo if em


cascata para comparar duas datas.

Escreva instrues if
1. Inicialize o Microsoft Visual Studio 2013 se ele ainda no estiver em execuo.
2. Abra o projeto Selection, localizado na pasta \Microsoft Press\Visual CSharp Step
By Step\Chapter 4\Windows X\Selection na sua pasta Documentos.
3. No menu Debug, clique em Start Debugging.
O Visual Studio 2013 compila e executa o aplicativo. O formulrio exibe dois
controles DatePicker, chamados firstDate e secondDate. Se estiver usando o Win-
dows 8.1, os dois controles exibiro a data atual.
4. Se estiver usando Windows 7 ou Windows 8, clique no cone de calendrio do
primeiro controle DatePicker e, ento, clique na data atual. Repita essa operao
para o segundo controle DatePicker.
5. Clique em Compare.

_Livro_Sharp_Visual.indb 100 30/06/14 15:03


CAPTULO 4 Instrues de deciso 101

O texto a seguir exibido na caixa de texto na metade inferior da janela:


firstDate == secondDate : False
firstDate != secondDate : True
firstDate < secondDate : False
firstDate <= secondDate : False
firstDate > secondDate : True
firstDate >= secondDate : True

A expresso booleana firstDate == secondDate deve ser true porque tanto first
quanto second esto configurados com a data atual. De fato, somente o ope-
rador menor que e o operador maior ou igual a parecem funcionar cor-
retamente. As imagens a seguir mostram as verses para Windows 8.1 e para
Windows 7 do aplicativo em execuo.

_Livro_Sharp_Visual.indb 101 30/06/14 15:03


102 PARTE I Introduo ao Microsoft Visual C# e ao Microsoft Visual Studio 2013

6. Retorne ao Visual Studio 2013. No menu Debug, clique em Stop Debugging (ou
simplesmente feche o aplicativo, se estiver usando o Windows 7 ou o Windows
8).
7. Exiba o cdigo de MainWindow.xaml.cs na janela Code and Text Editor.
8. Localize o mtodo compareClick, que deve ser parecido com este:
private void compareClick(object sender, RoutedEventArgs e)
{
int diff = dateCompare(first, second);
info.Text = "";
show("firstDate == secondDate", diff == 0);
show("firstDate != secondDate", diff != 0);
show("firstDate < secondDate", diff < 0);
show("firstDate <= secondDate", diff <= 0);
show("firstDate > secondDate", diff > 0);
show("firstDate >= secondDate", diff >= 0);
}

Esse mtodo executado sempre que o usurio clica no boto Compare do for-
mulrio. As variveis first e second contm valores DateTime; elas so preenchi-
das com as datas exibidas nos controles firstDate e secondDate do formulrio em
outro lugar no aplicativo. DateTime apenas mais um tipo de dado, como int
ou float, exceto pelo fato de que contm subelementos com os quais possvel
acessar as partes individuais de uma data, como ano, ms ou dia.
O mtodo compareClick passa os dois valores DateTime para o mtodo date-
Compare. O objetivo desse mtodo comparar datas e retornar o valor int 0
se elas forem iguais, -1 se a primeira data for menor do que a segunda e +1 se
a primeira for maior do que a segunda. Uma data considerada maior do que
outra se vem depois dela cronologicamente. Examinaremos o mtodo dateCom-
pare no prximo passo.
O mtodo show exibe os resultados da comparao no controle caixa de texto
info na metade inferior do formulrio.
9. Localize o mtodo dateCompare, que deve ser parecido com este:

_Livro_Sharp_Visual.indb 102 30/06/14 15:03


CAPTULO 4 Instrues de deciso 103

private int dateCompare(DateTime leftHandSide, DateTime rightHandSide)


{
// TO DO
return 42;
}

Atualmente, esse mtodo retorna o mesmo valor sempre que chamado em


vez de 0, -1 ou +1 , independentemente dos valores de seus parmetros. Isso
explica por que o aplicativo no funciona conforme o esperado. Voc precisa
implementar a lgica nesse mtodo para comparar duas datas de modo correto.
10. Remova o comentrio // TO DO e a instruo return do mtodo dateCompare.
11. Adicione as seguintes instrues mostradas em negrito ao corpo do mtodo
dateCompare:
private int dateCompare(DateTime leftHandSide, DateTime rightHandSide)
{
int result;

if (leftHandSide.Year < rightHandSide.Year)


{
result = -1;
}
else if (leftHandSide.Year > rightHandSide.Year)
{
result = 1;
}
}

Se a expresso leftHandSide.Year < rightHandSide.Year for true, a data em left-


HandSide deve ser anterior data em rightHandSide; portanto, o programa con-
figura a varivel result como -1. Caso contrrio, se a expresso leftHandSide.Year
> rightHandSide.Year for true, a data em leftHandSide deve ser posterior data
em rightHandSide; portanto, o programa configura a varivel result como 1.
Se a expresso leftHandSide.Year < rightHandSide.Year for false e a expresso
leftHandSide.Year > rightHandSide.Year tambm for false, a propriedade Year das
duas datas deve ser a mesma; portanto, o programa precisa comparar os meses
em cada data.
12. Adicione as instrues a seguir mostradas em negrito ao corpo do mtodo date-
Compare, depois do cdigo que voc inseriu no passo anterior:
private int dateCompare(DateTime leftHandSide, DateTime rightHandSide)
{
...
else if (leftHandSide.Month < rightHandSide.Month)
{
result = -1;
}
else if (leftHandSide.Month > rightHandSide.Month)
{
result = 1;
}
}

_Livro_Sharp_Visual.indb 103 30/06/14 15:03


104 PARTE I Introduo ao Microsoft Visual C# e ao Microsoft Visual Studio 2013

Essas instrues seguem uma lgica para comparar meses, semelhante quela
utilizada para comparar anos no passo anterior.
Se a expresso leftHandSide.Month < rightHandSide.Month for false e a expres-
so leftHandSide.Month > rightHandSide.Month tambm for false, a propriedade
Month das duas datas deve ser a mesma, assim o programa acaba precisando
comparar o dia em cada data.
13. Adicione as seguintes instrues ao corpo do mtodo dateCompare, depois do
cdigo que voc inseriu nos dois passos anteriores:
private int dateCompare(DateTime leftHandSide, DateTime rightHandSide)
{
...
else if (leftHandSide.Day < rightHandSide.Day)
{
result = -1;
}
else if (leftHandSide.Day > rightHandSide.Day)
{
result = 1;
}
else
{
result = 0;
}

return result;
}

Voc j deve reconhecer o padro nessa lgica.


Se leftHandSide.Day < rightHandSide.Day e leftHandSide.Day > rightHandSide.
Day forem false, o valor nas propriedades Day nas duas variveis deve ser o mes-
mo. Os valores Month e os valores Year tambm devem ser idnticos para que a
lgica do programa chegue at esse ponto; portanto, as duas datas devem ser
iguais, e o programa configura o valor de result como 0.
A ltima instruo retorna o valor armazenado na varivel result.
14. No menu Debug, clique em Start Debugging.
O aplicativo recompilado e reiniciado. Se estiver usando Windows 7 ou Win-
dows 8, configure os dois controles DatePicker com a data atual.
15. Clique em Compare.
O texto a seguir exibido na caixa de texto:
firstDate == secondDate : True
firstDate != secondDate : False
firstDate < secondDate: False
firstDate <= secondDate: True
firstDate > secondDate: False
firstDate >= secondDate: True

_Livro_Sharp_Visual.indb 104 30/06/14 15:03


CAPTULO 4 Instrues de deciso 105

Esses so os resultados corretos para datas idnticas.


16. Se estiver usando Windows 7 ou Windows 8, selecione um ms posterior para o
controle DatePicker secondDate. Se estiver usando o Windows 8.1, use as setas
suspensas para selecionar uma data posterior.
17. Clique em Compare.
O texto a seguir exibido na caixa de texto:
firstDate == secondDate: False
firstDate != secondDate: True
firstDate < secondDate: True
firstDate <= secondDate: True
firstDate > secondDate: False
firstDate >= secondDate: False

Mais uma vez, esses so os resultados corretos quando a primeira data anterior
segunda data.
18. Teste algumas outras datas e verifique se os resultados so os esperados. Volte
ao Visual Studio 2013 e interrompa a depurao (ou feche o aplicativo, se estiver
usando o Windows 7 ou o Windows 8) quando tiver terminado.

Comparao de datas em aplicativos do mundo real


Agora que vimos como utilizar uma srie um tanto longa e complicada de instru-
es if e else, devo mencionar que essa no a tcnica que voc empregaria para
comparar datas em um aplicativo real. Se voc examinar o mtodo dateCompare
do exerccio anterior, ver que os dois parmetros, leftHandSide e rightHandSide,
so valores DateTime. A lgica escrita s compara a parte da data desses parme-
tros, mas eles tambm contm um elemento hora que no foi considerado (nem
exibido). Para que dois valores DateTime sejam considerados iguais, eles no ape-
nas devem ter a mesma data, mas tambm a mesma hora. Comparar datas e horas
uma operao to comum que o tipo DateTime tem um mtodo interno, chama-
do CompareTo, para fazer justamente isso: ele recebe dois argumentos DateTime
e os compara, retornando um valor que indica se o primeiro argumento menor
que o segundo, caso em que o resultado ser negativo; se o primeiro argumento
maior que o segundo, caso em que o resultado ser positivo; ou se os dois argu-
mentos representam a mesma data e hora, caso em que o resultado ser 0.

Instrues switch
Algumas vezes, ao se escrever uma instruo if em cascata, cada uma das instrues if
parecem iguais, porque todas avaliam uma expresso idntica. A nica diferena que
cada if compara o resultado da expresso com um valor diferente. Por exemplo, consi-
dere o seguinte bloco de cdigo que utiliza uma instruo if para examinar o valor na
varivel day e calcular qual o dia da semana:
if (day == 0)
{
dayName = "Sunday";

_Livro_Sharp_Visual.indb 105 30/06/14 15:03


106 PARTE I Introduo ao Microsoft Visual C# e ao Microsoft Visual Studio 2013

}
else if (day == 1)
{
dayName = "Monday";
}
else if (day == 2)
{
dayName = "Tuesday";
}
else if (day == 3)
{
...
}
else
{
dayName = "Unknown";
}

Nessas situaes, normalmente possvel reescrever a instruo if em cascata


como uma instruo switch, para tornar o programa mais eficiente e legvel.

Entenda a sintaxe da instruo switch


A sintaxe de uma instruo switch a seguinte (switch, case e default so palavras-
-chave):
switch ( expressoDeControle )
{
case expressoConstante :
instrues
break;
case expressoConstante :
instrues
break;
...
default :
instrues
break;
}

A expressoDeControle, que deve ser colocada entre parnteses, avaliada uma


vez. O controle passa ento para o bloco de cdigo identificado pela expressoCons-
tante, cujo valor igual ao resultado da expressoDeControle. (O identificador da ex-
pressoConstante tambm chamado de rtulo case.) A execuo prossegue at a
instruo break e, ento, a instruo switch termina e o programa continua na primeira
instruo depois da chave de fechamento da instruo switch. Se nenhum dos valores
da expressoConstante for igual ao valor da expressoDeControle, as instrues abaixo
do rtulo default opcional sero executadas.

_Livro_Sharp_Visual.indb 106 30/06/14 15:03


CAPTULO 4 Instrues de deciso 107

Nota Cada valor da expressoConstante deve ser nico; assim, a expressoDe-


Controle s corresponder a um deles. Se o valor da expressoDeControle no
corresponder a nenhum valor da expressoConstante e no houver um rtulo
default, a execuo do programa continuar na primeira instruo aps a chave
de fechamento da instruo switch.

Portanto, voc pode reescrever a instruo if em cascata anterior como a instru-


o switch a seguir:
switch (day)
{
case 0 :
dayName = "Sunday";
break;
case 1 :
dayName = "Monday";
break;
case 2 :
dayName = "Tuesday";
break;
...
default :
dayName = "Unknown";
break;
}

Siga as regras da instruo switch


A instruo switch muito til, mas, infelizmente, nem sempre voc poder utiliz-la
como deseja. Todas as instrues switch que voc escrever devem obedecer s seguin-
tes regras:
j A instruo switch s pode ser utilizada em certos tipos de dados, como int, char
ou string. Com qualquer outro tipo (incluindo float e double), voc deve utilizar
uma instruo if.
j Os rtulos case devem ser expresses constantes, como 42, se o tipo de dado
da instruo switch for int, 4, se for char ou 42, se for string. Se for necessrio
calcular valores dos rtulos case em tempo de execuo, utilize uma instruo if.
j Os rtulos case devem ser expresses nicas. Ou seja, dois rtulos case no po-
dem ter o mesmo valor.
j Voc pode especificar que deseja executar as mesmas instrues para mais de
um valor fornecendo uma lista de rtulos de caso sem nenhuma instruo no
meio, caso em que o cdigo do rtulo final na lista executado para todas
as instrues case nessa lista. Mas se um rtulo tiver uma ou mais instrues
associadas, a execuo no poder prosseguir (fall-through) para os rtulos sub-
sequentes; nesse caso, o compilador gerar um erro. O fragmento de cdigo a
seguir ilustra esses pontos:
switch (trumps)
{
case Hearts :
case Diamonds : // Fall-through allowed - no h nenhum cdigo entre os rtulos

_Livro_Sharp_Visual.indb 107 30/06/14 15:03


108 PARTE I Introduo ao Microsoft Visual C# e ao Microsoft Visual Studio 2013

color = "Red"; // Cdigo executado para Hearts e Diamonds


break;
case Clubs :
color = "Black";
case Spades : // Erro cdigo entre rtulos
color = "Black";
break;
}

Nota A instruo break a maneira mais comum de parar um fall-through,


mas voc tambm pode usar uma instruo return para sair do mtodo que
contm a instruo switch ou uma instruo throw, para gerar uma exceo e
abortar a instruo switch. A instruo throw ser descrita no Captulo 6, Geren-
ciamento de erros e excees.

Regras de fall-through da instruo switch


Como no possvel passar acidentalmente de um rtulo case para outro se
houver algum cdigo no meio, voc pode reorganizar livremente as sees de
uma instruo switch sem afetar o significado (incluindo o rtulo default que, por
conveno, em geral mas no obrigatoriamente posicionado como o ltimo
rtulo).
Os programadores de C e C++ devem notar que a instruo break obri-
gatria para cada case em uma instruo switch (mesmo o case padro). H uma
razo para isso: em programas C ou C++, comum a instruo break ser esqueci-
da, permitindo que a execuo prossiga (faa fall-through) para o prximo rtulo,
originando erros difceis de descobrir.
Se voc quiser, pode simular o fall-through do C/C++ no C#, usando a ins-
truo goto para ir para a instruo case seguinte ou para o rtulo default. Mas, em
geral, o uso de goto no recomendvel, e este livro no demonstra como faz-lo.

No prximo exerccio, voc completar um programa que l os caracteres de


uma string e mapeia cada caractere para sua representao XML. Por exemplo, o ca-
ractere de sinal de menor, <, tem um significado especial em XML (ele utilizado para
formar elementos). Se houver dados que contenham esse caractere, eles devero ser
convertidos na entidade de texto &lt; para que um processador de XML saiba que so
dados e no parte de uma instruo XML. Regras semelhantes se aplicam ao sinal de
maior (>) e aos caracteres e comercial (&), aspa nica () e aspa dupla (). Voc escre-
ver uma instruo switch que testa o valor do caractere e captura os caracteres XML
especiais como rtulos case.

Escreva instrues switch


1. Inicie o Visual Studio 2013, se ele ainda no estiver em execuo.
2. Abra o projeto SwitchStatement, localizado na pasta \Microsoft Press\Visual
CSharp Step By Step\Chapter 4\Windows X\SwitchStatement na sua pasta
Documentos.

_Livro_Sharp_Visual.indb 108 30/06/14 15:03


CAPTULO 4 Instrues de deciso 109

3. No menu Debug, clique em Start Debugging.


O Visual Studio 2013 compila e executa o aplicativo. O aplicativo exibe um for-
mulrio contendo duas caixas de texto separadas por um boto Copy.
4. Digite o seguinte texto de exemplo na caixa de texto superior.
inRange = (lo < = number) && (hi > = number);
5. Clique em Copy.
A instruo copiada ipsis litteris para a caixa de texto inferior e no ocorre
qualquer traduo dos caracteres <, & ou >, como se v na captura de tela a
seguir, que mostra a verso para Windows 8.1 do aplicativo.

6. Retorne ao Visual Studio 2013 e interrompa a depurao.


7. Exiba o cdigo de MainWindow.xaml.cs na janela Code and Text Editor e localize
o mtodo copyOne.
O mtodo copyOne copia o caractere especificado como o parmetro de entra-
da no final do texto exibido na caixa de texto inferior. No momento, copyOne
contm uma instruo switch com uma nica ao default. Nos prximos passos,
voc modificar essa instruo switch para converter os caracteres que so sig-
nificativos em XML para seu mapeamento XML. Por exemplo, o caractere < ser
convertido na string &lt;.

_Livro_Sharp_Visual.indb 109 30/06/14 15:03


110 PARTE I Introduo ao Microsoft Visual C# e ao Microsoft Visual Studio 2013

8. Adicione as instrues mostradas em negrito a seguir instruo switch, depois


da chave de abertura da instruo e imediatamente antes do rtulo default:
switch (current)
{
case '<' :
target.Text += "&lt;";
break;
default:
target.Text += current;
break;
}

Se o caractere que est sendo copiado for um sinal de menor (<), o cdigo an-
terior acrescentar em seu lugar a string &lt; ao texto que est sendo gerado.
9. Adicione as seguintes instrues instruo switch, depois da instruo break
que voc recm adicionou e acima do rtulo default:
case '>' :
target.Text += "&gt;";
break;
case '&' :
target.Text += "&amp;";
break;
case '\"' :
target.Text += "&#34;";
break;
case '\'' :
target.Text += "&#39;";
break;

Nota A aspa nica () e a aspa dupla () tm um significado especial em C#


elas so utilizadas para delimitar constantes de caracteres e de string. A barra in-
vertida (\) no final dos dois rtulos case um caractere de escape que faz o com-
pilador C# tratar esses caracteres como literais, em vez de como delimitadores.

10. No menu Debug, clique em Start Debugging.


11. Digite o texto a seguir na caixa de texto superior.
inRange = (lo < = number) && (hi > = number);

_Livro_Sharp_Visual.indb 110 30/06/14 15:03


CAPTULO 4 Instrues de deciso 111

12. Clique em Copy.


A instruo copiada na caixa de texto inferior. Desta vez, cada caractere sub-
mete-se ao mapeamento XML implementado na instruo switch. A caixa de
texto de destino exibe o seguinte texto:
inRange = (lo &lt;= number) &amp;&amp; (hi &gt;= number);
13. Teste outras strings e verifique se todos os caracteres especiais (<, >, &, e ) so
tratados corretamente.
14. Volte ao Visual Studio e interrompa a depurao (ou simplesmente feche o apli-
cativo, se estiver usando o Windows 7 ou o Windows 8).

Resumo
Neste captulo, voc conheceu as expresses e variveis booleanas. Aprendeu a usar
expresses booleanas com instrues if e switch para tomar decises em seus progra-
mas e combinou expresses booleanas por meio de operadores booleanos.
j Se quiser continuar no prximo captulo, mantenha o Visual Studio 2013 exe-
cutando e v para o Captulo 5, Atribuio composta e instrues de iterao.
j Se quiser encerrar o Visual Studio 2013 agora, no menu File, clique em Exit. Se vir
uma caixa de dilogo Save, clique em Yes e salve o projeto.

Referncia rpida

Para Faa isto Exemplo


Determinar se dois valores so Utilize o operador == ou o answer == 42
equivalentes operador !=.
Comparar o valor de duas expresses Utilize o operador <, <=, > age >= 21
ou >=.
Declarar uma varivel booleana Utilize a palavra-chave bool bool inRange;
como o tipo da varivel.
Criar uma expresso booleana que seja Utilize o operador &&. inRange = (lo <= number)
verdadeira somente se duas condies && (number <= hi);
forem ambas verdadeiras
Criar uma expresso booleana que seja Utilize o operador ||. outOfRange = (number < lo)
verdadeira se uma de duas condies for || (hi < number);
verdadeira
Executar uma instruo se uma condio Utilize uma instruo if. if (inRange)
for verdadeira process();

_Livro_Sharp_Visual.indb 111 30/06/14 15:03


112 PARTE I Introduo ao Microsoft Visual C# e ao Microsoft Visual Studio 2013

Para Faa isto Exemplo


Executar mais de uma instruo se uma Utilize uma instruo if e um if (seconds == 59)
condio for verdadeira bloco. {
seconds = 0;
minutes++;
}

Associar diferentes instrues a Utilize uma instruo switch. switch (current)


diferentes valores de uma expresso de {
controle case 0:
...
break;

case 1:
...
break;
default :
...
break;
}

_Livro_Sharp_Visual.indb 112 30/06/14 15:03


CAPTULO 5

Atribuio composta e
instrues de iterao
Neste captulo, voc vai aprender a:
j Atualizar o valor de uma varivel utilizando os operadores de atribuio com-
posta.
j Escrever instrues de iterao (ou repetio) while, for e do.
j Inspecionar uma instruo do passo a passo e ver como os valores de variveis
mudam.
O Captulo 4, Instrues de deciso, mostrou como utilizar as construes if e switch
a fim de executar instrues seletivamente. Este captulo vai mostrar como usar vrias
instrues de iterao (loop) com a finalidade de executar uma ou mais instrues
repetidamente.
Ao escrever as instrues de iterao, em geral, preciso controlar o nmero de
iteraes que sero executadas. Isso feito utilizando-se uma varivel que atualiza seu
valor a cada iterao feita e que para o processo quando a varivel atinge um valor
especfico. Para auxiliar na simplificao desse processo, voc aprender sobre opera-
dores de atribuio especiais que precisam ser usados para a atualizao do valor de
uma varivel nessas circunstncias.

Operadores de atribuio composta


Voc j sabe como usar os operadores matemticos para criar novos valores. Por
exemplo, a instruo a seguir utiliza o operador (+) para exibir no console um valor
que 42 unidades maior que a varivel answer.
Console.WriteLine(answer + 42);

Voc tambm aprendeu como usar as instrues de atribuio para alterar o va-
lor de uma varivel. A instruo a seguir usa o operador de atribuio (=) para alterar
o valor da varivel answer para 42:
answer = 42;

_Livro_Sharp_Visual.indb 113 30/06/14 15:04


114 PARTE I Introduo ao Microsoft Visual C# e ao Microsoft Visual Studio 2013

Se voc quiser somar 42 ao valor de uma varivel, pode combinar o operador


de atribuio com o operador de adio. Por exemplo, a instruo a seguir adiciona
42 varivel answer. Depois da execuo dessa instruo, o valor de answer ser 42
unidades maior que o valor anterior:
answer = answer + 42;

Embora essa instruo funcione, voc provavelmente nunca ver um progra-


mador experiente escrever um cdigo assim. Adicionar um valor a uma varivel to
comum que o C# oferece um modo de executar essa tarefa de maneira mais rpida,
utilizando o operador +=. Para adicionar 42 a answer, escreva esta instruo:
answer += 42;

Utilize essa notao para combinar qualquer operador aritmtico com o ope-
rador de atribuio, como mostra a tabela a seguir. Esses operadores so conhecidos
como operadores de atribuio composta.

No escreva isto Escreva isto


varivel = varivel * nmero; varivel *= nmero;

varivel = varivel / nmero; varivel /= nmero;

varivel = varivel % nmero; varivel %= nmero;

varivel = varivel + nmero; varivel += nmero;

varivel = varivel - nmero; varivel -= nmero;

Dica Os operadores de atribuio composta compartilham a mesma prece-


dncia e associatividade direita dos operadores de atribuio simples corres-
pondentes.

O operador += tambm funciona em strings; ele anexa uma string ao final de


outra. Por exemplo, o cdigo a seguir exibe Hello John no console:
string name = "John";
string greeting = "Hello ";
greeting += name;
Console.WriteLine(greeting);

Voc no pode utilizar outro operador de atribuio composta em strings.

Dica Utilize os operadores de incremento (++) e decremento (--) em vez de


um operador de atribuio composta ao incrementar ou decrementar uma va-
rivel por 1. Por exemplo, substitua
count += 1;

por:
count++;

_Livro_Sharp_Visual.indb 114 30/06/14 15:04


CAPTULO 5 Atribuio composta e instrues de iterao 115

Escreva instrues while


Voc utiliza uma instruo while para executar uma instruo repetidamente enquan-
to alguma condio se mantiver verdadeira. A sintaxe de uma instruo while esta:
while ( booleanExpression )
statement

A expresso booleana (que deve ser colocada entre parnteses) avaliada e,


se for verdadeira, a instruo executada e a expresso booleana ento avaliada
novamente. Se a expresso se mantiver verdadeira, a instruo ser repetida e ento a
expresso booleana ser avaliada ainda mais uma vez. Esse processo continua at que
a expresso booleana seja avaliada como falsa; nesse ponto a instruo while termina.
A execuo continua ento com a primeira instruo depois da instruo while. Uma
instruo while compartilha as seguintes semelhanas sintticas com uma instruo if
(na verdade, a sintaxe idntica, s muda a palavra-chave):
j A expresso deve ser uma expresso booleana.
j A expresso booleana deve ser escrita entre parnteses.
j Se a expresso booleana for avaliada como falsa na primeira avaliao, a instru-
o no ser executada.
j Se quiser executar duas ou mais instrues sob o controle de uma instruo whi-
le, voc deve utilizar chaves para agrupar essas instrues em um bloco.
Observe uma instruo while que escreve os valores de 0 a 9 no console. Note
que, assim que a varivel i atinge o valor 10, a instruo while termina e o cdigo pre-
sente no bloco de instrues no executado:
int i = 0;
while (i < 10)
{
Console.WriteLine(i);
i++;
}

Todas as instrues while devem terminar em algum ponto. Um erro comum de


iniciantes esquecerem de incluir uma instruo para fazer a expresso booleana ser,
por fim, avaliada como falsa e terminar o loop, o que resulta em um programa que
executado de modo contnuo. No exemplo, a instruo i++; desempenha esse papel.

_Livro_Sharp_Visual.indb 115 30/06/14 15:04


116 PARTE I Introduo ao Microsoft Visual C# e ao Microsoft Visual Studio 2013

Nota A varivel i no loop while controla o nmero de iteraes que ele exe-
cuta. Essa expresso comum e a varivel que executa essa funo , s vezes,
chamada de varivel sentinela. Tambm possvel criar loops aninhados (um
loop dentro de outro) e, nesses casos, comum estender esse padro de nome-
ao para usar as letras j, k e at l como nomes das variveis sentinelas utilizadas
para controlar as iteraes nesses loops.
Dica Como nas instrues if, recomenda-se sempre utilizar um bloco com uma
instruo while, mesmo que o bloco contenha apenas uma instruo. Assim, se
depois voc decidir adicionar mais instrues ao corpo da construo while, ser
claro que deve adicion-las no bloco. Se voc no fizer isso, somente a primeira
instruo imediatamente aps a expresso booleana na construo while ser
executada como parte do loop, resultando em erros difceis de encontrar, como
este:
int i = 0;
while (i < 10)
Console.WriteLine(i);
i++;

Esse cdigo itera indefinidamente, exibindo um nmero infinito de zeros, pois


somente a instruo Console.WriteLine e no a instruo i++; executada
como parte da construo while.

No exerccio a seguir, voc escrever um loop while para iterar pelo contedo de
um arquivo de texto, uma linha de cada vez, e escrever cada linha em uma caixa de
texto de um formulrio.

Escreva uma instruo while


1. Utilizando o Microsoft Visual Studio 2013, abra o projeto WhileStatement, loca-
lizado na pasta \Microsoft Press\Visual CSharp Step by Step\Chapter 5\Windows
X\WhileStatement na sua pasta Documentos.
2. No menu Debug, clique em Start Debugging.
O Visual Studio 2013 compila e executa o aplicativo. O aplicativo um visua-
lizador simples de arquivo de texto que voc pode utilizar para selecionar um
arquivo de texto e exibir o contedo.
3. Clique em Open File.
Se estiver usando o Windows 8.1, o selecionador de arquivos Open aparecer e
exibir os arquivos da pasta Documentos, como se v na imagem a seguir (a lista
de arquivos e pastas pode ser diferente em seu computador).

_Livro_Sharp_Visual.indb 116 30/06/14 15:04


CAPTULO 5 Atribuio composta e instrues de iterao 117

Se estiver usando o Windows 7, ser exibida a caixa de dilogo Open, como esta:

No importa o sistema operacional que esteja utilizado, com esse recurso pos-
svel ir at uma pasta e selecionar um arquivo para exibir.

_Livro_Sharp_Visual.indb 117 30/06/14 15:04


118 PARTE I Introduo ao Microsoft Visual C# e ao Microsoft Visual Studio 2013

4. Abra a pasta \Microsoft Press\Visual CSharp Step By Step\Chapter 5\Windows X\


WhileStatement\ WhileStatement na sua pasta Documentos.
5. Selecione o arquivo MainWindow.xaml.cs e clique em Open.
O nome do arquivo, MainWindow.xaml.cs, aparece na caixa de texto da parte
superior do formulrio, mas o contedo do arquivo no aparece na caixa de
texto grande. Isso ocorre porque voc ainda no implementou o cdigo que l e
exibe o contedo do arquivo. Voc adicionar essa funcionalidade nos prximos
passos.
6. Volte ao Visual Studio 2013 e interrompa a depurao (ou feche o aplicativo, se
estiver usando o Windows 7 ou o Windows 8).
7. Exiba o cdigo do arquivo MainWindow.xaml.cs na janela Code and Text Editor
e localize o mtodo openFileClick.
Esse mtodo chamado quando o usurio clica no boto Open para selecionar
um arquivo na caixa de dilogo Open. A maneira como esse mtodo imple-
mentado diferente nas diversas verses do aplicativo. Neste ponto, no ne-
cessrio entender os detalhes exatos do funcionamento desse mtodo basta
aceitar o fato de que ele solicita um arquivo para o usurio (com uma janela
FileOpenPicker ou OpenFileDialog) e abre o arquivo selecionado para leitura. (Na
verso para Windows 7, esse mtodo simplesmente exibe a janela OpenFileDia-
log e, quando o usurio seleciona um arquivo, o mtodo openFileDialogFileOk
executado; portanto, esse mtodo que realmente abre o arquivo para leitura.)
Mas as duas ltimas instrues no mtodo openFileClick (Windows 8.1) ou open-
FileDialogFileOk (Windows 7) so importantes. Na verso para Windows 8.1, o
cdigo como este:
TextReader reader = new StreamReader(inputStream.AsStreamForRead());
displayData(reader);

A primeira instruo declara uma varivel TextReader chamada reader. TextRea-


der uma classe disponibilizada pelo Microsoft .NET Framework que pode ser
utilizada para ler fluxos de caracteres a partir de fontes como arquivos. Ela est
localizada no namespace System.IO. Essa instruo torna os dados do arquivo
especificado pelo usurio no FileOpenPicker, disponveis para o objeto TextRe-
ader, o qual pode ento ser utilizado para ler os dados do arquivo. A ltima
instruo chama um mtodo denominado displayData, passando reader como
parmetro para esse mtodo. O mtodo displayData l os dados utilizando o
objeto reader e os exibe na tela (ou far isso, quando voc tiver escrito o cdigo
necessrio).
Na verso para Windows 7 do cdigo, as instrues correspondentes so como
segue:
TextReader reader = src.OpenText();
displayData(reader);

A varivel src um objeto FileInfo preenchido com informaes sobre o arquivo


selecionado pelo usurio com a janela OpenFileDialog. FileInfo outra classe
encontrada no .NET Framework e fornece o mtodo OpenText para abrir um
arquivo para leitura. A primeira instruo abre o arquivo selecionado pelo usu-
rio para que a varivel reader possa recuperar o contedo desse arquivo. Como

_Livro_Sharp_Visual.indb 118 30/06/14 15:04


CAPTULO 5 Atribuio composta e instrues de iterao 119

na verso para Windows 8.1 do cdigo, a segunda instruo chama o mtodo


displayData, passando reader como parmetro.
8. Examine o mtodo displayData. Ele se parece com este nas duas verses:
private void displayData(TextReader reader)
{
// TODO: adicionar o loop while aqui

Pode-se ver que, fora o comentrio, esse mtodo est atualmente vazio. a que
voc precisa adicionar o cdigo para buscar e exibir os dados.
9. Substitua o comentrio // TODO: adicionar um loop while aqui pela seguinte
instruo:
source.Text = "";

A varivel source refere-se caixa de texto grande no formulrio. A configurao


de sua propriedade Text como uma string vazia () limpa todo o texto que
exibido atualmente nessa caixa de texto.
10. Adicione a seguinte instruo depois da linha anterior que voc adicionou ao
mtodo displayData;
string line = reader.ReadLine();

Essa instruo declara uma varivel string chamada line e chama o mtodo re-
ader.ReadLine para ler a primeira linha do arquivo nessa varivel. Esse mtodo
retorna a prxima linha de texto do arquivo ou um valor especial chamado null,
quando no h mais linhas para ler.
11. Adicione as seguintes instrues ao mtodo displayData, depois do cdigo que
voc acabou de inserir:
while (line != null)
{
source.Text += line + '\n';
line = reader.ReadLine();
}

Esse um loop while que itera pelo arquivo uma linha por vez at que no haja
linha alguma disponvel.
A expresso booleana no incio do loop while examina o valor da varivel line. Se
no for null, o corpo do loop exibir a linha de texto anexando-a propriedade
Text da caixa de texto source, junto com um caractere de nova linha (\n o m-
todo ReadLine do objeto TextReader exclui os caracteres de nova linha medida
que l cada linha, portanto, o cdigo precisa adicion-lo novamente). O loop
while l ento a prxima linha de texto antes de realizar a prxima iterao. O
loop while termina quando no h mais texto para ler no arquivo, e o mtodo
ReadLine retorna um valor null.

_Livro_Sharp_Visual.indb 119 30/06/14 15:04


120 PARTE I Introduo ao Microsoft Visual C# e ao Microsoft Visual Studio 2013

12. Se estiver usando o Windows 8.1, digite a seguinte instruo depois da chave de
fechamento no fim do loop while:
reader.Dispose();

Se estiver usando o Windows 7 ou o Windows 8, digite a seguinte instruo:


reader.Close();

Essas instrues liberam os recursos associados ao arquivo e o fecham. Essa


uma boa prtica, pois permite que outros aplicativos utilizem o arquivo, alm de
liberar memria e outros recursos utilizados para acessar o arquivo.
13. No menu Debug, clique em Start Debugging.
14. Quando o formulrio aparecer, clique em Open File.
15. No selecionador de arquivos Open ou na caixa de dilogo Open File, abra a
pasta \Microsoft Press\Visual CSharp Step By Step\Chapter 5\Windows X\Whi-
leStatement\WhileStatement na sua pasta Documentos, selecione o arquivo
MainWindow.xaml.cs e clique em Open.

Nota No tente abrir um arquivo que no contenha texto. Se voc tentar abrir
um programa executvel ou um arquivo grfico, por exemplo, o aplicativo sim-
plesmente exibir uma representao de texto da informao binria presente
nesse arquivo. Se o arquivo for grande, poder travar o aplicativo, exigindo que
voc o termine fora.

Desta vez, o contedo do arquivo selecionado aparece na caixa de texto voc


deve reconhecer o cdigo que esteve editando. A imagem a seguir mostra a
verso para Windows 8.1 do aplicativo em execuo; a verso para Windows 7
funciona da mesma maneira:

_Livro_Sharp_Visual.indb 120 30/06/14 15:04


CAPTULO 5 Atribuio composta e instrues de iterao 121

16. Role pelo texto na caixa de texto e localize o mtodo displayData. Verifique que
esse mtodo contm o cdigo que voc acabou de adicionar.
17. Volte ao Visual Studio e interrompa a depurao (ou feche o aplicativo, se estiver
usando o Windows 7).

Escreva instrues for


No C#, a maioria das instrues while tem a seguinte estrutura geral:
inicializao
while (expresso booleana)
{
instruo
atualizao da varivel de controle
}

No C#, a instruo for fornece uma verso mais formal desse tipo de construo,
combinando a inicializao, a expresso booleana e o cdigo que atualiza a varivel
de controle. A instruo for til, pois muito mais difcil sair acidentalmente do c-
digo que inicializa ou atualiza a varivel de controle, de modo que menos provvel
que voc escreva cdigo contendo loops infinitos. Observe a sintaxe da instruo for:
for (inicializao; expresso booleana; atualizao da varivel de controle)
instruo

A instruo que forma o corpo da construo for pode ser uma nica linha de
cdigo ou um bloco de cdigo colocado entre chaves.
Voc pode reformular o loop while mostrado anteriormente, que exibe os intei-
ros de 0 a 9, como o loop for a seguir:
for (int i = 0; i < 10; i++)
{
Console.WriteLine(i);
}

A inicializao ocorre apenas uma vez, bem no incio do loop. Portanto, se a ex-
presso booleana for avaliada como true, a instruo ser executada. A atualizao da
varivel de controle ocorre e ento a expresso booleana reavaliada. Se a condio
ainda for true, a instruo executada novamente, a varivel de controle atualizada,
a expresso booleana avaliada mais uma vez e assim por diante.
Observe que a inicializao ocorre apenas uma vez e que a instruo no corpo
do loop sempre executada antes que a atualizao se realize e que a atualizao
acontece antes de a expresso booleana ser reavaliada.

_Livro_Sharp_Visual.indb 121 30/06/14 15:04


122 PARTE I Introduo ao Microsoft Visual C# e ao Microsoft Visual Studio 2013

Dica Como na construo while, considerada uma boa prtica usar sempre
um bloco de cdigo, mesmo que o corpo do loop for seja composto de apenas
uma instruo. Caso mais instrues sejam adicionadas ao corpo do loop for
posteriormente, essa estratgia ajudar a garantir que o cdigo seja sempre
executado como parte de cada iterao.

Voc pode omitir qualquer uma das trs partes de uma instruo for. Se voc
omitir a expresso booleana, ela assumir true por padro; portanto, a instruo for a
seguir executada indefinidamente:
for (int i = 0; ;i++)
{
Console.WriteLine("somebody stop me!");
}

Se voc omitir as partes da inicializao e atualizao, ter um loop while escrito


de forma estranha:
int i = 0;
for (; i < 10; )
{
Console.WriteLine(i);
i++;
}

Nota As partes inicializao, expresso booleana e atualizao da varivel de


controle de uma instruo for sempre devem ser separadas por ponto e vrgula,
mesmo quando omitidas.

Tambm possvel fornecer vrias inicializaes e vrias atualizaes em um


loop for. (Contudo, voc pode ter somente uma expresso booleana.) Para conseguir
isso, separe as vrias inicializaes e atualizaes com vrgulas, como mostrado no
exemplo a seguir:
for (int i = 0, j = 10; i <= j; i++, j--)
{
...
}

Como um ltimo exemplo, observe o loop while do exerccio anterior reescrito


como um loop for :
for (string line = reader.ReadLine(); line != null; line = reader.ReadLine())
{
source.Text += line + '\n';
}

_Livro_Sharp_Visual.indb 122 30/06/14 15:04


CAPTULO 5 Atribuio composta e instrues de iterao 123

Entendendo o escopo da instruo for


Talvez voc tenha notado que possvel declarar uma varivel na parte da inicializao
de uma instruo for. Essa varivel tem o escopo definido para o corpo da instruo
for e desaparece quando a instruo for termina. Essa regra tem duas consequncias
importantes. Em primeiro lugar, voc no pode utilizar essa varivel aps a instruo
for ter terminado, porque ela no estar mais em escopo. Veja o exemplo:
for (int i = 0; i < 10; i++)
{
...
}
Console.WriteLine(i); // erro de tempo de compilao

Segundo, voc pode escrever duas ou mais instrues for que reutilizam o mes-
mo nome de varivel, porque cada varivel est em um escopo diferente, como no
cdigo a seguir:
for (int i = 0; i < 10; i++)
{
...
}
for (int i = 0; i < 20; i += 2) // ok
{
...
}

Escreva instrues do
As instrues while e for testam suas expresses booleanas no incio do loop. Isso
significa que, se a expresso avaliada como false no primeiro teste, o corpo do loop
no executado nem mesmo uma vez. A instruo do diferente: sua expresso
booleana avaliada aps cada iterao e, portanto, o corpo sempre executado ao
menos uma vez.
A sintaxe da instruo do a seguinte (no esquea o ponto e vrgula final):
do
instruo
while (expressoBooleana);

Se o corpo do loop contiver mais de uma instruo, voc deve utilizar um bloco
de instrues (se no fizer isso, o compilador informar um erro de sintaxe). Aqui est
uma verso do exemplo que escreve os valores de 0 a 9 no console, desta vez cons-
truda utilizando uma instruo do:
int i = 0;
do
{
Console.WriteLine(i);
i++;
}
while (i < 10);

_Livro_Sharp_Visual.indb 123 30/06/14 15:04


124 PARTE I Introduo ao Microsoft Visual C# e ao Microsoft Visual Studio 2013

As instrues break e continue


No Captulo 4, voc viu como utilizar a instruo break para sair de uma instruo
switch. Uma instruo break tambm pode ser utilizada para sair do corpo de
uma instruo de iterao. Quando voc sai de um loop, ele encerra imediata-
mente e a execuo continua na primeira instruo aps o loop. Nem a atualiza-
o nem a condio de continuao do loop so executadas novamente.
Por outro lado, a instruo continue faz o programa executar imediatamen-
te a prxima iterao do loop (depois de avaliar de novo a expresso booleana).
Observe uma verso do exemplo anterior que escreve os valores de 0 a 9 no
console, desta vez utilizando as instrues break e continue:
int i = 0;
while (true)
{
Console.WriteLine("continue " + i);
i++;
if (i < 10)
continue;
else
break;
}

Esse cdigo medonho. Muitas diretrizes de programao recomendam a


utilizao cautelosa da instruo continue ou simplesmente no utiliz-la, porque
ela est muitas vezes associada a um cdigo difcil de entender. O comporta-
mento de continue tambm muito sutil. Por exemplo, se voc executar uma
instruo continue de dentro de uma instruo for, a parte da atualizao ser
executada antes da execuo da prxima iterao do loop.

No exerccio a seguir, voc vai escrever uma instruo do para converter um


nmero inteiro decimal positivo na sua representao de string em notao octal.
O programa se baseia no seguinte algoritmo, fundamentado em um procedimento
matemtico conhecido:
armazene o nmero decimal na varivel dec
faa o seguinte
divida dec por 8 e armazene o resto
defina dec com o quociente do passo anterior
enquanto dec no igual a zero
combine os valores armazenados para o resto em cada clculo, em ordem inversa

Por exemplo, vamos supor que voc queira converter o nmero decimal 999 em
octal. Execute as seguintes etapas:
1. Divida 999 por 8. O quociente 124 e o resto 7.
2. Divida 124 por 8. O quociente 15 e o resto 4.
3. Divida 15 por 8. O quociente 1 e o resto 7.
4. Divida 1 por 8. O quociente 0 e o resto 1.

_Livro_Sharp_Visual.indb 124 30/06/14 15:04


CAPTULO 5 Atribuio composta e instrues de iterao 125

5. Combine os valores calculados para o resto em cada etapa, em ordem inversa. O


resultado 1747. Essa a representao octal do valor decimal 999.

Escreva uma instruo do


1. Utilizando Visual Studio 2013, abra o projeto DoStatement, localizado na pasta
\Microsoft Press\Visual CSharp Step By Step\Chapter 5\Windows X\DoStatement
na sua pasta Documentos.
2. Exiba o formulrio MainWindow.xaml na janela Design View.
O formulrio contm uma caixa de texto chamada number, na qual o usurio
pode digitar um nmero decimal. Quando o usurio clicar no boto Show Steps,
a representao octal do nmero inserido ser gerada. A caixa de texto direita,
chamada steps, mostra os resultados de cada estgio do clculo.
3. Exiba o cdigo de MainWindow.xaml.cs na janela Code and Text Editor. Localize
o mtodo showStepsClick.
Esse mtodo executado quando o usurio clica no boto Show Steps do for-
mulrio. Atualmente, ele est vazio.
4. Adicione ao mtodo showStepsClick as instrues que aparecem em negrito a
seguir:
private void showStepsClick(object sender, RoutedEventArgs e)
{
int amount = int.Parse(number.Text);
steps.Text = "";
string current = "";
}

A primeira instruo converte o valor da string na propriedade Text da caixa de


texto number em um tipo int usando o mtodo Parse do tipo int e o armazena
em uma varivel local, chamada amount.
A segunda instruo limpa o texto exibido na caixa de texto inferior, definindo
sua propriedade Text como uma string vazia.
A terceira instruo declara uma varivel string chamada current e a inicializa
como a string vazia. Voc vai usar essa string para armazenar os dgitos gerados
em cada iterao do loop utilizado para converter o nmero decimal em sua
representao octal.
5. Adicione a seguinte instruo do, que aparece em negrito, ao mtodo showS-
tepsClick:
private void showStepsClick(object sender, RoutedEventArgs e)
{
int amount = int.Parse(number.Text);
steps.Text = "";
string current = "";

do
{

_Livro_Sharp_Visual.indb 125 30/06/14 15:04


126 PARTE I Introduo ao Microsoft Visual C# e ao Microsoft Visual Studio 2013

int nextDigit = amount % 8;


amount /= 8;
int digitCode = '0' + nextDigit;
char digit = Convert.ToChar(digitCode);
current = digit + current;
steps.Text += current + "\n";
}
while (amount != 0);
}

O algoritmo efetua repetidamente aritmtica de inteiros para dividir a varivel


amount por 8 e determinar o resto. O resto depois de cada diviso sucessiva
constitui o prximo dgito na string que est sendo construda. Por fim, quando
amount reduzida a 0, o loop termina. Observe que o corpo deve ser executado
ao menos uma vez. Esse comportamento exatamente o que necessrio, por-
que mesmo o nmero 0 tem um dgito octal.
Examine o cdigo de forma mais minuciosa; voc ver que a primeira instruo
executada pelo loop do esta:
int nextDigit = amount % 8;

Essa instruo declara uma varivel int chamada nextDigit e a inicializa como o
resto da diviso do valor em amount por 8. Isso ser um nmero em algum lugar
entre 0 e 7.
A prxima instruo no loop do
amount /= 8;

Essa uma instruo de atribuio composta e equivale a escrever amount =


amount / 8;. Se o valor de amount for 999, o valor de amount depois da execu-
o dessa instruo ser 124.
A prxima instruo esta:
int digitCode = 0 + nextDigit;

Essa expresso exige uma pequena explicao. Os caracteres tm um cdigo


nico, de acordo com o conjunto de caracteres utilizado pelo sistema operacio-
nal. Nos conjuntos de caracteres frequentemente utilizados pelo sistema opera-
cional Microsoft Windows, o cdigo para o caractere 0 tem o valor inteiro 48.
O cdigo para o caractere 1 49, o cdigo para o caractere 2 50 e assim
por diante at o cdigo para o caractere 9, que tem o valor inteiro 57. No C#
possvel tratar um caractere como um inteiro e efetuar aritmtica nele, mas,
quando voc faz isso, o C# utiliza o cdigo do caractere como o valor. Portanto,
a expresso 0 + nextDigit na verdade resultar em um valor em algum lugar
entre 48 e 55 (lembre-se de que nextDigit estar entre 0 e 7), correspondente ao
cdigo para o dgito octal equivalente.
A quarta instruo no loop do
char digit = Convert.ToChar(digitCode);

Essa instruo declara uma varivel char chamada digit e a inicializa para o re-
sultado da chamada do mtodo Convert.ToChar(digitCode). O mtodo Convert.
ToChar recebe um inteiro que contm um cdigo de caractere e retorna o carac-

_Livro_Sharp_Visual.indb 126 30/06/14 15:04


CAPTULO 5 Atribuio composta e instrues de iterao 127

tere correspondente. Assim, por exemplo, se digitCode tiver o valor 54, Convert.
ToChar(digitCode) retornar o caractere 6.
Resumindo, as trs primeiras instrues no loop do determinaram o caractere
que representa o dgito octal menos significativo (mais direita) correspondente
ao nmero digitado pelo usurio. A tarefa seguinte incluir esse dgito no incio
da string a ser apresentada na sada, como segue:
current = digit + current;

A prxima instruo no loop do esta:


steps.Text += current + \n;

Essa instruo adiciona caixa de texto steps a string que contm os dgitos pro-
duzidos at agora para a representao octal do nmero. A instruo tambm
inclui um caractere de nova linha, para que cada estgio da converso aparea
em uma linha separada na caixa de texto.
Por fim, a condio na clusula while no fim do loop avaliada:
while (amount!= 0);

Como o valor de amount ainda no 0, o loop faz mais uma iterao.


No exerccio final deste captulo, voc utilizar o depurador do Visual Studio
2013 para inspecionar passo a passo a instruo do anterior, para ajud-lo a entender
como ela funciona.

Inspecione passo a passo a instruo do


1. Na janela Code and Text Editor que exibe o arquivo MainWindow.xaml.cs, mova
o cursor para a primeira instruo do mtodo showStepsClick:
int amount = int.Parse(number.Text);

2. Clique com o boto direito do mouse em qualquer lugar da primeira instruo e,


no menu de atalho que aparece, clique em Run To Cursor.
3. Quando o formulrio aparecer, digite 999 na caixa de texto number esquerda
e, em seguida, clique em Show Steps.
O programa para e voc colocado no modo de depurao do Visual Studio
2013. Uma seta amarela na margem esquerda da janela Code and Text Editor e o
realce amarelo do cdigo indicam a instruo atual.
4. Exiba a barra de ferramentas Debug, se ainda no estiver visvel. No menu View,
aponte para Toolbars e clique em Debug.
5. Na barra de ferramentas Debug, clique na seta suspensa, aponte para Add Or
Remove Buttons e, em seguida, selecione Windows, como mostrado na imagem
a seguir:

_Livro_Sharp_Visual.indb 127 30/06/14 15:04


128 PARTE I Introduo ao Microsoft Visual C# e ao Microsoft Visual Studio 2013

Essa ao adiciona o boto Breakpoints Window barra de ferramentas.


6. Na barra de ferramentas Debug, clique no boto Breakpoints Window e ento
em Locals.

A janela Locals aparece (se ainda no estiver aberta). Essa janela exibe o nome,
o valor e o tipo das variveis locais no mtodo atual, incluindo a varivel local
amount. Observe que o valor de amount no momento 0:

_Livro_Sharp_Visual.indb 128 30/06/14 15:04


CAPTULO 5 Atribuio composta e instrues de iterao 129

7. Na barra de ferramentas Debug, clique no boto Step Into.


O depurador executa a seguinte instruo:
int amount = int.Parse(number.Text);

O valor de amount na janela Locals muda para 999 e a seta amarela se move
para a prxima instruo.
8. Clique novamente em Step Into.
O depurador executa esta instruo:
steps.Text = ;

Essa instruo no afeta a janela Locals porque steps um campo do formulrio


e no uma varivel local. A seta amarela se move para a prxima instruo.

_Livro_Sharp_Visual.indb 129 30/06/14 15:04


130 PARTE I Introduo ao Microsoft Visual C# e ao Microsoft Visual Studio 2013

9. Clique em Step Into.


O depurador executa a instruo mostrada aqui:
string current = "";

A seta amarela se move para a chave de abertura no incio do loop do. O loop
do contm trs variveis locais prprias: nextDigit, digitCode e digit. Observe que
essas variveis locais aparecem na janela Locals o valor das trs variveis ini-
cialmente configurado como 0.
10. Clique em Step Into.
A seta amarela se move para a primeira instruo dentro do loop do.
11. Clique em Step Into.
O depurador executa a seguinte instruo:
int nextDigit = amount % 8;

O valor de nextDigit na janela Locals muda para 7. Esse o resto depois da divi-
so de 999 por 8.
12. Clique em Step Into.
O depurador executa esta instruo:
amount /= 8;

O valor de amount muda para 124 na janela Locals.


13. Clique em Step Into.
O depurador executa esta instruo:
int digitCode = '0' + nextDigit;

O valor de digitCode na janela Locals muda para 55. Esse o cdigo do caractere
7 (48 + 7).
14. Clique em Step Into.
O depurador continua nesta instruo:
char digit = Convert.ToChar(digitCode);

O valor de digit muda para 7 na janela Locals. A janela Locals mostra valores
char utilizando tanto o valor numrico subjacente (nesse caso, 55) como tam-
bm a representao em caractere (7).
Observe que, na janela Locals, o valor da varivel current ainda .

_Livro_Sharp_Visual.indb 130 30/06/14 15:04


CAPTULO 5 Atribuio composta e instrues de iterao 131

15. Clique em Step Into.


O depurador executa a seguinte instruo:
current = current + digit;

O valor de current muda para 7 na janela Locals.


16. Clique em Step Into.
O depurador executa a instruo mostrada aqui:
steps.Text += current + \n;

Essa instruo exibe o texto 7 na caixa de texto steps, seguido por um carac-
tere de nova linha para fazer a sada subsequente ser exibida na prxima linha
na caixa de texto. (O formulrio atualmente est oculto atrs do Visual Studio;
portanto, voc no ser capaz de v-lo.) O cursor se desloca para a chave de
fechamento no final do loop do.
17. Clique em Step Into.
A seta amarela se move para a instruo while para avaliar se o loop do foi con-
cludo ou se deve continuar para outra iterao.
18. Clique em Step Into.
O depurador executa esta instruo:
while (amount != 0);

O valor de amount 124 e a expresso 124!= 0 avaliada como true; portanto,


o loop do faz outra iterao. A seta amarela retorna chave de abertura no incio
do loop do.
19. Clique em Step Into.
A seta amarela se move novamente para a primeira instruo dentro do loop do.
20. Clique repetidamente em Step Into para investigar as trs iteraes seguintes do
loop do e observe como os valores das variveis mudam na janela Locals.
21. No fim da quarta iterao do loop, o valor de amount agora 0 e o valor de
current 1747. A seta amarela est na condio while no final do loop do:
while (amount != 0);

Como o valor de amount agora 0, a expresso amount!= 0 avaliada como


false e o loop do termina.
22. Clique em Step Into.
O depurador executa a seguinte instruo:
while (amount != 0);

_Livro_Sharp_Visual.indb 131 30/06/14 15:04


132 PARTE I Introduo ao Microsoft Visual C# e ao Microsoft Visual Studio 2013

Conforme previsto, o loop do termina e a seta amarela se move para a chave de


fechamento no final do mtodo showStepsClick.
23. No menu Debug, clique em Continue.
O formulrio aparece, exibindo as quatro etapas utilizadas para criar uma repre-
sentao octal de 999: 7, 47, 747 e 1747.

24. Retorne ao Visual Studio 2013. No menu Debug, clique em Stop Debugging (ou
feche o aplicativo, se estiver usando o Windows 7 ou o Windows 8).

Resumo
Neste captulo, voc aprendeu a utilizar os operadores de atribuio composta para
atualizar variveis numricas. Voc viu como possvel utilizar as instrues while, for
e do para executar o cdigo vrias vezes, enquanto uma condio booleana for true.
j Se quiser continuar no prximo captulo, mantenha o Visual Studio 2013 execu-
tando e v para o Captulo 6, Gerenciamento de erros e excees.
j Se quiser encerrar o Visual Studio 2013 agora, no menu File, clique em Exit. Se vir
uma caixa de dilogo Save, clique em Yes e salve o projeto.

_Livro_Sharp_Visual.indb 132 30/06/14 15:04


CAPTULO 5 Atribuio composta e instrues de iterao 133

Referncia rpida

Para Faa isto


Adicionar uma quantidade a uma varivel Utilize o operador de adio composto.
Por exemplo:
variable += amount;

Subtrair uma quantidade de uma varivel Utilize o operador de subtrao


composto. Por exemplo:
variable -= amount;

Executar uma ou mais instrues zero ou mais Utilize uma instruo while. Por exemplo:
vezes, enquanto uma condio for verdadeira
int i = 0;
while (i < 10)
{
Console.WriteLine(i);
i++;
}

Como alternativa, utilize uma instruo


for. Por exemplo:
for (int i = 0; i < 10; i++)
{
Console.WriteLine(i);
}

Executar repetidamente as instrues uma ou Utilize uma instruo do. Por exemplo:
mais vezes
int i = 0;
do
{
Console.WriteLine(i);
i++;
}
while (i < 10);

_Livro_Sharp_Visual.indb 133 30/06/14 15:04


CAPTULO 6

Gerenciamento de erros
e excees
Neste captulo, voc vai aprender a:
j Tratar excees utilizando as instrues try, catch e finally.
j Controlar o overflow de nmeros inteiros utilizando as palavras-chave checked
e unchecked.
j Levantar excees a partir de seus mtodos utilizando a palavra-chave throw.
j Garantir que o cdigo sempre execute, mesmo aps a ocorrncia de uma exce-
o, utilizando um bloco finally.
At aqui, voc aprendeu as principais instrues do C# necessrias para a execuo
das tarefas comuns, como escrever mtodos, declarar variveis, utilizar operadores
para criar valores, escrever instrues if e switch para a execuo de um cdigo de
modo seletivo e escrever instrues while, for e do para executar cdigo repetidamen-
te. Os captulos anteriores, entretanto, no consideraram a possibilidade (ou probabi-
lidade) de alguma coisa dar errado.
Garantir que o cdigo sempre funcione conforme o esperado muito difcil.
As falhas podem acontecer por inmeros motivos, e muitos deles esto alm do seu
controle como programador. Todos os aplicativos que voc escrever devem ter a capa-
cidade de detectar falhas e tratar delas elegantemente, executando as aes corretivas
adequadas ou, se isso no for possvel, informando as razes da falha de modo claro
para o usurio. Neste ltimo captulo da Parte I, voc vai aprender como o C# usa
excees para sinalizar uma falha e como utilizar as instrues try, catch e finally para
capturar e lidar com os erros que essas excees representam.
Por fim, voc ter uma base slida a respeito de todos os elementos fundamen-
tais do C#, sobre a qual desenvolver seu conhecimento na Parte II.

Lide com erros


s vezes, coisas ruins acontecem e isso faz parte da vida. Pneus furam, baterias des-
carregam, ferramentas nunca ficam onde voc as deixou e os usurios de seus aplica-
tivos se comportam de maneira imprevisvel. No mundo dos computadores, os discos
rgidos estragam, outros aplicativos em execuo no mesmo computador em que seu
programa executado consomem toda a memria disponvel de modo descontro-
lado, conexes de rede sem fio desaparecem no momento mais inoportuno e at
fenmenos naturais, como uma descarga eltrica, podem ter um impacto, se causa-
rem queda de energia ou uma falha da rede. Erros podem ocorrer em praticamente

_Livro_Sharp_Visual.indb 134 30/06/14 15:04


CAPTULO 6 Gerenciamento de erros e excees 135

qualquer estgio da execuo de um programa e muitos deles podem nem mesmo ser
falha de seu aplicativo; portanto, como detect-los e tentar se recuperar deles?
Ao longo dos anos, vrios mecanismos foram criados. Uma estratgia tpica,
adotada por sistemas mais antigos, como o UNIX, envolvia determinar que o sistema
operacional definisse uma varivel global especial sempre que um mtodo falhasse.
Ento, depois de cada chamada a um mtodo, voc verificava a varivel global para
ver se o mtodo havia sido bem-sucedido. O C# e a maioria das outras linguagens
modernas orientadas a objetos no tratam erros dessa maneira; trabalhoso demais.
Em vez disso, elas utilizam excees. Se quiser escrever programas robustos em C#,
voc precisa conhecer as excees.

Teste o cdigo e capture as excees


Os erros podem acontecer a qualquer momento, e o uso de tcnicas tradicionais para
adicionar manualmente um cdigo de deteco de erro em torno de cada instruo
complicado, lento e propenso a erros. Voc tambm pode perder de vista o fluxo prin-
cipal de um aplicativo se cada instruo exigir uma lgica enrolada de tratamento de
erros para gerenciar cada possvel erro que ocorra em cada estgio. Felizmente, o C#
facilita separar o cdigo de tratamento do cdigo que implementa a lgica principal de
um programa, utilizando as excees e as rotinas de tratamento de exceo. Para escre-
ver programas compatveis com excees, voc precisa fazer duas coisas:
j Escrever o cdigo dentro de um bloco try (try uma palavra-chave do C#).
Quando o cdigo executa, ele tenta executar todas as instrues no bloco try
e, se nenhuma das instrues gerar uma exceo, todas sero executadas, uma
aps a outra, at a concluso. Mas, se uma condio de erro ocorrer, a execuo
sai do bloco try e vai at outro fragmento de cdigo projetado para capturar e
tratar a exceo uma rotina de tratamento catch (em ingls, catch handler).
j Escrever uma ou mais rotinas de tratamento catch (catch outra palavra-chave
do C#) imediatamente aps o bloco try para tratar todas as condies de erro
possveis. Uma rotina de tratamento catch concebida para capturar e tratar um
tipo de exceo especfico e voc pode ter vrias rotinas de tratamento catch
depois de um bloco try, cada uma projetada para interceptar e processar uma
exceo especfica para que voc possa fornecer diferentes rotinas de tratamento
para os diferentes erros que possam surgir no bloco try. Se qualquer uma das
instrues dentro do bloco try causar um erro, o runtime lanar uma exceo. O
runtime examina ento as rotinas de tratamento catch aps o bloco try e transfe-
re o controle diretamente para a primeira rotina de tratamento correspondente.
Observe um exemplo de cdigo em um bloco try que tenta converter para valores
inteiros as strings digitadas por um usurio em algumas caixas de texto de um formu-
lrio, chamar um mtodo para calcular um valor e gravar o resultado em outra caixa de
texto. Converter uma string em um nmero inteiro exige que a sequncia contenha um
conjunto de dgitos vlidos e no alguma string arbitrria. Se a sequncia contm carac-
teres invlidos, o mtodo int.Parse lana uma FormatException e a execuo transfe-
rida para a rotina de tratamento catch correspondente. Quando a rotina de tratamento
catch termina, o programa continua na primeira instruo aps a rotina de tratamento.
Observe que, se no houver uma rotina de tratamento que corresponda exceo, diz-
-se que a exceo no tratada (essa situao ser descrita em breve).

_Livro_Sharp_Visual.indb 135 30/06/14 15:04


136 PARTE I Introduo ao Microsoft Visual C# e ao Microsoft Visual Studio 2013

try
{
int leftHandSide = int.Parse(lhsOperand.Text);
int rightHandSide = int.Parse(rhsOperand.Text);
int answer = doCalculation(leftHandSide, rightHandSide);
result.Text = answer.ToString();
}
catch (FormatException fEx)
{
// Trata a exceo
...
}

Uma rotina de tratamento catch emprega uma sintaxe similar utilizada por um
parmetro de mtodo para especificar a exceo a ser capturada. No exemplo ante-
rior, quando FormatException lanada, a varivel fEx preenchida com um objeto
que contm os detalhes da exceo.
O tipo FormatException possui vrias propriedades que voc pode examinar para
determinar a causa exata da exceo. Muitas dessas propriedades so comuns a todas
as excees. Por exemplo, a propriedade Message contm uma descrio textual do
erro que provocou a exceo. Voc pode utilizar essas informaes ao tratar a exceo,
talvez gravando os detalhes em um arquivo de log ou exibindo uma mensagem sig-
nificativa para o usurio e, depois, solicitando que ele tente novamente, por exemplo.

Excees no tratadas
O que acontece se um bloco try lana uma exceo e no h uma rotina de tratamen-
to catch correspondente? No exemplo anterior, possvel que a caixa de texto lhsOpe-
rand contenha a representao em string de um nmero inteiro vlido, mas o inteiro
representado esteja fora do intervalo de nmeros inteiros vlidos suportado pelo C#
(por exemplo, 2147483648). Nesse caso, a instruo int.Parse lana uma OverflowE-
xception que no ser capturada pela rotina de tratamento catch de FormatException.
Se isso ocorrer e o bloco try for parte de um mtodo, este se encerrar imediatamente
e a execuo retornar ao mtodo chamador. Se o mtodo chamador utiliza um bloco
try, o runtime tenta localizar e executar a rotina de tratamento catch correspondente
para esse bloco try. Se o mtodo chamador no utiliza um bloco try ou no h uma
rotina de tratamento catch correspondente, o mtodo chamador encerra imediata-
mente e a execuo retorna ao seu chamador, onde o processo repetido. Se uma
rotina de tratamento catch correspondente por fim encontrada, a rotina executada
e a execuo continua na primeira instruo aps a rotina de tratamento catch no
mtodo de captura.

Importante Observe que, aps a captura de uma exceo, a execuo conti-


nua no mtodo que contm o bloco catch que a capturou. Se a exceo ocorreu
em um mtodo alm daquele que contm a rotina de tratamento catch, o con-
trole no retorna ao mtodo que causou a exceo.

Se, aps retornar pela cascata de mtodos chamadores, o runtime for incapaz
de encontrar uma rotina de tratamento catch correspondente, o programa terminar
com uma exceo no tratada.

_Livro_Sharp_Visual.indb 136 30/06/14 15:04


CAPTULO 6 Gerenciamento de erros e excees 137

Voc pode examinar facilmente as excees geradas por seu aplicativo. Se voc
estiver executando o aplicativo no Microsoft Visual Studio 2013 no modo de depurao
(isto , voc selecionou Start Debugging no menu Debug para executar o aplicativo)
e uma exceo ocorrer, ser exibida uma caixa de dilogo semelhante da imagem a
seguir e o aplicativo far uma pausa para que voc determine a causa da exceo:

O aplicativo paralisado na instruo que causou a exceo e voc entra no


depurador. Voc pode examinar e alterar os valores de variveis e pode analisar seu
cdigo a partir do ponto em que a exceo ocorreu, utilizando a barra de ferramentas
Debug e as vrias janelas de depurao.

Utilize vrias rotinas de tratamento catch


A discusso anterior destacou como diferentes erros lanam diferentes tipos de ex-
ceo para representar diferentes tipos de falhas. Para lidar com essas situaes, voc
pode fornecer vrias rotinas de tratamento catch, uma aps a outra, como neste caso:
try
{
int leftHandSide = int.Parse(lhsOperand.Text);
int rightHandSide = int.Parse(rhsOperand.Text);
int answer = doCalculation(leftHandSide, rightHandSide);
result.Text = answer.ToString();
}
catch (FormatException fEx)
{
//...
}
catch (OverflowException oEx)
{
//...
}

_Livro_Sharp_Visual.indb 137 30/06/14 15:04


138 PARTE I Introduo ao Microsoft Visual C# e ao Microsoft Visual Studio 2013

Se o cdigo no bloco try lanar uma exceo FormatException, as instrues


no bloco catch para a exceo FormatException sero executadas. Se o cdigo lanar
uma exceo OverflowException, o bloco catch para a exceo OverflowException ser
executado.

Nota Se o cdigo no bloco catch de FormatException gerar uma exceo


OverflowException, o bloco catch de OverflowException adjacente no ser exe-
cutado. Em vez disso, a exceo se propagar para o mtodo que chamou o
cdigo, como descrito anteriormente nesta seo.

Capture mltiplas excees


O mecanismo de captura de excees fornecido pelo C# e pelo Microsoft .NET Fra-
mework bem abrangente. O .NET Framework define vrios tipos de excees, e qual-
quer programa que voc escreva poder lanar a maioria delas. bastante improvvel
que voc queira escrever rotinas de tratamento catch para cada exceo possvel que
seu cdigo possa lanar lembre-se de que seu aplicativo deve ser capaz de tratar de
excees que voc nem mesmo considerou ao escrev-lo! Ento, como voc assegura
que seus programas capturam e tratam todas as possveis excees?
A resposta a essa pergunta est na maneira como as diferentes excees esto
relacionadas entre si. As excees so organizadas em famlias chamadas hierarquias
de herana. (Voc aprender sobre herana no Captulo 12, Herana.) FormatExcep-
tion e OverflowException pertencem a uma famlia chamada SystemException, assim
como vrias outras excees. SystemException um membro de uma famlia maior,
chamada Exception, que a bisav de todas as excees. Se voc capturar Exception, a
rotina de tratamento capturar todas as excees possveis que possam ocorrer.

Nota A famlia Exception inclui uma ampla variedade de excees, muitas delas
planejadas para serem usadas por vrias partes do .NET Framework. Algumas
dessas excees so um pouco esotricas, mas ainda assim til entender como
captur-las.

O prximo exemplo mostra como capturar todas as possveis excees:


try
{
int leftHandSide = int.Parse(lhsOperand.Text);
int rightHandSide = int.Parse(rhsOperand.Text);
int answer = doCalculation(leftHandSide, rightHandSide);
result.Text = answer.ToString();
}
catch (Exception ex) // esta uma rotina de tratamento catch geral
{
//...
}

_Livro_Sharp_Visual.indb 138 30/06/14 15:04


CAPTULO 6 Gerenciamento de erros e excees 139

Dica Se quiser capturar a exceo Exception, voc pode omitir seu nome na
rotina de tratamento catch, porque ela a exceo padro:
catch
{
// ...
}

Mas isso no recomendado. O objeto exceo passado para a rotina de trata-


mento catch contm informaes teis referentes exceo, as quais no so
facilmente acessveis ao se utilizar essa verso da construo catch.

Neste ponto, h uma ltima pergunta que voc deve estar fazendo: o que acon-
tece se a mesma exceo corresponder a vrias rotinas de tratamento catch no final
de um bloco try? Se voc capturar FormatException e Exception em duas rotinas de
tratamento diferentes, qual delas ser executada? (Ou ambas sero executadas?)
Quando ocorre uma exceo, o runtime utiliza a primeira rotina de tratamento
correspondente exceo que encontra e as outras so ignoradas. Isso significa que,
se voc colocar uma rotina de tratamento para Exception antes de uma rotina de tra-
tamento para FormatException, a rotina de tratamento de FormatException nunca ser
executada. Portanto, voc deve colocar as rotinas de tratamento catch mais especficas
acima de uma rotina de tratamento catch geral, depois de um bloco try. Se as rotinas
de tratamento catch especficas no correspondem exceo, a rotina de tratamento
catch geral corresponder.
Nos exerccios a seguir, voc vai ver o que acontece quando um aplicativo lana
uma exceo no tratada e, em seguida, vai escrever um bloco try, alm de capturar e
tratar de uma exceo.

Observe como o Windows relata excees no tratadas


1. Inicie o Visual Studio 2013, se ele ainda no estiver em execuo.
2. Abra a soluo MathsOperators, localizada na pasta \Microsoft Press\Visual
CSharp Step By Step\Chapter 6\Windows X\MathsOperators na sua pasta Docu-
mentos.
Essa uma verso do programa do Captulo 2, Variveis, operadores e expres-
ses, que demonstra os diferentes operadores aritmticos.
3. No menu Debug, clique em Start Without Debugging.

Nota Para este exerccio, certifique-se de executar o aplicativo sem de-


purar, mesmo que esteja usando o Windows 8.1.

O formulrio aparece. Agora voc digitar na caixa Left Operand um texto que
causar uma exceo. Essa operao demonstrar a falta de robustez da verso
atual do programa.

_Livro_Sharp_Visual.indb 139 30/06/14 15:04


140 PARTE I Introduo ao Microsoft Visual C# e ao Microsoft Visual Studio 2013

4. Digite John na caixa Left Operand, digite 2 na caixa Right Operand, clique no
boto + Addition e ento clique em Calculate.
Essa ao aciona o tratamento de erros do Windows. Se estiver utilizando o Win-
dows 8.1, o aplicativo terminar e voc voltar para a tela Iniciar.
Se estiver utilizando a verso para Windows 7 do cdigo, voc dever ver a se-
guinte caixa de mensagem:

Aps um curto espao de tempo, essa caixa seguida por outra caixa de dilogo
reportando uma exceo no tratada:

Se clicar em Debug, voc poder lanar uma nova instncia do Visual Studio
sobre seu programa no modo de depurao, mas, por hora, clique em Close
Program.
Voc poder ver uma das seguintes verses dessa caixa de dilogo, dependendo
de como configurou o informe de problemas no painel de controle.

_Livro_Sharp_Visual.indb 140 30/06/14 15:04


CAPTULO 6 Gerenciamento de erros e excees 141

Se uma dessas caixas de dilogo aparecer, clique em Close The Program.


Alm disso, deve ser exibida uma caixa de dilogo com a mensagem Do you
want to send information about the problem?. O Windows pode reunir infor-
maes sobre os aplicativos com falha e envi-las para a Microsoft. Se essa caixa
de dilogo aparecer, clique em Cancel.
Agora que voc viu como o Windows captura e relata excees no tratadas,
o prximo passo tornar o aplicativo mais robusto, tratando de entradas invlidas e
impedindo a ocorrncia de excees no tratadas.

Escreva um bloco de instrues try/catch


1. Retorne ao Visual Studio 2013.
2. No menu Debug, clique em Start Debugging.
3. Quando o formulrio aparecer, digite John na caixa Left Operand, digite 2 na
caixa Right Operand, clique no boto + Addition e ento clique em Calculate.
Essa entrada deve causar a mesma exceo que ocorreu no exerccio anterior,
exceto que, agora, voc est executando no modo de depurao, de maneira
que o Visual Studio captura a exceo e a relata.

Nota Se aparecer uma caixa de mensagem informando que o modo


break falhou porque o arquivo App.g.i.cs no pertence ao projeto que est
sendo depurado, basta clicar em OK. Quando a caixa de mensagem desa-
parecer, a exceo ser exibida.

4. O Visual Studio exibe o seu cdigo e destaca a instruo que causou a exceo,
juntamente com uma caixa de dilogo que descreve essa exceo. Neste caso, a
informao a seguinte: Input string was not in a correct format.

_Livro_Sharp_Visual.indb 141 30/06/14 15:04


142 PARTE I Introduo ao Microsoft Visual C# e ao Microsoft Visual Studio 2013

Voc pode ver que a exceo foi lanada pela chamada a int.Parse dentro do
mtodo addValues. Esse mtodo, porm, incapaz de processar o texto John
em um nmero vlido.
5. Na caixa de dilogo de exceo, clique em View Detail.
Outra caixa de dilogo se abre, na qual possvel ver mais informaes sobre a
exceo. Se voc expandir System.FormatException, poder ver esta informao:

_Livro_Sharp_Visual.indb 142 30/06/14 15:04


CAPTULO 6 Gerenciamento de erros e excees 143

Dica Algumas excees resultam de outras lanadas anteriormente. A ex-


ceo relatada pelo Visual Studio apenas a ltima nesse encadeamento,
mas, em geral, so as excees anteriores que destacam a causa real do
problema. Voc pode examinar essas excees anteriores expandindo a
propriedade InnerException na caixa de dilogo View Detail. As excees
internas podem ter mais excees internas, e voc pode ir se aprofundan-
do at encontrar uma exceo com a propriedade InnerException configu-
rada como null (como mostrado na imagem anterior). Nesse ponto, voc
atingiu a exceo inicial e normalmente essa exceo que precisa ser
corrigida.

6. Clique em OK na caixa de dilogo View Detail e, ento, no Visual Studio, no


menu Debug, clique em Stop Debugging.
7. Exiba o cdigo do arquivo MainWindow.xaml.cs na janela Code and Text Editor
e localize o mtodo addValues.
8. Adicione um bloco try (incluindo as chaves) em torno das instrues dentro des-
se mtodo, junto com uma rotina de tratamento catch para a exceo FormatE-
xception, como mostrado no texto em negrito aqui:
try
{
int lhs = int.Parse(lhsOperand.Text);
int rhs = int.Parse(rhsOperand.Text);
int outcome = 0;

outcome = lhs + rhs;


expression.Text = lhsOperand.Text + + + rhsOperand.Text;
result.Text = outcome.ToString();
}
catch (FormatException fEx)
{
result.Text = fEx.Message;
}

Se ocorrer uma exceo FormatException, a rotina de tratamento catch exibir


na caixa de texto result, na parte inferior do formulrio, o texto contido na pro-
priedade Message da exceo.
9. No menu Debug, clique em Start Debugging.
10. Quando o formulrio aparecer, digite John na caixa Left Operand, digite 2 na
caixa Right Operand, clique no boto + Addition e ento clique em Calculate.
A rotina de tratamento catch captura com sucesso a FormatException e a mensa-
gem Input string was not in a correct format escrita na caixa de texto Result.
O aplicativo agora est um pouco mais robusto.

_Livro_Sharp_Visual.indb 143 30/06/14 15:04


144 PARTE I Introduo ao Microsoft Visual C# e ao Microsoft Visual Studio 2013

11. Substitua John pelo nmero 10, digite Sharp na caixa Right Operand e, ento,
clique em Calculate.
O bloco try encerra as instrues que processam as duas caixas de texto, de
modo que a mesma rotina de tratamento de exceo trata os erros de entrada
de usurio em ambas as caixas de texto.
12. Na caixa Left Operand, substitua Sharp por 20, clique no boto + Addition e
ento clique em Calculate.
Agora o aplicativo funciona como previsto e exibe o valor 30 na caixa Result.
13. Na caixa Left Operand, substitua 10 por John e, ento, clique no boto
Subtraction.
O Visual Studio aciona o depurador e relata novamente uma exceo FormatEx-
ception. Desta vez, o erro ocorreu no mtodo subtractValues, o qual no contm
o processamento de try/catch necessrio.
14. No menu Debug, clique em Stop Debugging.

Propague excees
A adio de um bloco try/catch ao mtodo addValues tornou o mtodo mais robusto,
mas preciso aplicar o mesmo tratamento de exceo aos outros mtodos: subtrac-
tValues, multiplyValues, divideValues e remainderValues. O cdigo para cada uma des-
sas rotinas de tratamento de exceo provavelmente ser muito parecido, resultando
na escrita do mesmo cdigo em cada mtodo. Cada um desses mtodos chamado
pelo mtodo calculateClick quando o usurio clica no boto Calculate. Portanto, para
evitar a duplicao do cdigo de tratamento de exceo, faz sentido transferi-lo para
o mtodo calculateClick. Se ocorrer uma FormatException em qualquer um dos mto-
dos subtractValues, multiplyValues, divideValues e remainderValues, ela ser propagada

_Livro_Sharp_Visual.indb 144 30/06/14 15:04


CAPTULO 6 Gerenciamento de erros e excees 145

retroativamente para tratamento no mtodo calculateClick, conforme descrito na se-


o Excees no tratadas, anteriormente neste captulo.

Propague uma exceo de volta para o mtodo chamador


1. Exiba o cdigo do arquivo MainWindow.xaml.cs na janela Code and Text Editor
e localize o mtodo addValues.
2. Remova o bloco try e a rotina de tratamento catch do mtodo addValues e
retorne-o ao seu estado original, como mostrado no seguinte cdigo:
private void addValues()
{
int leftHandSide = int.Parse(lhsOperand.Text);
int rightHandSide = int.Parse(rhsOperand.Text);
int outcome = 0;

outcome = lhs + rhs;


expression.Text = lhsOperand.Text + + + rhsOperand.Text
result.Text = outcome.ToString();
}

3. Localize o mtodo calculateClick. Adicione a esse mtodo o bloco try e a rotina


de tratamento catch mostrados em negrito no exemplo a seguir:
private void calculateClick(object sender, RoutedEventArgs e)
{
try
{
if ((bool)addition.IsChecked)
{
addValues();
}
else if ((bool)subtraction.IsChecked)
{
subtractValues();
}
else if ((bool)multiplication.IsChecked)
{
multiplyValues();
}
else if ((bool)division.IsChecked)
{
divideValues();
}
else if ((bool)remainder.IsChecked)
{
remainderValues();
}
}
catch (FormatException fEx)
{
result.Text = fEx.Message;
}
}

_Livro_Sharp_Visual.indb 145 30/06/14 15:04


146 PARTE I Introduo ao Microsoft Visual C# e ao Microsoft Visual Studio 2013

4. No menu Debug, clique em Start Debugging.


5. Quando o formulrio aparecer, digite John na caixa Left Operand, digite 2 na
caixa Right Operand, clique no boto + Addition e ento clique em Calculate.
Como antes, a rotina de tratamento catch captura com sucesso a exceo For-
matException e a mensagem Input string was not in a correct format escrita
na caixa de texto Result. Contudo, lembre-se de que, na verdade, a exceo foi
lanada no mtodo addValue, mas capturada pela rotina de tratamento do m-
todo calculateClick.
6. Clique no boto Subtraction e, em seguida, clique em Calculate.
Desta vez, o mtodo subtractValues causa a exceo, mas ela propagada de
volta para o mtodo calculateClick e tratada da mesma maneira que antes.
7. Teste os botes * Multiplication, / Division e % Remainder e verifique se a exce-
o FormatException capturada e tratada corretamente.
8. Retorne ao Visual Studio e interrompa a depurao.

Nota A deciso de capturar explicitamente as excees no tratadas em um


mtodo depender da natureza do aplicativo que voc est compilando. Em al-
guns casos, faz sentido capturar excees o mais prximo possvel do ponto em
que elas ocorrem. Em outras situaes, mais til deixar que uma exceo se
propague de volta ao mtodo que invocou a rotina e lanou a exceo e tratar
o erro ali.

Aritmtica verificada e no verificada de


nmeros inteiros
O Captulo 2 discutiu como utilizar os operadores aritmticos binrios, como + e *, em
tipos de dados primitivos, como int e double. Vimos tambm que os tipos de dados
primitivos tm um tamanho fixo. Por exemplo, um int do C# tem 32 bits. Como int tem
um tamanho fixo, voc sabe exatamente o intervalo de valores que ele pode armaze-
nar: de 2147483648 a 2147483647.

Dica Se quiser referenciar o valor mnimo ou mximo de int no cdigo, utilize


a propriedade int.MinValue ou int.MaxValue.

O tamanho fixo de um tipo int cria um problema. Por exemplo, o que acontece
se voc adicionar 1 a um int cujo valor atualmente 2147483647? A resposta que
depende de como o aplicativo compilado. Por padro, o compilador C# gera um
cdigo que permite ao clculo ter um overflow (estouro) silencioso e voc obtm
uma resposta errada. (Na verdade, o clculo excede para o valor inteiro negativo e o
resultado gerado 2147483648.) O motivo desse comportamento o desempenho:
a aritmtica de nmeros inteiros uma operao comum em quase todos os progra-

_Livro_Sharp_Visual.indb 146 30/06/14 15:04


CAPTULO 6 Gerenciamento de erros e excees 147

mas e adicionar a sobrecarga de verificar o overflow em cada expresso de nmeros


inteiros pode levar a um desempenho muito deficiente. Em muitos casos, o risco
aceitvel porque voc sabe (ou espera!) que seus valores int no atinjam seus limites.
Se no gostar dessa estratgia, voc pode ativar a verificao de overflow.

Dica Voc pode ativar e desativar a verificao de overflow no Visual Studio


2013 definindo as propriedades do projeto. No Solution Explorer, clique em
SeuProjeto (onde SeuProjeto o nome real de seu projeto). No menu Project,
clique em SeuProjeto Properties. Na caixa de dilogo de propriedades do proje-
to, clique na guia Build. Clique no boto Advanced no canto inferior direito da
pgina. Na caixa de dilogo Advanced Build Settings, marque ou desmarque a
caixa de seleo Check For Arithmetic Overflow/Underflow.

Independentemente de como voc compila um aplicativo, possvel utilizar as


palavras-chave checked e unchecked para ativar e desativar seletivamente a verifica-
o de overflow aritmtico de inteiros nas partes de um aplicativo que voc julgar
necessrio. Essas palavras-chave redefinem a opo de compilador especificada para
o projeto.

Escreva instrues verificadas


Uma instruo verificada um bloco precedido pela palavra-chave checked. Toda a
aritmtica de nmeros inteiros em uma instruo verificada sempre lana uma Over-
flowException se um clculo de inteiros no bloco sofrer overflow, como mostrado neste
exemplo:
int number = int.MaxValue;
checked
{
int willThrow = number++;
Console.WriteLine(this wont be reached);
}

Importante Somente a aritmtica de inteiros diretamente dentro do bloco


checked est sujeita verificao de overflow. Por exemplo, se uma das instru-
es verificadas for uma chamada de mtodo, a verificao no se aplicar ao
cdigo que executa o mtodo chamado.

Voc tambm pode utilizar a palavra-chave unchecked para criar uma instruo
de bloco unchecked. Toda a aritmtica de inteiros em um bloco unchecked no veri-
ficada e nunca lana uma OverflowException. Por exemplo:
int number = int.MaxValue;
unchecked
{
int wontThrow = number++;
Console.WriteLine(this will be reached);
}

_Livro_Sharp_Visual.indb 147 30/06/14 15:04


148 PARTE I Introduo ao Microsoft Visual C# e ao Microsoft Visual Studio 2013

Escreva expresses verificadas


Voc tambm pode utilizar as palavras-chave checked e unchecked para controlar a
verificao de overflow em expresses de nmeros inteiros, precedendo apenas a ex-
presso entre parnteses com a palavra-chave checked ou unchecked, como mostrado
neste exemplo:
int wontThrow = unchecked(int.MaxValue + 1);
int willThrow = checked(int.MaxValue + 1);

Os operadores compostos (como += e =) e os operadores de incremento, ++, e


de decremento, --, so operadores aritmticos e podem ser controlados com as pala-
vras-chave checked e unchecked. Lembre-se de que, x += y; o mesmo que x = x + y;.

Importante Voc no pode usar as palavras-chave checked e unchecked para


controlar a aritmtica de ponto flutuante (no inteiro). As palavras-chave che-
cked e unchecked s se aplicam aritmtica de inteiros utilizando tipos de dados
como int e long. A aritmtica de ponto flutuante nunca lana uma OverflowEx-
ception nem mesmo quando voc divide por 0.0. (Lembre-se, do Captulo 2,
que o .NET Framework tem uma representao de ponto flutuante especial para
infinito.)

No prximo exerccio, voc ver como executar a aritmtica verificada ao utilizar


o Visual Studio 2013.

Utilize expresses verificadas


1. Retorne ao Visual Studio 2013.
2. No menu Debug, clique em Start Debugging.
Agora, voc tentar multiplicar dois valores grandes.
3. Digite 9876543 na caixa Left Operand, digite 9876543 na caixa Right Operand,
clique no boto * Multiplication e ento clique em Calculate.
O valor -1195595903 aparece na caixa Result do formulrio. Esse um valor
negativo, que no pode estar correto. Esse valor o resultado de uma operao
de multiplicao que silenciosamente excedeu o limite de 32 bits do tipo int.
4. Retorne ao Visual Studio e interrompa a depurao.
5. Na janela Code and Text Editor que exibe MainWindow.xaml.cs, localize o mto-
do multiplyValues, que deve ser como este:
private void multiplyValues()
{
int lhs = int.Parse(lhsOperand.Text);
int rhs = int.Parse(rhsOperand.Text);
int outcome = 0;

_Livro_Sharp_Visual.indb 148 30/06/14 15:04


CAPTULO 6 Gerenciamento de erros e excees 149

outcome = lhs * rhs;


expression.Text = lhsOperand.Text + * + rhsOperand.Text;
result.Text = outcome.ToString();;
}

A instruo outcome = lhs * rhs; contm a operao de multiplicao que causa


overflow silenciosamente.
6. Edite essa instruo para que o valor do clculo seja verificado, desta maneira:
outcome = checked(lhs * rhs);

A multiplicao agora verificada e lanar uma OverflowException, em vez de


retornar silenciosamente a resposta errada.
7. No menu Debug, clique em Start Debugging.
8. Digite 9876543 na caixa Left Operand, digite 9876543 na caixa Right Operand,
clique no boto * Multiplication e ento clique em Calculate.
O Visual Studio aciona o depurador e relata que a multiplicao resultou em
uma exceo OverflowException. Agora, voc precisa adicionar uma rotina de
tratamento para capturar essa exceo e tratar dela de forma mais elegante do
que apenas falhar com um erro.
9. No menu Debug, clique em Stop Debugging.
10. Na janela Code and Text Editor que exibe o arquivo MainWindow.xaml.cs, locali-
ze o mtodo calculateClick.
11. Adicione a rotina de tratamento catch a seguir (mostrada em negrito), imedia-
tamente aps a rotina de tratamento catch de FormatException existente nesse
mtodo:
private void calculateClick(object sender, RoutedEventArgs e)
{
try
{
...
}
catch (FormatException fEx)
{
result.Text = fEx.Message;
}
catch (OverflowException oEx)
{
result.Text = oEx.Message;
}
}

A lgica dessa rotina de tratamento catch a mesma da rotina de tratamento


catch de FormatException. Mas ainda vale a pena manter essas duas rotinas de
tratamento separadas, em vez de simplesmente escrever uma rotina de trata-
mento catch de Exception genrica, porque talvez voc queira tratar essas exce-
es de maneira diferente no futuro.

_Livro_Sharp_Visual.indb 149 30/06/14 15:04


150 PARTE I Introduo ao Microsoft Visual C# e ao Microsoft Visual Studio 2013

12. No menu Debug, clique em Start Debugging para compilar e executar o aplica-
tivo.
13. Digite 9876543 na caixa Left Operand, digite 9876543 na caixa Right Operand,
clique no boto * Multiplication e ento clique em Calculate.
A segunda rotina de tratamento catch captura com sucesso a OverflowException
e exibe a mensagem Arithmetic operation resulted in an overflow na caixa
Result.
14. Retorne ao Visual Studio e interrompa a depurao.

Tratamento de exceo e o Visual Studio Debugger


Por padro, o Visual Studio Debugger s interrompe um aplicativo que est sen-
do depurado e relata as excees no tratadas. s vezes, interessante depurar
as prprias rotinas de tratamento de exceo e, nesse caso, voc precisa seguir
as excees quando elas so lanadas pelo aplicativo, antes de serem capturadas.
Essa funcionalidade pode ser habilitada facilmente. No menu Debug, clique em
Exceptions. Na caixa de dilogo Exceptions, selecione a coluna Thrown de Com-
mon Language Runtime Exceptions e, em seguida, clique em OK:

Agora, quando ocorrerem excees, como OverflowException, o Visual Stu-


dio acionar o depurador e voc poder utilizar o boto Step da barra de ferra-
mentas Debug para percorrer passo a passo a rotina de tratamento catch. Se no
quiser capturar todas as excees Common Language Runtime (CLR) dessa ma-
neira, voc pode ser mais seletivo. Se expandir o n Common Language Runtime
Exceptions, poder ver as diferentes categorias de excees que podem ocorrer
(elas esto organizadas por namespace). Se expandir qualquer namespace, voc
poder ver as excees individuais disponveis e poder selecionar cada uma de-
las individualmente.

_Livro_Sharp_Visual.indb 150 30/06/14 15:04


CAPTULO 6 Gerenciamento de erros e excees 151

Lance excees
Suponha que voc esteja implementando um mtodo chamado monthName que
aceita um nico argumento int e retorna o nome do ms correspondente. Por exem-
plo, monthName(1) retorna January, monthName(2) retorna February e assim por
diante. A pergunta : o que o mtodo deve retornar se o argumento inteiro for menor
que 1 ou maior que 12? A melhor resposta que o mtodo no deve retornar coisa
alguma ele deve lanar uma exceo. As bibliotecas de classes do .NET Framework
contm uma grande quantidade de classes de exceo projetadas especificamente
para situaes desse tipo. Na maioria das vezes, voc achar que uma dessas classes
descreve sua condio excepcional. (Se no, voc pode criar sua prpria classe de ex-
ceo de modo fcil, mas antes disso precisa conhecer um pouco mais da linguagem
C#.) Nesse caso, a classe ArgumentOutOfRangeException existente no .NET Framework
serve perfeitamente. Voc pode lanar uma exceo utilizando a instruo throw,
como mostrado no exemplo a seguir:
public static string monthName(int month)
{
switch (month)
{
case 1 :
return January;
case 2 :
return February;
...
case 12 :
return December;
default :
throw new ArgumentOutOfRangeException(Bad month);
}
}

A instruo throw precisa de um objeto exceo para ser lanada. Esse objeto
contm os detalhes da exceo, incluindo qualquer mensagem de erro. Esse exemplo
utiliza uma expresso que cria um novo objeto ArgumentOutOfRangeException. O ob-
jeto inicializado com uma string que preenche sua propriedade Message utilizando
um construtor. Os construtores sero abordados detalhadamente no Captulo 7, Cria-
o e gerenciamento de classes e objetos.
Nos exerccios a seguir, voc modificar o projeto MathsOperators para lanar
uma exceo se o usurio tentar efetuar um clculo sem especificar um operador.

Nota Esse exerccio um pouco artificial, pois qualquer bom projeto de apli-
cativo forneceria um operador padro, mas o objetivo desse aplicativo ilustrar
esse ponto.

Lance uma exceo


1. Retorne ao Visual Studio 2013.
2. No menu Debug, clique em Start Debugging.

_Livro_Sharp_Visual.indb 151 30/06/14 15:04


152 PARTE I Introduo ao Microsoft Visual C# e ao Microsoft Visual Studio 2013

3. Digite 24 na caixa Left Operand, digite 36 na caixa Right Operand e ento clique
em Calculate.
Nada aparece nas caixas Expression e Result. O fato de voc no ter selecionado
uma opo de operador no fica claro imediatamente. Seria til escrever uma
mensagem de diagnstico na caixa Result.
4. Retorne ao Visual Studio e interrompa a depurao.
5. Na janela Code and Text Editor que exibe MainWindow.xaml.cs, localize e exami-
ne o mtodo calculateClick, que deve ser como este:
private int calculateClick(object sender, RoutedEventArgs e)
{
try
{
if ((bool)addition.IsChecked)
{
addValues();
}
else if ((bool)subtraction.IsChecked)
{
subtractValues();
}
else if ((bool)multiplication.IsChecked)
{
multiplyValues();
}
else if ((bool)division.IsChecked)
{
divideValues();
}
else if ((bool)remainder.IsChecked)
{
remainderValues();
}
}
catch (FormatException fEx)
{
result.Text = fEx.Message;
}
catch (OverflowException oEx)
{
result.Text = oEx.Message;
}
}

Os campos addition, subtraction, multiplication, division e remainder so os bo-


tes de opo que aparecem no formulrio. Cada boto tem uma propriedade
chamada IsChecked que indica se o usurio a selecionou. IsChecked uma pro-
priedade booleana nullable que tem o valor true se o boto estiver selecionado
ou false, caso contrrio (voc vai aprender mais sobre os valores nullable no
Captulo 8, Valores e referncias). A instruo if em cascata examina cada boto
para descobrir qual deles est selecionado. (Os botes de opo so mutua-
mente exclusivos; portanto, o usurio pode selecionar no mximo um boto de
opo.) Se no houver boto selecionado, no haver instrues if verdadeiras e
os mtodos de clculo no sero chamados.

_Livro_Sharp_Visual.indb 152 30/06/14 15:04


CAPTULO 6 Gerenciamento de erros e excees 153

Voc pode tentar resolver o problema adicionando mais uma instruo else
cascata if-else, para escrever uma mensagem na caixa de texto result do formul-
rio, mas uma soluo melhor separar a deteco e a sinalizao de um erro da
captura e do tratamento desse erro.
6. Adicione outra instruo else no final da lista de instrues if-else e lance uma
InvalidOperationException, como mostrado em negrito a seguir:
if ((bool)addition.IsChecked)
{
addValues();
}
...
else if ((bool)remainder.IsChecked)
{
remainderValues();
}
else
{
throw new InvalidOperationException(No operator selected);
}

7. No menu Debug, clique em Start Debugging para compilar e executar o aplicativo.


8. Digite 24 na caixa Left Operand, digite 36 na caixa Right Operand e ento clique
em Calculate.
O Visual Studio detecta que seu aplicativo lanou uma exceo InvalidOperation
e uma caixa de dilogo de exceo aberta. Seu aplicativo lanou uma exceo,
mas o cdigo no a captura ainda.
9. No menu Debug, clique em Stop Debugging.
Agora que escreveu uma instruo throw e verificou que ela lana uma exceo,
voc escrever uma rotina de tratamento catch para capturar essa exceo.

Capture a exceo
1. Na janela Code and Text Editor que exibe o arquivo MainWindow.xaml.cs, adicione
a seguinte rotina de tratamento catch, mostrada em negrito, imediatamente abai-
xo das duas rotinas de tratamento catch existentes no mtodo calculateClick:
...
catch (FormatException fEx)
{
result.Text = fEx.Message;
}
catch (OverflowException oEx)
{
result.Text = oEx.Message;
}
catch (InvalidOperationException ioEx)
{
result.Text = ioEx.Message;
}

Esse cdigo captura a InvalidOperationException que lanada quando no h


boto de operador selecionado.

_Livro_Sharp_Visual.indb 153 30/06/14 15:04


154 PARTE I Introduo ao Microsoft Visual C# e ao Microsoft Visual Studio 2013

2. No menu Debug, clique em Start Debugging.


3. Digite 24 na caixa Left Operand, digite 36 na caixa Right Operand e ento clique
em Calculate.
A mensagem no operator selected aparece na caixa Result.

Nota Se o Visual Studio Debugger for acionado, voc provavelmente


habilitou o Visual Studio para capturar excees ao serem lanadas, con-
forme descrito anteriormente. Se isso acontecer, no menu Debug, clique
em Continue. Quando terminar este exerccio, lembre-se de desabilitar no
Visual Studio a captura de excees CLR quando so lanadas!

4. Retorne ao Visual Studio e interrompa a depurao.


Agora o aplicativo est muito mais robusto. Mas ainda podem surgir vrias exce-
es que no so capturadas e faro o aplicativo falhar. Por exemplo, se voc tentar di-
vidir por 0, uma DivideByZeroException no tratada ser lanada. (Diviso de inteiro por
0 lana uma exceo, diferentemente da diviso de ponto flutuante por 0.) Uma ma-
neira de resolver esse problema escrever um nmero ainda maior de rotinas de tra-
tamento catch dentro do mtodo calculateClick. Outra soluo adicionar no final da
lista de rotinas de tratamento catch uma rotina de tratamento catch geral que capture
Exception. Isso capturar todas as excees inesperadas que possam ter sido esquecidas
ou que possam ocorrer como resultado de circunstncias realmente incomuns.

Nota O uso de uma rotina de tratamento genrica para capturar a exceo Ex-
ception no justificativa para omitir a captura de excees especficas. Quanto
mais preciso voc possa ser no tratamento de excees, mais fcil ser manter
seu cdigo e identificar as causas de qualquer problema obscuro ou recorrente.
S utilize a exceo Exception em casos realmente... bem, excepcionais. Para os
propsitos do prximo exerccio, a exceo dividir por zero cai nessa categoria.
Contudo, tendo-se estabelecido que essa exceo uma possibilidade diferen-
ciada em um aplicativo profissional, uma boa prtica seria adicionar uma rotina
de tratamento para a exceo DivideByZeroException ao aplicativo.

Capture excees no tratadas


1. Na janela Code and Text Editor que exibe o arquivo MainWindow.xaml.cs, adi-
cione a seguinte rotina de tratamento catch no final da lista de rotinas de trata-
mento catch existentes no mtodo calculateClick:
catch (Exception ex)
{
result.Text = ex.Message;
}

Essa rotina de tratamento catch capturar todas as excees no tratadas at


aqui, qualquer que seja seu tipo especfico.

_Livro_Sharp_Visual.indb 154 30/06/14 15:04


CAPTULO 6 Gerenciamento de erros e excees 155

2. No menu Debug, clique em Start Debugging.


Agora voc vai tentar efetuar alguns clculos conhecidos por provocar excees
e confirmar se elas so tratadas corretamente.
3. Digite 24 na caixa Left Operand, digite 36 na caixa Right Operand e ento clique
em Calculate.
Confirme que a mensagem de diagnstico no operator selected ainda exibi-
da na caixa Result. Essa mensagem foi gerada pela rotina de tratamento Invali-
dOperationException.
4. Digite John na caixa de texto Left Operand, clique no boto + Addition e depois
clique em Calculate.
Confirme que a mensagem de diagnstico Input string was not in a correct
format exibida na caixa Result. Essa mensagem foi gerada pela rotina de tra-
tamento FormatException.
5. Digite 24 na caixa Left Operand, digite 0 na caixa Right Operand, clique no bo-
to / Division e ento clique em Calculate.
Confirme que a mensagem de diagnstico Attempted to divide by zero exi-
bida na caixa Result. Essa mensagem foi gerada pela rotina de tratamento Ex-
ception geral.
6. Experimente outras combinaes de valores e verifique que as condies de ex-
ceo so tratadas sem fazer o aplicativo falhar. Quando tiver terminado, retorne
ao Visual Studio e interrompa a depurao.

Bloco finally
importante lembrar que, quando uma exceo lanada, ela altera o fluxo da execuo
no programa. Isso significa que voc no pode garantir que uma instruo ser sempre
executada quando a instruo anterior terminar, porque a instruo anterior poder lan-
ar uma exceo. Lembre-se de que, nesse caso, aps a execuo da rotina de tratamento
catch, o fluxo de controle retomado na prxima instruo do bloco que contm essa
rotina e no na instruo imediatamente aps o cdigo que lanou a exceo.
Observe o exemplo a seguir, adaptado do cdigo do Captulo 5, Atribuio
composta e instrues de iterao. muito fcil supor que a chamada a reader.Dispo-
se sempre ocorrer quando o loop while terminar (se estiver usando o Windows 7 ou o
Windows 8, substitua reader.Dispose por reader.Close nesse exemplo). Afinal de contas,
o que est no cdigo.
TextReader reader = ...;
...
string line = reader.ReadLine();
while (line != null)
{
...
line = reader.ReadLine();
}
reader.Dispose();

_Livro_Sharp_Visual.indb 155 30/06/14 15:04


156 PARTE I Introduo ao Microsoft Visual C# e ao Microsoft Visual Studio 2013

Algumas vezes, o fato de uma instruo especfica no ser executada no pro-


blema, mas em muitas ocasies isso pode ser um grande problema. Se a instruo
libera um recurso que foi adquirido em uma instruo anterior, ento a falha na exe-
cuo dessa instruo resultar na reteno do recurso. Este exemplo precisamente o
caso: quando um arquivo aberto para leitura, essa operao adquire um recurso (um
handle de arquivo) e voc deve garantir a chamada de reader.Dispose para liberar o re-
curso (reader.Close chama reader.Dispose para fazer isso no Windows 7 e no Windows
8). Se voc no fizer isso, cedo ou tarde no ter handles de arquivos suficientes e ser
incapaz de abrir mais arquivos. Se achar handles de arquivos muito triviais, pense, em
vez disso, nas conexes de banco de dados.
A maneira de garantir que uma instruo seja sempre executada, quer uma ex-
ceo seja lanada ou no, escrever essa instruo em um bloco finally. Um bloco
finally ocorre imediatamente aps um bloco try ou imediatamente aps a ltima ro-
tina de tratamento catch, depois de um bloco try. Desde que o programa entre no
bloco try associado a um bloco finally, o bloco finally sempre ser executado, mesmo
que uma exceo ocorra. Se uma exceo for lanada e capturada localmente, a rotina
de tratamento de exceo ser executada primeiro, seguida pelo bloco finally. Se a
exceo no for capturada localmente (ou seja, o runtime precisar pesquisar a lista de
mtodos chamadores para descobrir uma rotina de tratamento), o bloco finally ser
executado primeiro. Em qualquer caso, o bloco finally sempre executado.
A soluo para o problema da instruo reader.Close a seguinte:
TextReader reader = ...;
...
try
{
string line = reader.ReadLine();
while (line != null)
{
...
line = reader.ReadLine();
}
}
finally
{
if (reader != null)
{
reader.Dispose();
}
}

Mesmo que ocorra uma exceo durante a leitura do arquivo, o bloco finally ga-
rante que a instruo reader.Dispose sempre seja executada. Voc ver outra maneira
de tratar dessa situao no Captulo 14, Coleta de lixo e gerenciamento de recursos.

Resumo
Neste captulo, voc aprendeu a capturar e tratar excees por meio das construes
try e catch. Voc viu como possvel ativar e desativar a verificao de overflow de
nmeros inteiros por meio das palavras-chave checked e unchecked. Aprendeu a lan-
ar uma exceo se seu cdigo detectar uma situao excepcional e examinou como

_Livro_Sharp_Visual.indb 156 30/06/14 15:04


CAPTULO 6 Gerenciamento de erros e excees 157

utilizar um bloco finally para garantir que o cdigo crucial seja executado, mesmo se
ocorrer uma exceo.
j Se quiser continuar no prximo captulo, mantenha o Visual Studio 2013 execu-
tando e v para o Captulo 7.
j Se quiser encerrar o Visual Studio 2013 agora, no menu File, clique em Exit. Se vir
uma caixa de dilogo Save, clique em Yes e salve o projeto.

Referncia rpida

Para Faa isto


Capturar uma exceo especfica Escreva uma rotina e tratamento catch que capture
a classe de exceo especfica. Por exemplo:
try
{
...
}
catch (FormatException fEx)
{
...
}

Garantir que a aritmtica de inteiros seja Use a palavra-chave checked. Por exemplo:
sempre verificada quanto a overflow
int number = Int32.MaxValue;
checked
{
number++;
}

Lanar uma exceo Utilize uma instruo throw. Por exemplo:


throw new FormatException(source);

Capturar todas as excees em uma Escreva uma rotina de tratamento catch que
nica rotina de tratamento catch capture Exception. Por exemplo:
try
{
...
}
catch (Exception ex)
{
...
}

Garantir que algum cdigo sempre seja Escreva o cdigo dentro de um bloco finally. Por
executado, mesmo se uma exceo for exemplo:
lanada
try
{
...
}
finally
{
// sempre executa
}

_Livro_Sharp_Visual.indb 157 30/06/14 15:04


Esta pgina foi deixada em branco intencionalmente.

_Livro_Sharp_Visual.indb 158 30/06/14 15:04


PARTE II

O modelo de objetos
do C#
CAPTULO 7 Criao e gerenciamento de classes e objetos . . . . . . . . . . . . . . . . . 161

CAPTULO 8 Valores e referncias . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 183

CAPTULO 9 Como criar tipos-valor com enumeraes e estruturas . . . . . . . . . . 206

CAPTULO 10 Arrays . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 226

CAPTULO 11 Arrays de parmetros . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 249

CAPTULO 12 Herana . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 261

CAPTULO 13 Como criar interfaces e definir classes abstratas . . . . . . . . . . . . . . . . 284

CAPTULO 14 Coleta de lixo e gerenciamento de recursos . . . . . . . . . . . . . . . . . . . 313

_Livro_Sharp_Visual.indb 159 30/06/14 15:05


Esta pgina foi deixada em branco intencionalmente.

_Livro_Sharp_Visual.indb 160 30/06/14 15:05


CAPTULO 7

Criao e gerenciamento
de classes e objetos
Neste captulo, voc vai aprender a:
j Definir uma classe contendo um conjunto de mtodos e itens de dados
relacionados.
j Controlar a acessibilidade de membros utilizando as palavras-chave public e private.
j Criar objetos utilizando a palavra-chave new para chamar um construtor.
j Escrever e chamar seus prprios construtores.
j Criar mtodos e dados que podem ser compartilhados por todas as instncias da
mesma classe utilizando a palavra-chave static.
j Explicar como criar classes annimas.
O Microsoft Windows Runtime do Windows 8 e Windows 8.1, junto com o Microsoft
.NET Framework disponvel no Windows 7, no Windows 8 e no Windows 8.1, contm
muitas classes, e voc j utilizou muitas delas, inclusive Console e Exception. As classes
apresentam um mecanismo conveniente para modelar as entidades manipuladas pe-
los aplicativos. Uma entidade pode representar um item especfico, como um cliente,
ou algo mais abstrato, como uma transao. Parte do processo do projeto de qual-
quer sistema est concentrada na determinao das entidades importantes para os
processos implementados pelo sistema e na execuo de uma anlise para ver quais
informaes essas entidades necessitam armazenar e quais operaes devem executar.
Voc armazena as informaes de uma classe como campos e usa mtodos para a
implementao das operaes que uma classe pode realizar.

Classificao
Classe a raiz da palavra classificao. Ao projetar uma classe, voc sistematicamente
organiza as informaes e o comportamento em uma entidade com significado. Essa
organizao um ato de classificao e algo que todos fazem no apenas os pro-
gramadores. Por exemplo, todos os carros compartilham comportamentos comuns
(eles podem ser dirigidos, parados, acelerados, etc.) e atributos comuns (eles tm um
volante, um motor, etc.). As pessoas utilizam a palavra carro para significar um objeto
que compartilha esses comportamentos e atributos comuns. Desde que todos concor-
dem com o que a palavra significa, esse sistema funcionar bem e voc pode expressar
ideias complexas, mas precisas, de maneira concisa. Sem a classificao, difcil imagi-
nar como as pessoas poderiam pensar ou se comunicar.

_Livro_Sharp_Visual.indb 161 30/06/14 15:05


162 PARTE II O modelo de objetos do C#

Como a classificao est profundamente arraigada na maneira como pensamos


e nos comunicamos, faz sentido tentar escrever programas classificando os diferentes
conceitos inerentes a um problema e sua soluo e ento modelar essas classes em
uma linguagem de programao. Isso exatamente o que voc pode fazer com lin-
guagens modernas de programao orientada a objetos, como o Microsoft Visual C#.

O objetivo do encapsulamento
O encapsulamento um princpio importante durante a definio de classes. A ideia
que um programa que utiliza uma classe no precisa se preocupar com o modo
como essa classe realmente funciona internamente; o programa simplesmente cria
uma instncia de uma classe e chama os mtodos dessa classe. Desde que esses m-
todos faam o que se propem a fazer, o programa no se preocupa com a maneira
como eles so implementados. Por exemplo, ao chamar o mtodo Console.WriteLine,
voc no quer se incomodar com todos os detalhes complicados de como a classe
Console organiza fisicamente os dados a serem escritos na tela. Uma classe talvez pre-
cise manter todos os tipos de informaes internas para executar seus vrios mtodos.
Essas atividades e informaes de estado adicionais so ocultas do programa que est
utilizando a classe. Portanto, o encapsulamento , s vezes, chamado de ocultamento
de informao. O encapsulamento na realidade tem dois objetivos:
j Combinar os mtodos e dados dentro de uma classe; ou seja, dar suporte
classificao.
j Controlar a acessibilidade de mtodos e dados; ou seja, controlar o uso da classe.

Defina e utilize uma classe


No C#, voc utiliza a palavra-chave class para definir uma nova classe. Os dados e os
mtodos da classe ocorrem no corpo da classe entre um par de chaves. A seguir est
uma classe do C# chamada Circle que contm um mtodo (para calcular a rea do
crculo) e uma parte de dados (o raio do crculo):
class Circle
{
int radius;

double Area()
{
return Math.PI * radius * radius;
}
}

Nota A classe Math contm mtodos para efetuar clculos matemticos e


campos contendo constantes matemticas. O campo Math.PI contm o valor
3.14159265358979323846, que uma aproximao do valor de pi.

_Livro_Sharp_Visual.indb 162 30/06/14 15:05


CAPTULO 7 Criao e gerenciamento de classes e objetos 163

O corpo de uma classe contm mtodos comuns (como Area) e campos (como
radius). Lembre-se de que as variveis em uma classe so chamadas de campos. O
Captulo 2, Variveis, operadores e expresses, mostrou como declarar variveis e
o Captulo 3, Como escrever mtodos e aplicar escopo, demonstrou como escrever
mtodos, de modo que quase no h sintaxe nova aqui.
Voc pode utilizar a classe Circle de modo semelhante a como usa outros tipos
j encontrados. Voc cria uma varivel especificando Circle como seu tipo e inicializa a
varivel com algum dado vlido. Veja um exemplo:
Circle c; // Cria uma varivel Circle
c = new Circle(); // Inicializa a varivel

Um aspecto que merece destaque nesse cdigo o uso da palavra-chave new.


Antes, ao inicializar uma varivel como int ou float, voc simplesmente atribuiu um
valor a ela:
int i;
i = 42;

Voc no pode fazer o mesmo com variveis do tipo classe. Uma razo que o
C# no fornece uma sintaxe para atribuir valores literais de classe s variveis. Voc
no pode escrever uma instruo como esta:
Circle c;
c = 42;

Afinal, o que significaria um Circle igual a 42? Outra razo diz respeito maneira
como a memria para variveis do tipo classe alocada e gerenciada pelo runtime
isso ser discutido com mais detalhes no Captulo 8, Valores e referncias. Por en-
quanto, basta aceitar que a palavra-chave new cria uma nova instncia de uma classe,
normalmente chamada de objeto.
Mas voc pode atribuir diretamente uma instncia de uma classe a outra varivel
do mesmo tipo, assim:
Circle c;
c = new Circle();
Circle d;
d = c;

Mas isso no to simples e direto quanto parece ser primeira vista, por razes
que abordaremos no Captulo 8.

Importante No confunda os termos classe e objeto. Uma classe a definio


de um tipo. Um objeto uma instncia desse tipo, criada quando o programa
executado. Vrios objetos podem ser instncias da mesma classe.

_Livro_Sharp_Visual.indb 163 30/06/14 15:05


164 PARTE II O modelo de objetos do C#

Controle a acessibilidade
Surpreendentemente, a classe Circle no tem, hoje, qualquer utilidade prtica. Por
padro, quando voc encapsula seus mtodos e dados dentro de uma classe, a clas-
se forma um limite para o mundo externo. Campos (como radius) e mtodos (como
Area) definidos na classe podem ser vistos por outros mtodos dentro da classe, mas
no pelo mundo externo eles so privados para a classe. Assim, embora seja possvel
criar um objeto Circle em um programa, no possvel acessar seu campo radius ou
chamar seu mtodo Area, razo pela qual a classe no muito til ainda! Mas voc
pode modificar a definio de um campo ou mtodo com as palavras-chave public e
private para controlar se ele pode ou no ser acessado de fora:
j Dizemos que um mtodo ou campo privado se ele acessvel somente a partir
de dentro da classe. Para declarar que um mtodo ou campo privado, voc
escreve a palavra-chave private antes da sua declarao. Conforme anunciado
antes, esse de fato o padro, mas uma boa prtica determinar explicitamente
que campos e mtodos so privados para evitar qualquer confuso.
j Dizemos que um mtodo ou campo pblico se ele acessvel tanto de dentro
quanto de fora da classe. Para declarar que um mtodo ou campo pblico,
voc escreve a palavra-chave public antes da sua declarao.
Veja a classe Circle novamente. Desta vez, Area declarada como um mtodo
pblico e radius declarado como um campo privado:
class Circle
{
private int radius;

public double Area()


{
return Math.PI * radius * radius;
}
}

Nota Se voc programador de C++, note que no h um sinal de dois-


-pontos aps as palavras-chave public ou private. Voc precisa repetir a palavra-
-chave para cada declarao de campo e mtodo.

Embora radius seja declarado como um campo privado e no esteja acessvel


fora da classe, radius estar acessvel a partir de dentro da classe Circle. O mtodo Area
est dentro da classe Circle; portanto, o corpo de Area tem acesso a radius. Entretanto,
a classe ainda de valor limitado, pois no h como inicializar o campo radius. Para
corrigir isso, voc utiliza um construtor.

Dica De modo diferente das variveis declaradas em um mtodo, os campos


em uma classe so automaticamente inicializados como 0, false ou null, depen-
dendo do seu tipo. Mas ainda uma boa prtica fornecer uma maneira explcita
de inicializar os campos.

_Livro_Sharp_Visual.indb 164 30/06/14 15:05


CAPTULO 7 Criao e gerenciamento de classes e objetos 165

Conveno de nomes e acessibilidade


Muitas organizaes tm seu prprio estilo, que solicitam aos desenvolvedores
seguir, ao escreverem cdigo. Parte desse estilo muitas vezes envolve regras para
dar nomes a identificadores, e o objetivo dessas regras em geral ajudar na ma-
nuteno do cdigo. As recomendaes a seguir so razoavelmente comuns e
relacionam-se s convenes de nomes para campos e mtodos com base na
acessibilidade dos membros da classe; contudo, o C# no impe essas regras:
j Os identificadores que so public devem iniciar com uma letra maiscula.
Por exemplo, Area comea com A (no com a) porque public. Esse sistema
conhecido como esquema de nomes PascalCase (porque foi utilizado pri-
meiramente na linguagem Pascal).
j Os identificadores que no so public (que incluem as variveis locais) de-
vem comear com uma letra minscula. Por exemplo, radius comea com
r (no com R) porque private. Esse sistema conhecido como camelo
(camelCase).

Nota Algumas organizaes utilizam o sistema camelo somente


para mtodos e adotam a conveno de que os nomes dos campos
privados comeam com um caractere de sublinhado, como _radius.
Contudo, os exemplos deste livro utilizam o sistema camelo para m-
todos e campos privados.

S h uma exceo a essa regra: os nomes de classes devem iniciar com uma
letra maiscula e os construtores devem corresponder exatamente ao nome de
suas classes; portanto, um construtor private deve iniciar com uma letra maiscula.

Importante No declare dois membros de classe public cujos no-


mes diferem apenas pelo uso de maisculas e minsculas. Se fizer
isso, os desenvolvedores que utilizam outras linguagens que no fa-
zem distino entre letras maisculas e minsculas (como o Microsoft
Visual Basic) talvez no possam utilizar sua classe na soluo deles.

Trabalhe com construtores


Quando voc utiliza a palavra-chave new para criar um objeto, o runtime precisa cons-
truir esse objeto utilizando a definio da classe. O runtime precisa se apropriar de uma
parte da memria do sistema operacional, preench-la com os campos definidos pela
classe e, ento, chamar o construtor para executar qualquer inicializao necessria.

_Livro_Sharp_Visual.indb 165 30/06/14 15:05


166 PARTE II O modelo de objetos do C#

Um construtor um mtodo especial executado automaticamente quando voc


cria uma instncia de uma classe. Ele tem o mesmo nome da classe e pode receber
parmetros, mas no pode retornar um valor (nem mesmo void). Toda classe deve ter
um construtor. Se voc no escrever um, o compilador ir gerar automaticamente um
construtor padro para voc. (Mas o construtor padro gerado pelo compilador na
realidade no faz coisa alguma.) Voc pode escrever seu prprio construtor padro
facilmente. Basta adicionar um mtodo pblico que no retorna um valor e dar a ele o
mesmo nome da classe. O exemplo a seguir mostra a classe Circle com um construtor
padro que inicializa o campo radius como 0:
class Circle
{
private int radius;

public Circle() // construtor padro


{
radius = 0;
}

public double Area()


{
return Math.PI * radius * radius;
}
}

Nota No jargo do C#, o construtor padro um construtor que no recebe


parmetros. No importa se gerado pelo compilador ou escrito por voc; ain-
da assim ele o construtor padro. Voc tambm pode escrever construtores
no padro (construtores que recebem parmetros), como veremos na prxima
seo, Sobrecarregue construtores.

Nesse exemplo, o construtor est marcado como public. Se essa palavra-chave


for omitida, o construtor ser privado (exatamente como qualquer outro mtodo e
campo). Se o construtor for privado, ele no poder ser utilizado fora da classe, o que
lhe impede de criar objetos Circle a partir dos mtodos que no fazem parte da classe
Circle. Assim, voc pode achar que os construtores privados no so to valiosos. Eles
realmente tm suas utilidades, mas estas esto fora do objetivo da discusso atual.
Tendo adicionado um construtor pblico, voc agora pode utilizar a classe Circle
e empregar seu mtodo Area. Observe como voc utiliza a notao de ponto para
chamar o mtodo Area em um objeto Circle:
Circle c;
c = new Circle();
double areaOfCircle = c.Area();

_Livro_Sharp_Visual.indb 166 30/06/14 15:05


CAPTULO 7 Criao e gerenciamento de classes e objetos 167

Sobrecarregue construtores
Voc quase j terminou, s falta um detalhe. Agora voc pode declarar uma varivel
Circle, utiliz-la para referenciar um objeto Circle recm-criado e ento chamar seu
mtodo Area. Mas h um ltimo problema. A rea de todos os objetos Circle sempre
ser 0, porque o construtor padro define o raio como 0 e ele permanece em 0; o
campo radius privado e no h como alterar seu valor depois que ele inicializado.
Um construtor apenas um tipo especial de mtodo e como todos os mtodos
pode ser sobrecarregado. Assim como existem vrias verses do mtodo Console.
WriteLine e cada uma recebe parmetros diferentes, tambm possvel escrever dife-
rentes verses de um construtor. Assim, voc pode adicionar outro construtor classe
Circle, com um parmetro especificando o raio a ser usado, como este:
class Circle
{
private int radius;

public Circle() // construtor padro


{
radius = 0;
}

public Circle(int initialRadius) // construtor sobrecarregado


{
radius = initialRadius;
}

public double Area()


{
return Math.PI * radius * radius;
}
}

Nota A ordem dos construtores em uma classe irrelevante; voc pode definir
construtores na ordem que achar melhor.

Voc pode ento utilizar esse construtor ao criar um novo objeto Circle, como
a seguir:
Circle c;
c = new Circle(45);

Quando voc compila o aplicativo, o compilador deduz qual construtor deve


chamar com base nos parmetros especificados para o operador new. Neste exemplo,
voc passou um int; portanto, o compilador gera o cdigo que chama o construtor
que recebe um parmetro int.
Fique atento a um importante recurso da linguagem C#: se voc escrever seu
prprio construtor para uma classe, o compilador no gerar um construtor padro.
Portanto, se voc escreveu um construtor que aceita um ou mais parmetros e tam-
bm quiser um construtor padro, voc mesmo ter de escrever o construtor padro.

_Livro_Sharp_Visual.indb 167 30/06/14 15:05


168 PARTE II O modelo de objetos do C#

Classes parciais
Uma classe pode conter vrios mtodos, campos e construtores, assim como
outros itens discutidos nos prximos captulos. Uma classe altamente funcional
pode tornar-se muito grande. Com o C#, possvel dividir o cdigo-fonte para
uma classe em arquivos separados de modo que voc possa organizar a definio
de uma classe grande em partes menores, mais fceis de gerenciar. Esse recurso
usado pelo Microsoft Visual Studio 2013 para aplicativos Windows Presentation
Foundation (WPF) e aplicativos Windows Store, em que o cdigo-fonte que o
desenvolvedor pode editar mantido em um arquivo separado do cdigo que
gerado pelo Visual Studio sempre que o layout de um formulrio for alterado.
Ao dividir uma classe em vrios arquivos, voc define as partes da classe
usando a palavra-chave partial em cada arquivo. Por exemplo, se a classe Circle
fosse dividida entre dois arquivos chamados circ1.cs (contendo os construtores) e
circ2.cs (contendo os mtodos e campos), o contedo de circ1.cs seria este:
partial class Circle
{
public Circle() // construtor padro
{
this.radius = 0;
}

public Circle(int initialRadius) // construtor sobrecarregado


{
this.radius = initialRadius;
}
}

O contedo de circ2.cs seria semelhante a este:


partial class Circle
{
private int radius;

public double Area()


{
return Math.PI * this.radius * this.radius;
}
}

Ao compilar uma classe que foi dividida em arquivos separados, voc deve
fornecer todos os arquivos para o compilador.

No prximo exerccio, voc vai declarar uma classe que modela um ponto no
espao bidimensional. Essa classe conter dois campos privados para as coordenadas x
e y de um ponto e fornecer os construtores para inicializar esses campos. Voc criar
instncias da classe usando a palavra-chave new e chamando os construtores.

_Livro_Sharp_Visual.indb 168 30/06/14 15:05


CAPTULO 7 Criao e gerenciamento de classes e objetos 169

Escreva os construtores e crie os objetos


1. Inicie o Visual Studio 2013, se ele ainda no estiver em execuo.
2. Abra o projeto Classes, localizado na pasta \Microsoft Press\Visual CSharp Step
By Step\Chapter 7\Windows X\Classes na sua pasta Documentos.
3. No Solution Explorer, clique duas vezes no arquivo Program.cs para exibi-lo na
janela Code and Text Editor.
4. Na classe Program, localize o mtodo Main.
O mtodo Main chama o mtodo doWork, inserido dentro de um bloco try e se-
guido por uma rotina de tratamento catch. Com esse bloco try/catch, voc pode
escrever no mtodo doWork o cdigo que em geral entraria em Main, tendo a
certeza de que ele ir capturar e tratar qualquer exceo. Atualmente, o mtodo
doWork no contm nada, a no ser um comentrio // TODO:.

Dica Os comentrios TODO so frequentemente utilizados pelos desenvolve-


dores como um lembrete de que h um trecho de cdigo a ser revisto, muitas
vezes contendo a descrio do trabalho a ser feito, como // TODO: implementar
o mtodo doWork. O Visual Studio reconhece essa forma de comentrio, e eles
podem ser localizados rapidamente em qualquer lugar de um aplicativo, com
a janela Task List. Para exibir essa janela, no menu View, clique em Task List. Por
padro, a janela Task List aberta abaixo da janela Code and Text Editor. Na
caixa de lista suspensa, na parte superior dessa janela, selecione Comments. To-
dos os comentrios TODO sero listados. Voc pode ento clicar duas vezes em
qualquer um desses comentrios para ir diretamente ao cdigo correspondente,
o qual ser exibido na janela Code and Text Editor.

_Livro_Sharp_Visual.indb 169 30/06/14 15:05


170 PARTE II O modelo de objetos do C#

5. Exiba o arquivo Point.cs na janela Code and Text Editor.


Esse arquivo define uma classe chamada Point, a qual voc utilizar para repre-
sentar a localizao de um ponto no espao bidimensional, definido por um par
de coordenadas x e y. No momento, a no ser por outro comentrio // TODO, a
classe Point est vazia.
6. Retorne ao arquivo Program.cs. Na classe Program, edite o corpo do mtodo
doWork e substitua o comentrio // TODO pela instruo a seguir:
Point origin = new Point();

Essa instruo cria uma nova instncia da classe Point e chama seu construtor
padro.
7. No menu Build, clique em Build Solution.
O cdigo compilado sem erro porque o compilador gera o cdigo para um
construtor padro para a classe Point. Mas voc no pode ver o cdigo C# desse
construtor porque o compilador no gera qualquer instruo na linguagem fonte.
8. Retorne classe Point no arquivo Point.cs. Substitua o comentrio // TODO por
um construtor public que aceita dois argumentos int chamados x e y e que cha-
mam o mtodo Console.WriteLine para exibir os valores desses argumentos no
console, como mostrado no texto em negrito no exemplo de cdigo a seguir:
class Point
{
public Point(int x, int y)
{
Console.WriteLine("x:{0}, y:{1}", x, y);
}
}

Nota Lembre-se de que o mtodo Console.WriteLine usa {0} e {1} como espa-
os reservados. Na instruo mostrada, {0} ser substitudo pelo valor de x e {1}
ser substitudo pelo valor de y, quando o programa for executado.

9. No menu Build, clique em Build Solution.


O compilador agora informa um erro:
'Classes.Point' does not contain a constructor that takes 0 arguments

A chamada ao construtor padro no mtodo doWork agora invlida, porque


no h mais um construtor padro. Voc escreveu seu prprio construtor para a
classe Point; portanto, o compilador no gerar o construtor padro. Agora voc
corrigir isso escrevendo seu prprio construtor padro.

_Livro_Sharp_Visual.indb 170 30/06/14 15:05


CAPTULO 7 Criao e gerenciamento de classes e objetos 171

10. Edite a classe Point, adicionando um construtor padro public que chama Conso-
le.WriteLine para escrever a string Default constructor called no console, como
mostrado em negrito no exemplo a seguir. Agora a classe Point deve ser seme-
lhante a isto:
class Point
{
public Point()
{
Console.WriteLine("Default constructor called");
}

public Point(int x, int y)


{
Console.WriteLine("x:{0}, y:{1}", x, y);
}
}

11. No menu Build, clique em Build Solution.


O programa agora deve ser compilado com sucesso.
12. No arquivo Program.cs, edite o corpo do mtodo doWork. Declare uma varivel
chamada bottomRight do tipo Point e inicialize-a como um novo objeto Point
utilizando o construtor com dois argumentos, como mostrado em negrito no
cdigo a seguir. Fornea os valores 1366 e 768, que representam as coordenadas
do canto inferior direito da tela com base na resoluo 1366 768 (uma reso-
luo comum de muitos dispositivos tablet para Windows 8 e Windows 8.1). O
mtodo doWork deve agora ser semelhante a este:
static void doWork()
{
Point origin = new Point();
Point bottomRight = new Point(1366, 768);
}

13. No menu Debug, clique em Start Without Debugging.


O programa compila e executa, escrevendo as seguintes mensagens no console:

14. Pressione a tecla Enter para finalizar o programa e retornar ao Visual Studio
2013.
Agora voc adicionar dois campos int classe Point para representar as coor-
denadas x e y de um ponto e modificar os construtores para inicializar esses
campos.

_Livro_Sharp_Visual.indb 171 30/06/14 15:05


172 PARTE II O modelo de objetos do C#

15. Edite a classe Point no arquivo Point.cs, adicionando dois campos private cha-
mados x e y, do tipo int, como mostrado em negrito no cdigo a seguir. Agora a
classe Point deve ser semelhante a isto:
class Point
{
private int x, y;

public Point()
{
Console.WriteLine("default constructor called");
}

public Point(int x, int y)


{
Console.WriteLine("x:{0}, y:{1}", x, y);
}
}

Voc editar o segundo construtor Point para inicializar os campos x e y com os


valores dos parmetros x e y. H uma armadilha potencial quando se faz isso. Se
voc no tiver cuidado, o construtor ficar igual a este:
public Point(int x, int y) // No digite isso!
{
x = x;
y = y;
}

Embora o cdigo seja compilado, essas instrues parecem ambguas. Como o


compilador sabe que na instruo x = x; o primeiro x o campo e o segundo x
o parmetro? A resposta que ele no sabe! Um parmetro de mtodo com
o mesmo nome do campo oculta o campo para todas as instrues no mtodo.
Tudo o que esse cdigo realmente faz atribuir os parmetros a eles mesmos;
ele no modifica os campos. Isso exatamente o que no queremos.
A soluo utilizar a palavra-chave this para qualificar quais variveis so par-
metros e quais so campos. Colocar o prefixo this na varivel significa o campo
neste objeto.
16. Modifique o construtor Point que recebe dois parmetros, substituindo a instru-
o Console.WriteLine pelo seguinte cdigo mostrado em negrito:
public Point(int x, int y)
{
this.x = x;
this.y = y;
}

17. Edite o construtor Point padro para inicializar os campos x e y com -1, como no
texto em negrito. Observe que, embora no haja parmetros para causar confu-
so, ainda uma boa prtica qualificar as referncias de campo com this:

_Livro_Sharp_Visual.indb 172 30/06/14 15:05


CAPTULO 7 Criao e gerenciamento de classes e objetos 173

public Point()
{
this.x = -1;
this.y = -1;
}

18. No menu Build, clique em Build Solution. Confirme se o cdigo compila sem
erros ou alertas. (Voc pode execut-lo, mas ele ainda no produz sada.)
Os mtodos que pertencem a uma classe e que operam em dados que perten-
cem a uma instncia especfica de uma classe so chamados mtodos de instncia.
(Voc vai aprender sobre outros tipos de mtodos mais adiante neste captulo.) No
exerccio a seguir, voc escrever um mtodo de instncia para a classe Point, chama-
do DistanceTo, o qual calcula a distncia entre dois pontos.

Escreva e chame mtodos de instncia


1. No projeto Classes no Visual Studio 2013, adicione classe Point o mtodo de
instncia pblico chamado DistanceTo a seguir, depois dos construtores. O m-
todo aceita um nico argumento Point chamado other e retorna um double.
O mtodo DistanceTo deve ser semelhante a este:
class Point
{
...
public double DistanceTo(Point other)
{
}
}

Nos prximos passos, voc adicionar cdigo ao corpo do mtodo de instncia


DistanceTo para calcular e retornar a distncia entre o objeto Point que est
sendo utilizado para fazer a chamada e o objeto Point passado como parme-
tro. Para fazer isso, voc deve calcular a diferena entre as coordenadas x e as
coordenadas y.
2. No mtodo DistanceTo, declare uma varivel local int chamada xDiff e inicialize-a
com a diferena entre this.x e other.x, como mostrado em negrito a seguir:
public double DistanceTo(Point other)
{
int xDiff = this.x - other.x;
}

3. Declare outra varivel int local chamada yDiff e inicialize-a com a diferena entre
this.y e other.y, como mostrado aqui no texto em negrito:
public double DistanceTo(Point other)
{
int xDiff = this.x - other.x;
int yDiff = this.y - other.y;
}

_Livro_Sharp_Visual.indb 173 30/06/14 15:05


174 PARTE II O modelo de objetos do C#

Nota Embora os campos x e y sejam privados, outras instncias da mesma


classe ainda podem acess-los. importante entender que o termo private ope-
ra no nvel da classe e no no nvel do objeto; dois objetos que so instncias da
mesma classe podem acessar dados privados uns dos outros, mas objetos que
so instncias de outra classe, no podem.

Para calcular a distncia, utilize o teorema de Pitgoras e calcule a raiz quadrada


da soma dos quadrados de xDiff e yDiff. A classe System.Math fornece o mtodo
Sqrt que voc pode utilizar para calcular razes quadradas.
4. Declare uma varivel chamada distance de tipo double e utilize-a para conter o
resultado do clculo que acabamos de descrever.
public double DistanceTo(Point other)
{
int xDiff = this.x - other.x;
int yDiff = this.y - other.y;
double distance = Math.Sqrt((xDiff * xDiff) + (yDiff * yDiff));
}

5. Adicione a instruo return ao final do mtodo DistanceTo e retorne o valor na


varivel distance:
public double DistanceTo(Point other)
{
int xDiff = this.x - other.x;
int yDiff = this.y - other.y;
double distance = Math.Sqrt((xDiff * xDiff) + (yDiff * yDiff));
return distance;
}

Agora voc testar o mtodo DistanceTo.


6. Retorne ao mtodo doWork na classe Program. Aps as instrues que decla-
ram e inicializam as variveis Point origin e bottomRight, declare uma varivel
chamada distance do tipo double. Inicialize essa varivel double com o resultado
obtido pela chamada ao mtodo DistanceTo no objeto origin, passando o objeto
bottomRight para ele como argumento.
O mtodo doWork deve agora ser semelhante a este:
static void doWork()
{
Point origin = new Point();
Point bottomRight = new Point(1366, 768);
double distance = origin.DistanceTo(bottomRight);
}

_Livro_Sharp_Visual.indb 174 30/06/14 15:05


CAPTULO 7 Criao e gerenciamento de classes e objetos 175

Nota O Microsoft IntelliSense deve exibir o mtodo DistanceTo quando voc


digitar o caractere de ponto aps origin.

7. Adicione ao mtodo doWork outra instruo que escreve o valor da varivel


distance no console utilizando o mtodo Console.WriteLine.
O mtodo doWork deve ser semelhante a este:
static void doWork()
{
Point origin = new Point();
Point bottomRight = new Point(1366, 768);
double distance = origin.DistanceTo(bottomRight);
Console.WriteLine("Distance is: {0}", distance);
}

8. No menu Debug, clique em Start Without Debugging.


9. Confirme que o valor 1568.45465347265 escrito na janela do console e, em
seguida, pressione Enter para fechar o aplicativo e voltar ao Visual Studio 2013.

Dados e mtodos static


No exerccio anterior, voc utilizou o mtodo Sqrt da classe Math. Da mesma forma,
ao examinar a classe Circle, voc leu o campo PI da classe Math. Se pensar sobre isso, a
maneira como voc chamou o mtodo Sqrt ou leu o campo PI foi um pouco estranha.
Voc chamou o mtodo e leu o campo na prpria classe, no em um objeto do tipo
Math. como tentar escrever Point.DistanceTo em vez de origin.DistanceTo no cdigo
que voc adicionou no exerccio anterior. Portanto, o que est acontecendo e como
isso funciona?
Voc notar com frequncia que nem todos os mtodos pertencem a uma ins-
tncia de uma classe; eles so mtodos utilitrios, pois fornecem uma funo til que
independente de qualquer instncia da classe especfica. O mtodo Sqrt serve apenas
como um exemplo. Se Sqrt fosse um mtodo de instncia de Math, voc teria de criar
um objeto Math para chamar Sqrt:
Math m = new Math();
double d = m.Sqrt(42.24);

Isso seria inconveniente. O objeto Math no participaria do clculo da raiz qua-


drada. Todos os dados de entrada que Sqrt necessita so fornecidos na lista de par-
metros e o resultado retornado para o chamador utilizando o valor de retorno do
mtodo. Os objetos no so realmente necessrios aqui; portanto, forar Sqrt em uma
instncia camisa de fora no uma boa ideia.

Nota Alm do mtodo Sqrt e do campo PI, a classe Math contm vrios outros
mtodos matemticos utilitrios, como Sin, Cos, Tan e Log.

_Livro_Sharp_Visual.indb 175 30/06/14 15:05


176 PARTE II O modelo de objetos do C#

Em C#, todos os mtodos devem ser declarados dentro de uma classe. Mas se
declarar um mtodo ou um campo como static, voc pode chamar o mtodo ou aces-
sar o campo utilizando o nome da classe. No h necessidade de instncia. Veja como
o mtodo Sqrt da classe Math declarado:
class Math
{
public static double Sqrt(double d)
{
...
}
...
}

Um mtodo esttico no depende de uma instncia da classe e no pode aces-


sar um campo ou mtodo de instncia definido na classe; ele s utiliza os campos e
outros mtodos marcados como static.

Crie um campo compartilhado


A definio de um campo como esttico torna possvel criar uma nica instncia de
um campo que compartilhada entre todos os objetos criados a partir de uma nica
classe. (Campos no estticos so locais para cada instncia de um objeto.) No exem-
plo a seguir, o campo static NumCircles na classe Circle incrementado pelo constru-
tor Circle toda vez que um novo objeto Circle criado:
class Circle
{
private int radius;
public static int NumCircles = 0;

public Circle() // default constructor


{
radius = 0;
NumCircles++;
}

public Circle(int initialRadius) // overloaded constructor


{
radius = initialRadius;
NumCircles++;
}
}

Todos os objetos Circle compartilham a mesma instncia do campo NumCir-


cles; portanto, a instruo NumCircles++; incrementa os mesmos dados toda vez que
uma nova instncia criada. Observe que voc no pode prefixar NumCircles com a
palavra-chave this, pois NumCircles no pertence a um objeto especfico.
Voc pode acessar o campo NumCircles fora da classe, especificando a classe
Circle, em vez de um objeto Circle, como no exemplo a seguir:
Console.WriteLine("Number of Circle objects: {0}", Circle.NumCircles);

_Livro_Sharp_Visual.indb 176 30/06/14 15:05


CAPTULO 7 Criao e gerenciamento de classes e objetos 177

Nota Convm lembrar que os mtodos static tambm so chamados de m-


todos de classe. Mas os campos static no so em geral chamados de campos
de classe; eles so chamados apenas de campos static (ou, eventualmente, de
variveis static).

Crie um campo static utilizando a palavra-chave


const
Prefixando o campo com a palavra-chave const, voc pode declarar que um campo
esttico, mas que seu valor nunca pode mudar. A palavra-chave const uma abrevia-
o de constante. Um campo const no utiliza a palavra-chave static na sua declarao,
mas mesmo assim esttico. Contudo, por razes cujas explicaes esto fora dos ob-
jetivos deste livro, voc s pode declarar um campo como const quando esse campo
um tipo numrico (como int ou double), uma string ou uma enumerao (voc vai
aprender sobre enumeraes no Captulo 9, Como criar tipos-valor com enumeraes
e estruturas). Por exemplo, veja como a classe Math declara PI como um campo const:
class Math
{
...
public const double PI = 3.14159265358979323846;
}

Entenda as classes static


Outro recurso da linguagem C# a capacidade de declarar uma classe como static.
Uma classe static s pode conter membros static. (Todos os objetos que voc cria utili-
zando essa classe compartilham uma nica cpia desses membros.) O objetivo de uma
classe static puramente atuar como um continer de campos e mtodos utilitrios.
Uma classe static no pode conter dados ou mtodos de instncia e no faz sentido
tentar criar um objeto de uma classe static usando o operador new. De fato, voc no
pode criar uma instncia de um objeto que utiliza uma classe static utilizando new,
mesmo se quiser fazer isso. (O compilador informar um erro se voc tentar.) Se voc
precisar fazer alguma inicializao, uma classe static poder ter um construtor padro,
desde que ele tambm seja declarado como static. Qualquer outro tipo de construtor
ilegal e ser reportado como tal pelo compilador.
Se voc estivesse definindo sua prpria verso da classe Math, contendo apenas
membros static, ela poderia se parecer com esta:
public static class Math
{
public static double Sin(double x) {...}
public static double Cos(double x) {...}
public static double Sqrt(double x) {...}
...
}

Nota A classe Math real no definida assim, porque na verdade ela tem al-
guns mtodos de instncia.

_Livro_Sharp_Visual.indb 177 30/06/14 15:05


178 PARTE II O modelo de objetos do C#

No exerccio final deste captulo, voc adicionar um campo private static clas-
se Point e inicializar o campo como 0. Voc incrementar essa contagem nos dois
construtores. Por fim, voc escrever um mtodo public static para retornar o valor
desse campo private static. Com esse campo, voc pode descobrir quantos objetos
Point foram criados.

Escreva membros static e chame mtodos static


1. No Visual Studio 2013, exiba a classe Point na janela Code and Text Editor.
2. Adicione um campo private static chamado objectCount do tipo int classe
Point, imediatamente antes dos construtores. Inicialize-o como 0 ao declar-lo,
da seguinte maneira:
class Point
{
...
private static int objectCount = 0;
...
}

Nota Ao declarar um campo como objectCount, voc pode escrever as pala-


vras-chave private e static em qualquer ordem. Contudo, a ordem preferida
private em primeiro lugar, static em segundo.

3. Adicione uma instruo aos dois construtores Point para incrementar o campo
objectCount, como mostrado em negrito no exemplo de cdigo a seguir.
A classe Point deve se parecer com isto:
class Point
{
private int x, y;
private static int objectCount = 0;

public Point()
{
this.x = -1;
this.y = -1;
objectCount++;
}

public Point(int x, int y)


{
this.x = x;
this.y = y;
objectCount++;
}
public double DistanceTo(Point other)
{
int xDiff = this.x - other.x;
int yDiff = this.y - other.y;
return Math.Sqrt((xDiff * xDiff) + (yDiff * yDiff));
}
}

_Livro_Sharp_Visual.indb 178 30/06/14 15:05


CAPTULO 7 Criao e gerenciamento de classes e objetos 179

Toda vez que um objeto criado, seu construtor chamado. Desde que voc
incremente o objectCount em cada construtor (incluindo o construtor padro),
objectCount armazenar o nmero de objetos criados at aqui. Essa estratgia s
funciona porque objectCount um campo static compartilhado. Se objectCount
fosse um campo de instncia, cada objeto teria seu prprio campo objectCount
pessoal que seria definido como 1.
A questo agora : como os usurios da classe Point podem descobrir quantos
objetos Point foram criados? No momento, o campo objectCount private e
no est disponvel fora da classe. Uma soluo precria seria tornar o campo
objectCount publicamente acessvel. Essa estratgia quebraria o encapsulamen-
to da classe e, ento, voc no teria qualquer garantia de que seu valor estaria
correto, porque qualquer coisa poderia alterar o valor no campo. Uma ideia
muito melhor fornecer um mtodo public static que retorne o valor do campo
objectCount. Isso o que voc far agora.
4. Adicione classe Point um mtodo public static chamado ObjectCount, que re-
torna um int mas no recebe parmetros. Nesse mtodo, retorne o valor do
campo objectCount, como em negrito aqui:
class Point
{
...
public static int ObjectCount()
{
return objectCount;
}
}

5. Exiba a classe Program na janela Code and Text Editor. Adicione uma instruo
ao mtodo doWork para escrever na tela o valor retornado a partir do mtodo
ObjectCount da classe Point, como mostrado no texto em negrito no exemplo de
cdigo a seguir.
static void doWork()
{
Point origin = new Point();
Point bottomRight = new Point(1366, 768);
double distance = origin.distanceTo(bottomRight);
Console.WriteLine("Distance is: {0}", distance);
Console.WriteLine("Number of Point objects: {0}", Point.ObjectCount());
}

O mtodo ObjectCount chamado referenciando Point, o nome da classe e no


o nome de uma varivel Point (como origin ou bottomRight). Como dois objetos
Point foram criados quando ObjectCount foi chamado, o mtodo deve retornar
o valor 2.

_Livro_Sharp_Visual.indb 179 30/06/14 15:05


180 PARTE II O modelo de objetos do C#

6. No menu Debug, clique em Start Without Debugging.


Confirme que a mensagem Number of Point objects: 2 foi escrita na janela do
console (aps a mensagem que exibe o valor da varivel distance).
7. Pressione Enter para terminar o programa e retorne para o Visual Studio 2013.

Classes annimas
Uma classe annima uma classe que no tem nome. Isso parece bastante estranho,
mas bem til em algumas situaes que veremos mais adiante neste livro, especial-
mente ao se utilizar expresses de consulta (query). (Voc aprender sobre expresses
de consulta no Captulo 20, Separao da lgica do aplicativo e tratamento de even-
tos.) Por enquanto, voc ter de acreditar que elas so teis.
Voc cria uma classe annima simplesmente utilizando a palavra-chave new e
um par de chaves que definem os campos e valores que voc quer que a classe con-
tenha, assim:
myAnonymousObject = new { Name = "John", Age = 47 };

Essa classe contm dois campos pblicos chamados Name (inicializado com a
string John) e Age (inicializado com o inteiro 47). O compilador infere os tipos dos
campos a partir dos tipos de dados que voc especifica para inicializ-los.
Ao se definir uma classe annima, o compilador gera um nome prprio para a
classe, mas ele no informar qual esse nome. Portanto, as classes annimas sus-
citam um enigma potencialmente interessante: se voc no sabe o nome da classe,
como poder criar um objeto do tipo apropriado e atribuir uma instncia da classe a
ele? No exemplo de cdigo mostrado antes, qual deve ser o tipo da varivel myAnony-
mousObject? A resposta que voc no sabe esse o propsito das classes anni-
mas! Mas isso no um problema se voc declarar myAnonymousObject como uma
varivel implicitamente tipada utilizando a palavra-chave var, desta maneira:
var myAnonymousObject = new { Name = "John", Age = 47 };

Lembre-se de que a palavra-chave var faz o compilador criar uma varivel do


mesmo tipo da expresso utilizada para inicializ-la. Nesse caso, o tipo da expresso
o nome que o compilador gera para a classe annima.
Voc pode acessar os campos no objeto utilizando a conhecida notao de pon-
to, como demonstrado aqui:
Console.WriteLine("Name: {0} Age: {1}", myAnonymousObject.Name, myAnonymousObject.Age};

Voc pode at mesmo criar outras instncias da mesma classe annima, mas
com valores diferentes, como no seguinte:
var anotherAnonymousObject = new { Name = "Diana", Age = 46 };

_Livro_Sharp_Visual.indb 180 30/06/14 15:05


CAPTULO 7 Criao e gerenciamento de classes e objetos 181

O compilador do C# utiliza os nomes, os tipos, o nmero e a ordem dos campos


para determinar se duas instncias de uma classe annima tm o mesmo tipo. Nes-
se caso, as variveis myAnonymousObject e anotherAnonymousObject tm o mesmo
nmero de campos, com o mesmo nome e tipo, na mesma ordem; portanto, as duas
variveis so instncias da mesma classe annima. Isso significa que voc pode realizar
instrues de atribuio como esta:
anotherAnonymousObject = myAnonymousObject;

Nota Esteja ciente de que essa instruo de atribuio talvez no realize o que
voc espera. Voc aprender mais sobre como atribuir variveis de objeto no
Captulo 8.

H muitas restries quanto ao contedo de uma classe annima. Por exemplo,


as classes annimas s podem conter campos pblicos, todos esses campos precisam
ser inicializados, eles no podem ser estticos e voc no pode definir mtodo algum
para elas. Voc vai usar classes annimas periodicamente neste livro e, medida que
fizer isso, vai aprender mais sobre elas.

Resumo
Neste captulo, voc viu como pode definir novas classes. Voc aprendeu que, por
padro, os campos e os mtodos de uma classe so privados e inacessveis ao cdigo
fora da classe, mas que pode utilizar a palavra-chave public para expor campos e m-
todos para o mundo exterior. Voc viu como utilizar a palavra-chave new para criar
uma nova instncia de uma classe e como definir construtores que podem inicializar
instncias de classes. Por ltimo, voc examinou a implementao de campos e mto-
dos estticos, para fornecer dados e operaes que independem de qualquer instncia
especfica de uma classe.
j Se quiser continuar no prximo captulo, mantenha o Visual Studio 2013 execu-
tando e v para o Captulo 8.
j Se quiser encerrar o Visual Studio 2013 agora, no menu File, clique em Exit. Se vir
uma caixa de dilogo Save, clique em Yes e salve o projeto.

_Livro_Sharp_Visual.indb 181 30/06/14 15:05


182 PARTE II O modelo de objetos do C#

Referncia rpida

Para Faa isto


Declarar uma Escreva a palavra-chave class, seguida pelo nome da classe, seguida por uma
classe chave de abertura e uma de fechamento. Os mtodos e campos da classe
so declarados entre as chaves de abertura e fechamento. Por exemplo:
class Point
{
...
}

Declarar um Escreva um mtodo cujo nome seja o mesmo nome da classe e que no
construtor tenha qualquer tipo de retorno (nem mesmo void). Por exemplo:
class Point
{
public Point(int x, int y)
{
...
}
}

Chamar um Use a palavra-chave new e especifique o construtor com um conjunto de


construtor parmetros apropriados. Por exemplo:
Point origin = new Point(0, 0);

Declarar um Escreva a palavra-chave static antes da declarao do mtodo. Por exemplo:


mtodo static
class Point
{
public static int ObjectCount()
{
...
}
}

Chamar um Escreva o nome da classe, seguida de um ponto, seguida do nome do


mtodo static mtodo. Por exemplo:
int pointsCreatedSoFar = Point.ObjectCount();

Declarar um Use a palavra-chave static antes do tipo do campo. Por exemplo:


campo static
class Point
{
...
private static int objectCount;
}

Declarar um Escreva a palavra-chave const antes da declarao do campo e omita a


campo const palavra-chave static. Por exemplo:
class Math
{
...
public const double PI = ...;
}

Acessar um Escreva o nome da classe, seguido de um ponto, seguido do nome do


campo static mtodo. Por exemplo:
double area = Math.PI * radius * radius;

_Livro_Sharp_Visual.indb 182 30/06/14 15:05


CAPTULO 8

Valores e referncias
Neste captulo, voc vai aprender a:
j Explicar as diferenas entre um tipo-valor e um tipo-referncia.
j Modificar a maneira como os argumentos so passados como parmetros de
mtodos utilizando as palavras-chave ref e out.
j Converter um valor em uma referncia usando boxing.
j Converter uma referncia de volta em um valor usando unboxing e casting.
O Captulo 7, Criao e gerenciamento de classes e objetos, apresentou a declarao
de suas classes e a criao de objetos por meio da palavra-chave new. Tambm foi
possvel ver como fazer a inicializao de um objeto por meio de um construtor. Neste
captulo, voc vai aprender a diferena entre as caractersticas dos tipos primitivos
como int, double e char e as caractersticas dos tipos de classe.

Copie variveis de tipo-valor e classes


A maioria dos tipos primitivos do C#, como int, float, double e char (mas no string, por
motivos que sero abordados em breve) coletivamente chamada de tipos-valor. Es-
ses tipos tm tamanho fixo e, quando voc declara uma varivel como um tipo-valor,
o compilador gera o cdigo que aloca um bloco de memria grande o suficiente para
conter um valor correspondente. Por exemplo, declarar uma varivel int faz o compi-
lador alocar 4 bytes de memria (32 bits). Uma instruo que atribui um valor (como
42) a int faz o valor ser copiado para esse bloco de memria.
Os tipos classe, como Circle (descrito no Captulo 7), so tratados de maneira
diferente. Quando voc declara uma varivel Circle, o compilador no gera um cdigo
que aloca um bloco de memria grande o suficiente para armazenar Circle; tudo o que
ele faz alocar uma pequena parte da memria que possa armazenar o endereo de
(ou referncia a) outro bloco de memria que contm Circle. (Um endereo especifica
a localizao de um item na memria.) A memria para o objeto Circle real s aloca-
da quando a palavra-chave new utilizada para criar o objeto. Uma classe um exem-
plo de tipo-referncia. Tipos-referncia contm referncias a blocos de memria. Para
escrever programas C# eficazes, que usem plenamente o Microsoft .NET Framework,
voc deve saber a diferena entre tipos-valor e tipos-referncia.

_Livro_Sharp_Visual.indb 183 30/06/14 15:05


184 PARTE II O modelo de objetos do C#

Nota Em C#, o tipo string na verdade uma classe. Isso porque no h um


tamanho padro para uma string (diferentes strings podem conter diferentes
nmeros de caracteres) e bem mais eficiente alocar memria para elas dina-
micamente, quando o programa executado, do que estaticamente, em tempo
de compilao. A descrio de tipos-referncia, como as classes, deste captulo,
tambm se aplica ao tipo string. Na verdade, no C#, a palavra-chave string
apenas um alias para a classe System.String.

Considere a situao em que voc declara uma varivel chamada i como um


int e atribui a ela o valor 42. Se declarar outra varivel chamada copyi como um int e
ento atribuir i a copyi, copyi conter o mesmo valor que i (42). Contudo, embora copyi
e i contenham o mesmo valor, h dois blocos de memria contendo o valor 42: um
bloco para i e outro bloco para copyi. Se voc modificar o valor de i, o valor de copyi
no ser alterado. Vejamos isso em cdigo:
int i = 42; // declara e inicializa i
int copyi = i; /* copyi contm uma cpia dos dados em i:
i e copyi contm ambas o valor 42 */
i++; /* um incremento em i no tem efeito sobre copyi;
agora i contm 43, mas copyi ainda contm 42

O efeito de declarar uma varivel c como um tipo de classe, como Circle, muito
diferente. Quando voc declara c como Circle, c pode se referir a um objeto Circle; o
valor real armazenado por c o endereo de um objeto Circle na memria. Se voc
declarar mais uma varivel, chamada refc (tambm como Circle), e atribuir c a refc, refc
ter uma cpia do mesmo endereo que c; ou seja, existe apenas um objeto Circle e,
agora, tanto refc como c se referem a ele. Vejamos o exemplo em cdigo:
Circle c = new Circle(42);
Circle refc = c;

A figura a seguir ilustra ambos os exemplos. O sinal (@) nos objetos Circle repre-
senta uma referncia que armazena um endereo na memria:

Essa diferena muito importante. Em particular, ela significa que o comporta-


mento dos parmetros do mtodo depende de eles serem tipos-valor ou tipos-refe-
rncia. Voc vai explorar essa diferena no prximo exerccio.

_Livro_Sharp_Visual.indb 184 30/06/14 15:05


CAPTULO 8 Valores e referncias 185

Cpia de tipos-referncia e privacidade de dados


Se voc realmente quiser copiar o contedo de um objeto Circle, c, para outro
objeto Circle, refc, em vez de apenas copiar a referncia, deve fazer refc refe-
renciar uma nova instncia da classe Circle e ento copiar os dados campo por
campo, de c para refc, assim:
Circle refc = new Circle();
refc.radius = c.radius; // No tente isto

Mas se qualquer membro da classe Circle for privado (como o campo ra-
dius), voc no poder copiar esses dados. Em vez disso, poderia tornar os dados
dos campos privados acessveis, expondo-os como propriedades, e ento utilizar
essas propriedades para ler os dados de c e copi-los em refc. Voc aprender a
fazer isso no Captulo 15, Implementao de propriedades para acessar campos.
Como alternativa, uma classe poderia fornecer um mtodo Clone que retor-
nasse outra instncia da mesma classe, mas preenchesse com os mesmos dados.
O mtodo Clone teria acesso aos dados privados de um objeto e poderia copiar
esses dados diretamente para a outra instncia da mesma classe. Por exemplo, o
mtodo Clone da classe Circle poderia ser definido assim:
class Circle
{
private int radius;
// Construtores e outros mtodos omitidos
...
public Circle Clone()
{
// Cria um novo objeto Circle
Circle clone = new Circle();

// Copia dados privados de this para clone


clone.radius = this.radius;

// Retorna o novo objeto Circle contendo os dados copiados


return clone;
}
}

Essa estratgia natural se todos os dados privados consistirem em valores,


mas se um ou mais campos forem eles prprios tipos-referncia (por exemplo,
a classe Circle poderia ser estendida para conter um objeto Point do Captulo
7, indicando a posio do Circle em um grfico), esses tipos-referncia tambm
precisariam fornecer um mtodo Clone; caso contrrio, o mtodo Clone da classe
Circle simplesmente copiaria uma referncia para esses campos. Esse um pro-
cesso conhecido como cpia profunda. A estratgia alternativa, onde o mtodo
Clone simplesmente copia referncias, conhecida como cpia rasa.

_Livro_Sharp_Visual.indb 185 30/06/14 15:05


186 PARTE II O modelo de objetos do C#

O exemplo de cdigo anterior tambm apresenta uma questo interes-


sante: como private dado privado? Vimos anteriormente que a palavra-chave
private torna um campo ou mtodo inacessvel fora de uma classe. No entanto,
isso no significa que ele possa ser acessado por apenas um objeto. Se voc criar
dois objetos da mesma classe, cada um poder acessar os dados privados do ou-
tro. Isso parece curioso, mas na verdade, mtodos como Clone dependem dessa
caracterstica. A instruo clone.radius = this.radius; s funciona porque o campo
privado radius no objeto clone acessvel dentro da instncia atual da classe Cir-
cle. Assim, private significa na verdade privado para a classe e no privado para
um objeto. Mas no confunda private com static. Se voc simplesmente declara
um campo como private, cada instncia da classe recebe seus prprios dados.
Se um campo declarado como static, cada instncia da classe compartilha os
mesmos dados.

Utilize parmetros por valor e parmetros por referncia


1. Inicialize o Microsoft Visual Studio 2013 se ele ainda no estiver em execuo.
2. Abra o projeto Parameters, localizado na pasta \Microsoft Press\Visual CSharp
Step By Step\Chapter 8\Windows X\Parameters na sua pasta Documentos.
O projeto contm trs arquivos de cdigo C#: Pass.cs, Program.cs e WrappedInt.cs.
3. Exiba o arquivo Pass.cs na janela Code and Text Editor.
Esse arquivo define uma classe chamada Pass que atualmente est vazia, a no
ser por um comentrio // TODO:

Dica Lembre-se de que possvel utilizar a janela Task List para localizar
todos os comentrios TODO em uma soluo.

4. Adicione um mtodo public static chamado Value classe Pass, substituindo o


comentrio // TODO:. Esse mtodo deve aceitar um nico parmetro int (um
tipo-valor) chamado param e ter um tipo de retorno void. O corpo do mtodo
Value deve simplesmente atribuir o valor 42 a param, como mostrado em negri-
to no exemplo de cdigo a seguir.
namespace Parameters
{
class Pass
{
public static void Value(int param)
{
param = 42;
}
}
}

_Livro_Sharp_Visual.indb 186 30/06/14 15:05


CAPTULO 8 Valores e referncias 187

Nota O motivo de voc estar definindo esse mtodo como esttico


manter o exerccio simples. Voc pode chamar o mtodo Value diretamen-
te na classe Pass, em vez de primeiro ter de criar um novo objeto Pass. Os
princpios ilustrados neste exerccio se aplicam exatamente da mesma ma-
neira aos mtodos de instncia.

5. Exiba o arquivo-fonte Program.cs na janela Code and Text Editor e localize o


mtodo doWork da classe Program.
O mtodo doWork chamado pelo mtodo Main quando o programa comea a
executar. Conforme explicado no Captulo 7, a chamada de mtodo vem dentro
de um bloco try e seguida por uma rotina de tratamento catch.
6. Adicione quatro instrues ao mtodo doWork para executar as seguintes tarefas:
a. Declarar uma varivel local int chamada i e inicializ-la como 0.
b. Escrever o valor de i no console utilizando Console.WriteLine.
c. Chamar Pass.Value, passando i como argumento.
d. Escrever novamente o valor de i no console.
Com as chamadas a Console.WriteLine antes e depois da chamada a Pass.Value,
voc pode ver se a chamada a Pass.Value realmente modifica o valor de i. O m-
todo doWork concludo deve ser exatamente como este:
static void doWork()
{
int i = 0;
Console.WriteLine(i);
Pass.Value(i);
Console.WriteLine(i);
}

7. No menu Debug, clique em Start Without Debugging para compilar e executar


o aplicativo.
8. Confirme se o valor 0 foi escrito duas vezes na janela do console.
A instruo de atribuio dentro do mtodo Pass.Value, que atualiza o parme-
tro e o define com 42, utiliza uma cpia do argumento passado e o argumento
original i permanece completamente inalterado.
9. Pressione a tecla Enter para fechar o aplicativo.
Voc ver agora o que acontece quando passa um parmetro int que est inse-
rido dentro de uma classe.
10. Exiba o arquivo WrappedInt.cs na janela Code and Text Editor. Esse arquivo
contm a classe WrappedInt, a qual est vazia, a no ser por um comentrio
// TODO: .

_Livro_Sharp_Visual.indb 187 30/06/14 15:05


188 PARTE II O modelo de objetos do C#

11. Adicione um campo de instncia public chamado Number do tipo int classe
WrappedInt, como mostrado em negrito no cdigo a seguir:
namespace Parameters
{
class WrappedInt
{
public int Number;
}
}

12. Exiba o arquivo Pass.cs na janela Code and Text Editor. Adicione um mtodo pu-
blic static chamado Reference classe Pass. Esse mtodo deve aceitar um nico
parmetro WrappedInt chamado param e ter um tipo de retorno void. O corpo
do mtodo Reference deve atribuir 42 a param.Number, como mostrado aqui:
public static void Reference(WrappedInt param)
{
param.Number = 42;
}

13. Exiba o arquivo Program.cs na janela Code and Text Editor. Transforme em co-
mentrio o cdigo existente no mtodo doWork e adicione mais quatro instru-
es para executar as seguintes tarefas:
a. Declarar uma varivel local WrappedInt chamada wi e inicializ-la com um
novo objeto WrappedInt chamando o construtor padro.
b. Escrever o valor de wi.Number no console.
c. Chamar o mtodo Pass.Reference, passando wi como argumento.
d. Escrever o valor de wi.Number novamente no console.
Como antes, com as chamadas a Console.WriteLine, voc pode ver se a chamada
a Pass.Reference modifica o valor de wi.Number. O mtodo doWork agora deve
estar assim (as novas instrues esto destacadas em negrito):
static void doWork()
{
// int i = 0;
// Console.WriteLine(i);
// Pass.Value(i);
// Console.WriteLine(i);

WrappedInt wi = new WrappedInt();


Console.WriteLine(wi.Number);
Pass.Reference(wi);
Console.WriteLine(wi.Number);
}

14. No menu Debug, clique em Start Without Debugging para compilar e executar
o aplicativo.

_Livro_Sharp_Visual.indb 188 30/06/14 15:05


CAPTULO 8 Valores e referncias 189

Desta vez, os dois valores exibidos na janela de console correspondem ao valor


de wi.Number antes e depois da chamada ao mtodo Pass.Reference. Voc deve
ver que os valores 0 e 42 so exibidos.
15. Pressione a tecla Enter para finalizar o programa e retornar ao Visual Studio
2013.
Para explicar o que o exerccio anterior demonstra, o valor de wi.Number ini-
cializado como 0 pelo construtor gerado pelo compilador. A varivel wi contm uma
referncia ao objeto WrappedInt recm-criado (que contm um int). A varivel wi
ento copiada como um argumento para o mtodo Pass.Reference. Como WrappedInt
uma classe (um tipo-referncia), wi e param referenciam o mesmo objeto Wrappe-
dInt. Qualquer alterao feita ao contedo do objeto, por meio da varivel param no
mtodo Pass.Reference, visvel utilizando a varivel wi quando o mtodo concludo.
O diagrama a seguir ilustra o que acontece quando um objeto WrappedInt passado
como um argumento para o mtodo Pass.Reference:

Valores nulos e tipos nullable


Ao se declarar uma varivel, sempre uma boa ideia inicializ-la. Com tipos-valor,
comum ver cdigo como este:
int i = 0;
double d = 0.0;

Lembre-se de que, para inicializar uma varivel de referncia como uma classe,
voc pode criar uma nova instncia da classe e atribuir a varivel de referncia ao novo
objeto, assim:
Circle c = new Circle(42);

Tudo isso est correto, mas e se voc na verdade no quiser criar um novo ob-
jeto? Talvez o propsito da varivel seja simplesmente armazenar uma referncia para
um objeto existente em algum ponto posterior em seu programa. No exemplo de
cdigo a seguir, a varivel Circle copy inicializada, mas depois a ela atribuda uma
referncia a outra instncia da classe Circle:
Circle c = new Circle(42);
Circle copy = new Circle(99); // Algum valor aleatrio, para inicializar copy
...
copy = c; // copy e c referenciam o mesmo objeto

_Livro_Sharp_Visual.indb 189 30/06/14 15:05


190 PARTE II O modelo de objetos do C#

Depois de atribuir c a copy, o que acontece ao objeto Circle original com um raio
de 99 que voc utilizou para inicializar copy? Nada mais o referencia. Nessa situao, o
runtime pode reivindicar a memria, realizando uma operao conhecida como coleta
de lixo, cujos detalhes voc conhecer no Captulo 14, Coleta de lixo e gerenciamento
de recursos. O importante a entender agora que a coleta de lixo uma operao
potencialmente demorada; voc no deve criar objetos que nunca so utilizados, pois
isso desperdia tempo e recursos.
Voc poderia argumentar que, se uma varivel vai receber uma referncia a ou-
tro objeto em algum ponto em um programa, no faz sentido inicializ-la. Mas isso
uma pssima prtica de programao, que pode levar a problemas no seu cdigo.
Por exemplo, voc se encontrar inevitavelmente na situao em que quer referenciar
uma varivel para um objeto somente se essa varivel ainda no contiver uma refern-
cia, como mostra o seguinte exemplo de cdigo:
Circle c = new Circle(42);
Circle copy; // No inicializada !!!
...
if (copy == // s atribui a copy se no estiver inicializada, mas o que acontece aqui?)
{
copy = c; // copy e c referenciam o mesmo objeto
...
}

O propsito da instruo if testar a varivel copy para ver se ela foi inicializada,
mas com qual valor voc deve comparar essa varivel? A resposta utilizar um valor
especial chamado null.
No C#, voc pode atribuir o valor null a qualquer varivel-referncia. O valor null
simplesmente significa que a varivel no referencia objeto algum na memria. Voc
pode utiliz-lo desta forma:
Circle c = new Circle(42);
Circle copy = null; // Inicializada
...
if (copy == null)
{
copy = c; // copy e c referenciam o mesmo objeto
...
}

Utilize tipos nullable


O valor null til para inicializar tipos-referncia. s vezes, voc precisa de um valor
equivalente para tipos-valor, mas null ele prprio uma referncia; assim, no poss-
vel atribu-lo a um tipo-valor. A seguinte instruo , portanto, invlida no C#:
int i = null; // invlido

Mas o C# define um modificador que pode ser utilizado para declarar se uma
varivel um tipo-valor nullable. Um tipo-valor nullable comporta-se de maneira se-
melhante ao tipo-valor original, mas voc pode atribuir o valor null a ele. Use o ponto
de interrogao (?) para indicar que um tipo-valor nullable, assim:
int? i = null; // vlido

Sharp_Visual_08.indd 190 10/09/14 16:50


CAPTULO 8 Valores e referncias 191

possvel determinar se uma varivel nullable contm null testando-a da mesma


maneira que um tipo-referncia:
if (i == null)
...

Voc pode atribuir uma expresso do tipo-valor apropriado diretamente a uma


varivel nullable. Todos os exemplos a seguir so vlidos:
int? i = null;
int j = 99;
i = 100; // Copia um tipo-valor constante em um tipo nullable
i = j; // Copia um tipo-valor varivel em um tipo nullable

Voc deve observar que o contrrio no verdadeiro. Voc no pode atribuir


uma varivel nullable a uma varivel de tipo-valor normal. Portanto, dadas as defini-
es das variveis i e j do exemplo anterior, a instruo a seguir no permitida:
j = i; // Invlido

Isso faz sentido, se voc considerar que a varivel i pode conter null e que j um
tipo-valor que no pode conter null. Isso tambm significa que voc no pode utilizar
uma varivel nullable como um parmetro para um mtodo que espera receber um
tipo-valor normal. Se voc se lembra, o mtodo Pass.Value do exerccio anterior espera
um parmetro normal int; portanto, a seguinte chamada de mtodo no compilar:
int? i = 99;
Pass.Value(i); // Erro do compilador

Entenda as propriedades dos tipos nullable


Um tipo nullable expe um par de propriedades que voc pode utilizar para deter-
minar se o tipo realmente tem um valor no null e qual esse valor. A propriedade
HasValue indica se um tipo nullable contm um valor ou null e voc pode recuperar
o valor de um tipo nullable no null lendo a propriedade Value, desta maneira:
int? i = null;
...
if (!i.HasValue)
{
// Se i null, atribui o valor 99 a ele
i = 99;
}
else
{
// Se i no null, ento exibe seu valor
Console.WriteLine(i.Value);
}

O Captulo 4, Instrues de deciso, ensinou que o operador NOT (!) nega um


valor booleano. Esse fragmento de cdigo testa a varivel nullable i e, se ela no tiver
um valor (for null), atribui a essa varivel o valor 99; do contrrio, exibe o valor da
varivel. Nesse exemplo, utilizar a propriedade HasValue no traz benefcio algum em
relao a testar se um valor null diretamente. Alm disso, ler a propriedade Value
uma maneira tediosa de ler o contedo da varivel. Mas essas deficincias aparentes
so causadas pelo fato de que int? um tipo nullable muito simples. Voc pode criar

Sharp_Visual_08.indd 191 10/09/14 16:53


192 PARTE II O modelo de objetos do C#

tipos-valor mais complexos e utiliz-los para declarar variveis nullable em que as


vantagens da utilizao das propriedades HasValue e Value tornam-se mais aparentes.
Veremos alguns exemplos no Captulo 9, Como criar tipos-valor com enumerao e
estruturas.

Nota A propriedade Value de um tipo nullable somente de leitura. Voc


pode utilizar essa propriedade para ler o valor de uma varivel, mas no para
modific-la. Para atualizar uma varivel nullable, utilize uma instruo de atri-
buio comum.

Parmetros ref e out


Em geral, quando voc passa um argumento para um mtodo, o parmetro corres-
pondente inicializado com uma cpia do argumento. Isso verdade independente-
mente de o parmetro ser um tipo-valor (como um int), um tipo nullable (como int?)
ou um tipo-referncia (como um WrappedInt). Esse arranjo significa que impossvel
qualquer alterao no parmetro afetar o valor do argumento passado. Por exemplo,
no cdigo a seguir, o valor apresentado no console 42 e no 43. O mtodo doIncre-
ment incrementa uma cpia do argumento (arg) e no o argumento original, como
demonstrado aqui:
static void doIncrement(int param)
{
param++;
}

static void Main()


{
int arg = 42;
doIncrement(arg);
Console.WriteLine(arg); // escreve 42, no 43
}

No exerccio anterior, voc viu que, se o parmetro para um mtodo um tipo-


-referncia, qualquer alterao feita utilizando esse parmetro modifica os dados re-
ferenciados pelo argumento passado por ele. O ponto-chave este: embora os dados
referenciados tenham mudado, o argumento passado como parmetro no mudou
ele ainda referencia o mesmo objeto. Em outras palavras, embora seja possvel
modificar o objeto que o argumento referencia, no possvel modificar o argumento
propriamente dito (por exemplo, para defini-lo a fim de referenciar um objeto com-
pletamente diferente). Na maioria das vezes, essa garantia muito til e pode ajudar a
reduzir o nmero de erros em um programa. Eventualmente, porm, voc pode que-
rer escrever um mtodo que de fato precise modificar um argumento. O C# fornece as
palavras-chave ref e out para isso.

_Livro_Sharp_Visual.indb 192 30/06/14 15:05


CAPTULO 8 Valores e referncias 193

Crie parmetros ref


Se voc utilizar a palavra-chave ref como prefixo de um parmetro, o compilador do
C# gerar cdigo que passa uma referncia ao argumento real, em vez de uma cpia
do argumento. Ao utilizar um parmetro ref, tudo o que voc fizer ao parmetro tam-
bm ser feito ao argumento original, porque o parmetro e o argumento referenciam
o mesmo dado. Ao passar um argumento como um parmetro ref, voc tambm deve
prefixar o argumento com a palavra-chave ref. Essa sintaxe fornece uma indicao
visual til para o programador de que o argumento pode mudar. Veja novamente o
exemplo anterior, desta vez modificado para utilizar a palavra-chave ref:
static void doIncrement(ref int param) // usando ref
{
param++;
}

static void Main()


{
int arg = 42;
doIncrement(ref arg); // usando ref
Console.WriteLine(arg); // escreve 43
}

Desta vez, o mtodo doIncrement recebe uma referncia ao argumento original,


em vez de uma cpia; portanto, qualquer alterao feita pelo mtodo utilizando essa
referncia, muda o argumento original. Essa a razo de o valor 43 ser exibido no
console.
Lembre-se de que o C# impe a regra de que voc deve atribuir um valor a
uma varivel, antes que possa l-la. Essa regra tambm se aplica aos argumentos de
mtodo: voc no pode passar um valor no inicializado como argumento para um
mtodo, mesmo que o argumento seja definido como ref. Por exemplo, no programa
a seguir, arg no inicializada; portanto, esse cdigo no ser compilado. Essa falha
ocorre porque a instruo param++; dentro do mtodo doIncrement , na verdade,
um alias para a instruo arg++; e essa operao s permitida se arg tiver um valor
definido:
static void doIncrement(ref int param)
{
param++;
}

static void Main()


{
int arg; // no inicializada
doIncrement(ref arg);
Console.WriteLine(arg);
}

Crie parmetros out


O compilador verifica se o parmetro ref recebeu um valor, antes de chamar o mto-
do. Mas pode haver ocasies em que voc queira que o prprio mtodo inicialize o
parmetro. Voc pode fazer isso com a palavra-chave out.

_Livro_Sharp_Visual.indb 193 30/06/14 15:05


194 PARTE II O modelo de objetos do C#

A palavra-chave out sintaticamente semelhante palavra-chave ref. Voc pode


utilizar a palavra-chave out como prefixo do parmetro para que o parmetro se tor-
ne um alias para o argumento. Assim como ao utilizar ref, tudo o que voc faz no
parmetro tambm feito no argumento original. Ao passar um argumento para um
parmetro out, voc tambm deve prefixar o argumento com a palavra-chave out.
A palavra-chave out uma abreviao de output. Quando voc passa um par-
metro out para um mtodo, o mtodo deve atribuir um valor a ele antes de terminar
ou retornar, como mostrado no exemplo a seguir:
static void doInitialize(out int param)
{
param = 42; // Inicializa param antes de terminar
}

O exemplo a seguir no compila porque doInitialize no atribui um valor a param:


static void doInitialize(out int param)
{
// No faz nada
}

Uma vez que um parmetro out deve receber um valor do mtodo, voc pode
chamar o mtodo sem inicializar seu argumento. Por exemplo, o cdigo a seguir cha-
ma doInitialize para inicializar a varivel arg, que ento exibida no console:
static void doInitialize(out int param)
{
param = 42;
}

static void Main()


{
int arg; // no inicializada
doInitialize(out arg); // vlido
Console.WriteLine(arg); // escreve 42
}

Examinaremos parmetros ref no prximo exerccio.

Utilize parmetros ref


1. Retorne ao projeto Parameters no Visual Studio 2013.
2. Exiba o arquivo Pass.cs na janela Code and Text Editor.
3. Edite o mtodo Value para aceitar seu parmetro como um parmetro ref.
O mtodo Value deve se parecer com este:
class Pass
{
public static void Value(ref int param)
{
param = 42;
}
...
}

_Livro_Sharp_Visual.indb 194 30/06/14 15:05


CAPTULO 8 Valores e referncias 195

4. Exiba o arquivo Program.cs na janela Code and Text Editor.


5. Transforme em comentrio as quatro primeiras instrues. Observe que a ter-
ceira instruo do mtodo doWork, Pass.Value(i);, mostra um erro. Isso porque o
mtodo Value agora espera um parmetro ref. Edite essa instruo de modo que
a chamada do mtodo Pass.Value passe seu argumento como um parmetro ref.

Nota Deixe as quatro instrues que criam e testam o objeto WrappedInt


no estado em que se encontram.

O mtodo doWork deve agora ser semelhante a este:


class Program
{
static void doWork()
{
int i = 0;
Console.WriteLine(i);
Pass.Value(ref i);
Console.WriteLine(i);
...
}
}

6. No menu Debug, clique em Start Without Debugging para compilar e executar


o aplicativo.
Desta vez, os dois primeiros valores escritos na janela de console so 0 e 42. Esse
resultado mostra que a chamada ao mtodo Pass.Value modificou o argumento
i com sucesso.
7. Pressione a tecla Enter para finalizar o programa e retornar ao Visual Studio
2013.

Nota Voc pode usar os modificadores ref e out nos parmetros de tipo-
-referncia assim como nos parmetros de tipo-valor. O efeito exata-
mente o mesmo: o parmetro torna-se um alias para o argumento.

Como a memria do computador organizada


Os computadores utilizam a memria para armazenar os programas que esto sendo
executados e os dados que esses programas utilizam. Para entender as diferenas en-
tre os tipos-valor e os tipos-referncia, til entender como os dados so organizados
na memria.

_Livro_Sharp_Visual.indb 195 30/06/14 15:05


196 PARTE II O modelo de objetos do C#

Sistemas operacionais e runtimes (ambientes de execuo) de linguagens, como


os utilizados pelo C#, em geral, dividem a memria utilizada para armazenar dados
em duas reas separadas, cada uma gerenciada de uma maneira distinta. Essas duas
reas so tradicionalmente chamadas pilha (stack) e heap. Pilha e heap servem para
propsitos diferentes, os quais esto descritos aqui:
j Quando voc chama um mtodo, a memria necessria para seus parmetros e
suas variveis locais sempre adquirida da pilha. Quando o mtodo termina (seja
porque retornou, seja porque lanou uma exceo), a memria adquirida para os
parmetros e variveis locais automaticamente liberada de volta para a pilha e
fica disponvel para ser reutilizada quando outro mtodo for chamado. Os parme-
tros de mtodo e as variveis locais na pilha tm uma vida til bem definida: eles
nascem quando o mtodo comea e desaparecem assim que o mtodo termina.

Nota Na verdade, a mesma vida til se aplica s variveis definidas em


qualquer bloco de cdigo colocado entre chaves de abertura e fechamen-
to. No exemplo de cdigo a seguir, a varivel i criada quando o corpo
do loop while comea, mas desaparece quando o loop while termina e a
execuo continua aps a chave de fechamento:
while (...)
{
int i = ; // i criada na pilha aqui
...
}
// i desaparece da pilha aqui

j Quando voc cria um objeto (uma instncia de uma classe) utilizando a palavra-
-chave new, a memria necessria para compilar o objeto sempre adquirida
do heap. Voc viu que o mesmo objeto pode ser referenciado de vrios lugares
utilizando variveis de referncia. Quando a ltima referncia a um objeto desa-
parece, a memria utilizada pelo objeto torna-se disponvel para ser reutilizada
(embora ela possa no ser utilizada imediatamente). O Captulo 14 inclui uma
discusso mais detalhada de como a memria heap empregada. Portanto, os
objetos criados no heap tm vida til mais indeterminada; um objeto criado
com a palavra-chave new, mas s desaparece em algum ponto aps a ltima
referncia a ele ser removida.

Nota Todos os tipos-valor so criados na pilha. Todos os tipos-referncia


(objetos) so criados no heap (embora a referncia em si esteja na pilha).
Tipos nullable na verdade so tipos-referncia e so criados no heap.

Os nomes pilha e heap tm origem na maneira como o runtime gerencia a


memria:
j A memria de pilha organizada como uma pilha de caixas sobrepostas umas so-
bre as outras. Quando um mtodo chamado, cada parmetro colocado em uma
caixa que disposta na parte superior da pilha. Cada varivel local igualmente
atribuda a uma caixa, e esta colocada no topo da pilha de caixas. Quando um
mtodo termina, pode-se considerar que todas as caixas so removidas da pilha.

_Livro_Sharp_Visual.indb 196 30/06/14 15:05


CAPTULO 8 Valores e referncias 197

j A memria heap literalmente um monte de caixas espalhadas por uma sala,


em vez de empilhadas ordenadamente umas sobre as outras. Cada caixa tem
um rtulo indicando se est em uso ou no. Quando um novo objeto criado,
o runtime procura uma caixa vazia e a aloca para o objeto. A referncia caixa
armazenada em uma varivel local na pilha. O runtime monitora o nmero de
referncias a cada caixa. (Lembre-se de que duas variveis podem referenciar o
mesmo objeto). Quando a ltima referncia desaparece, o runtime marca a caixa
como fora de uso e, em algum ponto no futuro, esvaziar a caixa e a disponibi-
lizar para reutilizao.

Utilize a pilha e o heap


Agora vamos examinar o que acontece quando o mtodo Method a seguir chamado:
void Method(int param)
{
Circle c;
c = new Circle(param);
...
}

Suponha que o argumento passado para param seja o valor 42. Quando o mtodo
chamado, um bloco de memria (grande o suficiente para um int) alocado na pilha
e inicializado com o valor 42. Quando o fluxo do programa entra no mtodo, outro
bloco de memria, grande o suficiente para armazenar uma referncia (um endereo de
memria), tambm alocado da pilha, mas permanece no inicializado. (Isso serve para
a varivel Circle, c.) Em seguida, outra parte da memria grande o suficiente para um
objeto Circle alocada do heap. Isso o que faz a palavra-chave new. O construtor Circle
executado para converter essa memria bruta do heap em um objeto Circle. Uma refe-
rncia a esse objeto Circle armazenada na varivel c. A figura a seguir ilustra a situao:

Neste ponto, voc j deve ter notado duas coisas:


j Embora o objeto esteja armazenado no heap, a referncia ao objeto (a varivel
c) est armazenada na pilha.
j A memria heap no infinita. Se a memria heap estiver esgotada, o operador
new lanar uma exceo OutOfMemoryException e o objeto no ser criado.

Nota O construtor Circle tambm poder lanar uma exceo. Se ele o fizer, a
memria alocada para o objeto Circle ser reivindicada e o valor retornado pelo
construtor ser null.

_Livro_Sharp_Visual.indb 197 30/06/14 15:05


198 PARTE II O modelo de objetos do C#

Quando o mtodo termina, os parmetros e variveis locais saem do escopo. A


memria adquirida para c e param so automaticamente liberadas na pilha. O runtime
nota que o objeto Circle no mais referenciado e, mais tarde, providenciar para que
sua memria seja reivindicada pelo heap. (Consulte o Captulo 14.)

A classe System.Object
Um dos tipos-referncia mais importantes no .NET Framework a classe Object no
namespace System. Para compreender completamente o significado da classe Sys-
tem.Object necessrio que voc entenda herana, que ser descrita no Captulo 12,
Herana. Por enquanto, simplesmente aceite que todas as classes so tipos especia-
lizados da classe System.Object e que voc pode utilizar System.Object para criar uma
varivel que pode referenciar qualquer tipo-referncia. System.Object uma classe to
importante que o C# fornece a palavra-chave object como um alias de System.Object.
No seu cdigo, voc pode utilizar object ou pode escrever System.Object eles signifi-
cam exatamente a mesma coisa.

Dica Utilize a palavra-chave object em vez de System.Object. Ela mais direta


e coerente com outras palavras-chave que so sinnimos para classes (como
string para System.String e algumas outras que sero abordadas no Captulo 9).

No exemplo a seguir, as variveis c e o referenciam o mesmo objeto Circle. O fato


de que o tipo de c Circle e o tipo de o object (o alias de System.Object) na prtica
fornece duas vises diferentes do mesmo item na memria.
Circle c;
c = new Circle(42);
object o;
o = c;

O diagrama a seguir ilustra como as variveis c e o referenciam o mesmo item


no heap.

_Livro_Sharp_Visual.indb 198 30/06/14 15:05


CAPTULO 8 Valores e referncias 199

Boxing
Conforme voc acabou de ver, as variveis do tipo object podem referenciar qualquer
item de qualquer tipo-referncia. Mas as variveis do tipo object tambm podem re-
ferenciar um tipo-valor. Por exemplo, as duas instrues a seguir inicializam a varivel
i (do tipo int, um tipo-valor) como 42 e, ento, inicializam a varivel o (do tipo object,
um tipo-referncia) como i:
int i = 42;
object o = i;

A segunda instruo exige uma pequena explicao para se compreender o que


realmente est acontecendo. Lembre-se de que i um tipo-valor e existe na pilha. Se
a referncia dentro de o referenciasse diretamente i, ela referenciaria a pilha. Mas to-
das as referncias devem referenciar objetos no heap; criar referncias a itens na pilha
pode comprometer seriamente a robustez do runtime e criar uma potencial brecha
de segurana; logo, isso no permitido. Portanto, o runtime aloca uma parte da me-
mria a partir do heap, copia o valor do inteiro i para essa parte da memria e faz o
objeto o referenciar essa cpia. Essa cpia automtica de um item da pilha para o heap
chamada de boxing. A figura a seguir mostra o resultado:

Importante Se voc modificar o valor original da varivel i, o valor no heap


referenciado por meio de o no mudar. Da mesma forma, se voc modificar o
valor no heap, o valor original da varivel no ser alterado.

Unboxing
Como uma varivel do tipo object pode referenciar uma cpia na forma boxed de um
valor, razovel permitir que voc acesse o valor boxed por meio da varivel. Talvez
voc suponha que possa acessar o valor int na forma boxed que a varivel o referencia,
utilizando uma instruo de atribuio simples, como esta:
int i = o;

_Livro_Sharp_Visual.indb 199 30/06/14 15:05


200 PARTE II O modelo de objetos do C#

Mas se tentar essa sintaxe, voc receber um erro de tempo de compilao. Se


pensar no assunto, muito lgico que voc no possa utilizar a sintaxe int i = o;. Afi-
nal, o pode estar referenciando qualquer coisa, e no apenas um int. Considere o que
aconteceria no cdigo a seguir se essa instruo fosse permitida:
Circle c = new Circle();
int i = 42;
object o;

o = c; // o referencia um crculo
i = o; // o que armazenado em i?

Para obter o valor da cpia boxed, voc precisa utilizar o que conhecido como
casting. Essa uma operao que verifica se seguro converter um item de um tipo
em outro, antes de realmente fazer a cpia. Voc coloca o nome do tipo como prefixo
da varivel object entre parnteses, como neste exemplo:
int i = 42;
object o = i; // faz boxing
i = (int)o; // compila normalmente

O efeito desse casting sutil. O compilador nota que voc especificou o tipo int
no casting. Em seguida, o compilador gera um cdigo para verificar o que o realmente
referencia em tempo de execuo. Poderia ser absolutamente qualquer coisa. S por-
que seu casting diz que o referencia um int, isso no significa que ele de fato faz isso.
Se o realmente referencia um int na forma boxed e tudo coincide, o casting bem-
-sucedido e o cdigo gerado pelo compilador extrai o valor do int na forma boxed
e o copia em i. (Neste exemplo, o valor na forma boxed armazenado em i.) Isso
chamado unboxing. O diagrama a seguir mostra o que est acontecendo:

Por outro lado, se o no referencia um valor int na forma boxed, h uma incom-
patibilidade de tipos, fazendo o casting falhar. O cdigo gerado pelo compilador lana
uma exceo InvalidCastException em tempo de execuo. Veja o exemplo de um
casting para uma operao de unboxing que falha:
Circle c = new Circle(42);
object o = c; // no faz boxing porque Circle uma varivel de referncia
int i = (int)o; // compila normalmente, mas lana uma exceo em tempo de execuo

O diagrama a seguir ilustra esse caso:

_Livro_Sharp_Visual.indb 200 30/06/14 15:05


CAPTULO 8 Valores e referncias 201

Voc utilizar boxing e unboxing em exerccios posteriores. Lembre-se de que


boxing e unboxing so operaes caras devido quantidade de verificao exigida e
necessidade de alocar memria heap adicional. O boxing tem suas utilidades, mas
o uso imprudente pode prejudicar seriamente o desempenho de um programa. Voc
ver uma alternativa ao boxing no Captulo 17, Genricos.

Casting de dados seguro


Utilizando um casting, voc pode especificar que, em sua opinio, os dados referen-
ciados por um objeto tm um tipo especfico e que seguro referenciar o objeto
utilizando esse tipo. A expresso-chave aqui em sua opinio. O compilador do C#
no verificar se esse o caso, mas o runtime sim. Se o tipo de objeto na memria no
corresponder ao casting, o runtime lanar uma InvalidCastException, como descrito
na seo anterior. Voc deve estar preparado para capturar essa exceo e trat-la
apropriadamente, se ela ocorrer.
Mas capturar uma exceo e tentar se recuperar dela, caso o tipo de um objeto
no seja aquele que voc esperava, uma estratgia bastante inepta. O C# fornece
dois operadores bem mais teis que podem ajudar a fazer um casting de uma maneira
muito mais elegante, os operadores is e as.

O operador is
Utilize o operador is para verificar se o tipo de um objeto aquele que voc espera,
desta maneira:
WrappedInt wi = new WrappedInt();
...
object o = wi;
if (o is WrappedInt)
{
WrappedInt temp = (WrappedInt)o; // Isso seguro; o um WrappedInt
...
}

O operador is aceita dois operandos: uma referncia a um objeto esquerda e o


nome de um tipo direita. Se o tipo do objeto referenciado no heap tiver o tipo espe-
cificado, is ser avaliado como true; caso contrrio, ser avaliado como false. O cdigo
anterior tenta fazer o casting da referncia varivel object o somente se ele souber
que o casting ser bem-sucedido.

_Livro_Sharp_Visual.indb 201 30/06/14 15:05


202 PARTE II O modelo de objetos do C#

O operador as
O operador as desempenha um papel semelhante a is, mas de uma maneira ligeira-
mente mais abreviada. Voc utiliza o operador as desta maneira:
WrappedInt wi = new WrappedInt();
...
object o = wi;
WrappedInt temp = o as WrappedInt;
if (temp != null)
{
... // O casting foi bem-sucedido
}

Como ocorre com o operador is, o operador as recebe um objeto e um tipo


como seus operandos. O runtime tenta fazer o casting do objeto para o tipo especifi-
cado. Se o casting for bem-sucedido, o resultado ser retornado e, neste exemplo, ele
atribudo varivel WrappedInt temp. Se o casting for malsucedido, o operador as
ser avaliado como o valor null e atribuir isso a temp.
H um pouco mais sobre operadores is e as do que descrito aqui e o Captulo 12
os discutir com mais detalhes.

Ponteiros e cdigo inseguro


Esta seo serve apenas para sua informao e dirige-se aos desenvolvedores
que conhecem C ou C++. Se voc iniciante em programao, sinta-se livre para
pular esta seo.
Se voc j desenvolveu programas em linguagens como C ou C++, deve
estar familiarizado com grande parte da discusso deste captulo sobre refern-
cias a objetos. Embora nem o C nem o C++ tenham tipos-referncia explcitos,
as duas linguagens tm uma construo que fornece uma funcionalidade seme-
lhante: um ponteiro.
Um ponteiro uma varivel que armazena o endereo ou uma referncia
a um item na memria (no heap ou na pilha). Uma sintaxe especial usada para
identificar uma varivel como um ponteiro. Por exemplo, a instruo a seguir
declara a varivel pi como um ponteiro para um nmero inteiro:
int *pi;

Embora a varivel pi seja declarada como um ponteiro, na verdade ela no


apontar para lugar algum at que voc a inicialize. Por exemplo, para fazer pi
apontar para a varivel do tipo inteiro i, voc pode usar as instrues a seguir e o
operador de endereo (&), o que retorna o endereo de uma varivel:
int *pi;
int i = 99;
...
pi = &i;

Voc pode acessar e modificar o valor mantido na varivel i por meio da


varivel ponteiro pi, como mostrado aqui:
*pi = 100;

_Livro_Sharp_Visual.indb 202 30/06/14 15:05


CAPTULO 8 Valores e referncias 203

Esse cdigo atualiza o valor da varivel i para 100, uma vez que pi aponta
para a mesma posio da memria que a varivel i.
Um dos principais problemas que os desenvolvedores que aprendem C e
C++ encontram entender a sintaxe usada pelos ponteiros. O operador * tem
pelo menos dois significados (alm de ser o operador aritmtico da multiplica-
o) e sempre h uma grande confuso sobre quando usar & em vez de *. A outra
questo com os ponteiros a facilidade em apontar para algo invlido ou sim-
plesmente esquecer-se de apontar para algo, e ento tentar referenciar esse algo.
O resultado ser lixo ou um programa que falhar com um erro, porque o sistema
operacional detecta uma tentativa de acessar um endereo invlido na memria.
Tambm h toda uma srie de falhas de segurana em muitos sistemas existentes
que resultam de um gerenciamento inadequado dos ponteiros; alguns ambientes
(no o Microsoft Windows) falham em impor a verificao de que um ponteiro
no referencia a memria pertencente a outro processo, abrindo a possibilidade
de que dados confidenciais sejam comprometidos.
As variveis de referncia foram adicionadas ao C# para evitar todos esses
problemas. Se realmente quiser, voc pode continuar utilizando ponteiros no C#,
mas deve marcar o cdigo como unsafe. A palavra-chave unsafe pode ser usada
para marcar um bloco de cdigo ou um mtodo inteiro, como mostrado aqui:
public static void Main(string [] args)
{
int x = 99, y = 100;
unsafe
{
swap (&x, &y);
}
Console.WriteLine("x is now {0}, y is now {1}", x, y);
}

public static unsafe void swap(int *a, int *b)


{
int temp;
temp = *a;
*a = *b;
*b = temp;
}

Quando compilar programas que contm um cdigo inseguro, voc deve


especificar a opo Allow Unsafe Code ao compilar o projeto. Para fazer isso, no
Solution Explorer, clique com o boto direito do mouse no projeto e, ento, no
menu de atalho que aparece, clique em Properties. Na janela Properties, clique na
guia Build, selecione Allow Unsafe Code e ento, no menu File, clique em Save All.
Um cdigo inseguro tambm afeta a maneira como a memria geren-
ciada. Objetos criados em cdigo inseguro so chamados de no gerenciados.
Embora no seja comum, voc poder se deparar com algumas situaes que
exigem acessar a memria dessa maneira, especialmente se estiver escrevendo
cdigo que precisa executar algumas operaes de baixo nvel do Windows.
No Captulo 14, vamos ver com mais detalhes as implicaes do uso de
cdigo que acessa memria no gerenciada.

_Livro_Sharp_Visual.indb 203 30/06/14 15:05


204 PARTE II O modelo de objetos do C#

Resumo
Neste captulo, voc aprendeu algumas diferenas importantes entre tipos-valor, que
armazenam seus valores diretamente na pilha, e tipos-referncia, que referenciam in-
diretamente seus objetos no heap. Tambm aprendeu a utilizar as palavras-chave ref
e out nos parmetros de mtodo para obter acesso aos argumentos. Voc viu como a
atribuio de um valor (por exemplo, o int 42) a uma varivel da classe System.Object
cria uma cpia boxed do valor no heap e ento faz a varivel System.Object referenciar
essa cpia. Viu tambm como a atribuio de uma varivel de um tipo-valor (como
um int) a uma varivel da classe System.Object copia o (ou faz o unbox do) valor na
classe System.Object para a memria utilizada pelo int.
j Se quiser continuar no prximo captulo, mantenha o Visual Studio 2013 execu-
tando e v para o Captulo 9.
j Se quiser encerrar o Visual Studio 2013 agora, no menu File, clique em Exit. Se vir
uma caixa de dilogo Save, clique em Yes e salve o projeto.

Referncia rpida

Para Faa isto


Copiar uma varivel de tipo-valor Basta fazer a cpia. Como a varivel um tipo-valor,
voc ter duas cpias da mesma varivel. Por exemplo:
int i = 42;
int copyi = i;

Copiar uma varivel de Basta fazer a cpia. Como a varivel um tipo-


tipo-referncia referncia, voc ter duas referncias ao mesmo
objeto. Por exemplo:
Circle c = new Circle(42);
Circle refc = c;

Declarar uma varivel que possa Declare a varivel utilizando o modificador ? com o
armazenar um tipo-valor ou o valor tipo. Por exemplo:
null
int? i = null;

Passar um argumento para um Prefixe o argumento com a palavra-chave ref. Isso


parmetro ref torna o parmetro um alias para o argumento real,
em vez de uma cpia do argumento. O mtodo pode
mudar o valor do parmetro e essa mudana ser
efetuada no argumento real e no em uma cpia local.
Por exemplo:
static void Main()
{
int arg = 42;
DoWork(ref arg);
Console.WriteLine(arg);
}

_Livro_Sharp_Visual.indb 204 30/06/14 15:05


CAPTULO 8 Valores e referncias 205

Passar um argumento para um Prefixe o argumento com a palavra-chave out. Isso


parmetro out torna o parmetro um alias para o argumento real,
em vez de uma cpia do argumento. O mtodo deve
atribuir um valor ao parmetro e esse valor se torna o
argumento real. Por exemplo:
static void Main()
{
int arg;
DoWork(out arg);
Console.WriteLine(arg);
}

Fazer boxing em um valor Inicialize ou atribua uma varivel do tipo object com o
valor. Por exemplo:
object o = 42;

Fazer unboxing em um valor Faa o casting da referncia de objeto que referencia o


valor boxed para o tipo da varivel. Por exemplo:
int i = (int)o;

Fazer casting seguro de um objeto Utilize o operador is para testar se o casting vlido.
Por exemplo:
WrappedInt wi = new WrappedInt();
...
object o = wi;
if (o is WrappedInt)
{
WrappedInt temp = (WrappedInt)o;
...
}

Outra alternativa usar o operador as para fazer o


casting e testar se o resultado null. Por exemplo:
WrappedInt wi = new WrappedInt();
...
object o = wi;
WrappedInt temp = o as WrappedInt;
if (temp != null)
...

_Livro_Sharp_Visual.indb 205 30/06/14 15:05


CAPTULO 9

Como criar tipos-valor com


enumeraes e estruturas
Neste captulo, voc vai aprender a:
j Declarar um tipo enumerado.
j Criar e utilizar um tipo enumerado.
j Declarar um tipo-estrutura.
j Criar e utilizar um tipo-estrutura.
j Explicar as diferenas de comportamento entre uma estrutura e uma classe.
O Captulo 8, Valores e referncias, abordou os dois tipos fundamentais do Micro-
soft Visual C#: os tipos-valor e os tipos-referncia. No esquea que uma varivel de
tipo-valor armazena seu valor diretamente na pilha, ao passo que uma varivel de
tipo-referncia armazena uma referncia a um objeto no heap. O Captulo 7, Criao
e gerenciamento de classes e objetos, apresentou a criao de seus prprios tipos-
-referncia atravs da definio de classes. Neste captulo, voc poder a criar seus
prprios tipos-valor.
O C# suporta duas espcies de tipos-valor: enumeraes e estruturas. Veremos
uma de cada vez.

Enumeraes
Suponha que voc queira representar as estaes do ano em um programa. Voc
poderia utilizar os valores inteiros 0, 1, 2 e 3 para descrever a primavera, o vero, o ou-
tono e o inverno, respectivamente. Esse sistema funcionaria, mas no muito intuitivo.
Se voc usasse o valor inteiro 0 no cdigo, no seria bvio que um 0 representa pri-
mavera. Alm disso, no seria uma soluo muito slida. Por exemplo, se voc declarar
uma varivel int chamada season, no h como impedir que se atribua a ela um valor
inteiro vlido fora do conjunto 0, 1, 2 ou 3. O C# oferece uma soluo melhor. Voc
pode criar uma enumerao (s vezes chamada de tipo enum), cujos valores esto
limitados a um conjunto de nomes simblicos.

_Livro_Sharp_Visual.indb 206 30/06/14 15:05


CAPTULO 9 Como criar tipos-valor com enumeraes e estruturas 207

Declare uma enumerao


Defina uma enumerao utilizando a palavra-chave enum, seguida por um conjunto
de smbolos que identificam os valores vlidos que o tipo pode ter, includos entre
chaves. Veja como declarar um tipo enumerado chamado Season, cujos valores literais
esto limitados aos nomes simblicos Spring, Summer, Fall e Winter:
enum Season { Spring, Summer, Fall, Winter }

Utilize uma enumerao


Depois que voc declarar um tipo enumerado, poder utiliz-lo exatamente como
qualquer outro tipo. Se o nome da enumerao for Season, voc pode criar variveis
do tipo Season, campos do tipo Season e parmetros do tipo Season, como mostrado
neste exemplo:
enum Season { Spring, Summer, Fall, Winter }

class Example
{
public void Method(Season parameter) // exemplo de parmetro de mtodo
{
Season localVariable; // exemplo de varivel local
...
}

private Season currentSeason; // exemplo de campo


}

Para que o valor de uma varivel de tipo enumerado possa ser lido, necessrio
atribuir-lhe um valor. Voc s pode atribuir um valor definido pela enumerao a uma
varivel do tipo enumerado, como ilustrado aqui:
Season colorful = Season.Fall;
Console.WriteLine(colorful); // escreve 'Fall'

Nota Como ocorre com todos os tipos-valor, voc pode criar uma verso
nullable de uma varivel de tipo enumerado utilizando o modificador ?. Voc
ento pode atribuir varivel o valor null, bem como os valores definidos pela
enumerao:
Season? colorful = null;

Observe que voc tem de escrever Season.Fall em vez de Fall. Todos os nomes
literais de enumeraes tm escopo definido pelo seu tipo enumerado. Isso muito
til, porque torna possvel que diferentes tipos enumerados coincidentemente conte-
nham literais com o mesmo nome.
Alm disso, observe que, quando voc exibe uma varivel de tipo enumerado
utilizando Console.WriteLine, o compilador gera um cdigo que escreve o nome do
literal cujo valor corresponde ao valor da varivel. Se necessrio, voc pode converter
explicitamente uma varivel de tipo enumerado em uma string que representa seu

_Livro_Sharp_Visual.indb 207 30/06/14 15:05


208 PARTE II O modelo de objetos do C#

valor atual, utilizando o mtodo ToString predefinido que todos os tipos enumerados
automaticamente contm, como demonstrado no exemplo a seguir:
string name = colorful.ToString();
Console.WriteLine(name); // tambm escreve 'Fall'

Muitos dos operadores padro utilizados em variveis do tipo inteiro tambm


podem ser empregados em variveis de enumerao (exceto os operadores bit a bit e
os operadores de deslocamento, que sero abordados no Captulo 16, Indexadores).
Por exemplo, voc pode comparar a igualdade de duas variveis de enumerao do
mesmo tipo utilizando o operador de igualdade (==) e ainda efetuar clculos aritm-
ticos em uma varivel de tipo enumerado (embora o resultado talvez nem sempre
tenha um significado).

Escolha valores literais de enumerao


Internamente, uma enumerao associa um valor inteiro a cada elemento da enu-
merao. Por padro, a numerao inicia em 0 para o primeiro elemento e sobe em
incrementos de 1. possvel recuperar o valor inteiro subjacente de uma varivel de
tipo enumerado. Para isso, voc deve fazer um casting para seu tipo subjacente. A
discusso sobre unboxing no Captulo 8 mostrou que o casting converte os dados de
um tipo em outro, desde que a converso seja vlida e significativa. O fragmento de
cdigo a seguir escreve o valor 2 e no a palavra Fall (lembre-se de que na enumera-
o Season, Spring 0, Summer 1, Fall 2 e Winter 3):
enum Season { Spring, Summer, Fall, Winter }
...
Season colorful = Season.Fall;
Console.WriteLine((int)colorful); // escreve '2'

Se preferir, voc pode associar uma constante inteira especfica (como 1) a um


literal de enumerao (como Spring), como no exemplo a seguir:
enum Season { Spring = 1, Summer, Fall, Winter }

Importante O valor inteiro com o qual voc inicializa um literal de enumera-


o deve ser um valor constante em tempo de compilao (como 1).

Se voc no fornecer explicitamente um valor inteiro constante a um literal de


enumerao, o compilador fornecer um valor que uma unidade maior do que o
valor do literal de enumerao anterior, exceto para o primeiro literal de enumerao,
ao qual o compilador fornece o valor padro 0. No exemplo anterior, os valores subja-
centes de Spring, Summer, Fall e Winter so atualmente 1, 2, 3 e 4.
Voc pode fornecer mais de um literal de enumerao o mesmo valor subjacen-
te. Por exemplo, no Reino Unido, o outono (Fall) chamado de Autumn. Voc pode
agradar as duas culturas como mostrado a seguir:
enum Season { Spring, Summer, Fall, Autumn = Fall, Winter }

_Livro_Sharp_Visual.indb 208 30/06/14 15:05


CAPTULO 9 Como criar tipos-valor com enumeraes e estruturas 209

Escolha o tipo subjacente de uma enumerao


Quando voc declara uma enumerao, os literais de enumerao recebem valores
do tipo int. Voc tambm pode optar por basear sua enumerao em um tipo inteiro
subjacente diferente. Por exemplo, para declarar que o tipo subjacente de Season
um short em vez de um int, voc pode escrever o seguinte:
enum Season : short { Spring, Summer, Fall, Winter }

A principal razo para fazer isso economizar memria; um int ocupa mais me-
mria do que um short e, se voc no precisa de todo o intervalo de valores dispon-
veis para um int, talvez faa sentido utilizar um tipo menor de dado.
Voc pode basear uma enumerao em qualquer um dos oito tipos de inteiro:
byte, sbyte, short, ushort, int, uint, long ou ulong. Os valores de todos os literais de
enumerao devem estar dentro do intervalo do tipo base escolhido. Por exemplo, se
basear uma enumerao no tipo de dado byte, voc poder ter no mximo 256 literais
(comeando em zero).
Agora que voc sabe como declarar uma enumerao, a prxima etapa utiliz-
-la. No exerccio a seguir, voc trabalhar com um aplicativo de console para declarar
e utilizar uma classe de enumerao que representa os meses do ano.

Crie e utilize uma enumerao


1. Inicialize o Microsoft Visual Studio 2013 se ele ainda no estiver em execuo.
2. Abra o projeto StructsAndEnums, localizado na pasta \Microsoft Press\Visual
CSharp Step By Step\Chapter 9\Windows X\StructsAndEnums na sua pasta Do-
cumentos.
3. Na janela Code and Text Editor, exiba o arquivo Month.cs.
O arquivo-fonte est vazio, a no ser pela declarao de um namespace chama-
do StructsAndEnums e um comentrio // TODO:.
4. Exclua o comentrio // TODO: e adicione uma enumerao chamada Month
para modelar os meses do ano dentro do namespace StructsAndEnums, como
mostrado em negrito no cdigo a seguir. Os 12 literais de enumerao para
Month so January a December.
namespace StructsAndEnums
{
enum Month
{
January, February, March, April,
May, June, July, August,
September, October, November, December
}
}

5. Exiba o arquivo Program.cs na janela Code and Text Editor.


Como nos exerccios dos captulos anteriores, o mtodo Main chama o mtodo
doWork e captura todas as excees que ocorrerem.

_Livro_Sharp_Visual.indb 209 30/06/14 15:05


210 PARTE II O modelo de objetos do C#

6. Na janela Code and Text Editor, adicione uma instruo ao mtodo doWork para
declarar uma varivel chamada first do tipo Month e inicialize-a como Month.Ja-
nuary. Adicione outra instruo para escrever o valor da varivel first no console.
O mtodo doWork deve ser semelhante a este:
static void doWork()
{
Month first = Month.January;
Console.WriteLine(first);
}

Nota Quando voc digita o ponto depois de Month, o Microsoft Intelli-


Sense exibe automaticamente todos os valores na enumerao Month.

7. No menu Debug, clique em Start Without Debugging.


O Visual Studio 2013 compila e executa o programa. Confirme que a palavra
January est escrita no console.
8. Pressione Enter para fechar o programa e retornar ao ambiente de programao
do Visual Studio 2013.
9. Adicione mais duas instrues ao mtodo doWork para incrementar a varivel
first e exibir seu novo valor no console, como mostrado aqui:
static void doWork()
{
Month first = Month.January;
Console.WriteLine(first);
first++;
Console.WriteLine(first);
}

10. No menu Debug, clique em Start Without Debugging.


O Visual Studio 2013 compila e executa o programa. Confirme que as palavras
January e February esto escritas no console.
Observe que efetuar uma operao matemtica (como a operao de incre-
mento) em uma varivel de tipo enumerado altera o valor inteiro interno da
varivel. Quando a varivel escrita no console, exibido o valor de enumera-
o correspondente.
11. Pressione Enter para fechar o programa e retornar ao ambiente de programao
do Visual Studio 2013.
12. Modifique a primeira instruo no mtodo doWork para inicializar a varivel first
como Month.December, conforme mostrado em negrito:

_Livro_Sharp_Visual.indb 210 30/06/14 15:05


CAPTULO 9 Como criar tipos-valor com enumeraes e estruturas 211

static void doWork()


{
Month first = Month.December;
Console.WriteLine(first);
first++;
Console.WriteLine(first);
}

13. No menu Debug, clique em Start Without Debugging.


O Visual Studio 2013 compila e executa o programa. Desta vez, a palavra De-
cember escrita no console, seguida pelo nmero 12.

Embora voc possa efetuar clculos aritmticos em uma enumerao, se os re-


sultados dessa operao estiverem fora do intervalo dos valores definidos para
o enumerador, tudo o que o runtime pode fazer interpretar o valor da varivel
como o valor inteiro correspondente.
14. Pressione Enter para fechar o programa e retornar ao ambiente de programao
do Visual Studio 2013.

Estruturas
O Captulo 8 ilustrou que as classes definem tipos-referncia, que so sempre criados
no heap. Em alguns casos, a classe pode conter to poucos dados que a sobrecarga
de gerenciamento do heap se torna desproporcional. Nesses casos, melhor definir o
tipo como uma estrutura. Uma estrutura um tipo-valor. Como as estruturas so ar-
mazenadas na pilha, desde que a estrutura seja razoavelmente pequena, a sobrecarga
de gerenciamento da memria, em geral, reduzida.
Como uma classe, uma estrutura pode ter campos, mtodos e (com uma exce-
o importante, discutida mais adiante neste captulo) construtores prprios.

Tipos-estrutura comuns
Talvez voc no tenha percebido isso, mas j usou estruturas em exerccios ante-
riores neste livro. No C#, os tipos numricos primitivos int, long e float so alias
para as estruturas System.Int32, System.Int64 e System.Single, respectivamente.
Essas estruturas tm campos e mtodos, e voc pode chamar mtodos nas va-
riveis e literais desses tipos. Por exemplo, todas essas estruturas fornecem um
mtodo ToString que pode converter um valor numrico na sua representao de
string. Todas as instrues a seguir so vlidas no C#:

_Livro_Sharp_Visual.indb 211 30/06/14 15:05


212 PARTE II O modelo de objetos do C#

int i = 55;
Console.WriteLine(i.ToString());
Console.WriteLine(55.ToString());
float f = 98.765F;
Console.WriteLine(f.ToString());
Console.WriteLine(98.765F.ToString());

Voc no v com frequncia esse uso do mtodo ToString, porque o mto-


do Console.WriteLine o chama automaticamente quando ele necessrio. mais
comum utilizar alguns dos mtodos estticos expostos por essas estruturas. Por
exemplo, nos captulos anteriores voc utilizou o mtodo esttico int.Parse para
converter uma string no seu valor inteiro correspondente. Assim, voc est cha-
mando o mtodo Parse da estrutura Int32:
string s = "42";
int i = int.Parse(s); // exatamente o mesmo que Int32.Parse

Essas estruturas tambm incluem alguns campos estticos teis. Por exem-
plo, Int32.MaxValue o valor mximo que um int pode armazenar e Int32.MinVa-
lue o menor valor que pode ser armazenado em um int.
A tabela a seguir mostra os tipos primitivos no C# e seus tipos equivalentes
no Microsoft .NET Framework. Observe que os tipos string e object so classes
(tipos-referncia) em vez de estruturas.

Palavra-chave Tipo equivalente Classe ou estrutura


bool System.Boolean Estrutura
byte System.Byte Estrutura
decimal System.Decimal Estrutura
double System.Double Estrutura
float System.Single Estrutura
int System.Int32 Estrutura
long System.Int64 Estrutura
object System.Object Classe
sbyte System.SByte Estrutura
short System.Int16 Estrutura
string System.String Classe
uint System.UInt32 Estrutura
ulong System.UInt64 Estrutura
ushort System.UInt16 Estrutura

_Livro_Sharp_Visual.indb 212 30/06/14 15:05


CAPTULO 9 Como criar tipos-valor com enumeraes e estruturas 213

Declare uma estrutura


Para declarar seu tipo-estrutura, voc utiliza a palavra-chave struct seguida pelo nome
do tipo, seguido pelo corpo da estrutura entre chaves de abertura e fechamento. Sin-
taticamente, o processo semelhante a declarar uma classe. Por exemplo, veja uma
estrutura chamada Time que contm trs campos public int chamados hours, minutes
e seconds:
struct Time
{
public int hours, minutes, seconds;
}

Assim como nas classes, na maioria dos casos no recomendvel tornar pu-
blic os campos de uma estrutura; no h como controlar os valores armazenados nos
campos public. Por exemplo, qualquer pessoa poderia configurar o valor de minutes
ou seconds com um valor maior que 60. Uma ideia melhor tornar os campos private
e fornecer sua estrutura com construtores e mtodos para inicializar e manipular esses
campos, como mostrado neste exemplo:
struct Time
{
private int hours, minutes, seconds;
...
public Time(int hh, int mm, int ss)
{
this.hours = hh % 24;
this.minutes = mm % 60;
this.seconds = ss % 60;
}

public int Hours()


{
return this.hours;
}
}

Nota Por padro, voc no pode utilizar muitos dos operadores comuns nos
seus prprios tipos-estrutura. Por exemplo, voc no pode empregar operadores
como o de igualdade (==) e o de desigualdade (!=) nas suas prprias variveis
de tipo-estrutura. No entanto, pode compar-las usando o mtodo predefinido
Equals() exposto por todas as estruturas e tambm pode declarar explicitamente
e implementar operadores para seus prprios tipos-estrutura. A sintaxe para
fazer isso ser abordada no Captulo 21, Consulta a dados na memria usando
expresses de consulta.

Ao copiar uma varivel do tipo-valor, voc obtm duas cpias do valor. Por outro
lado, ao copiar uma varivel do tipo-referncia, voc obtm duas referncias ao mes-
mo objeto. Em resumo, use estruturas para valores pequenos de dados para os quais
elas sejam to eficientes, ou quase to eficientes, para copiar o valor quanto seriam
para copiar um endereo. Utilize classes para dados mais complexos a fim de copiar
com eficincia.

_Livro_Sharp_Visual.indb 213 30/06/14 15:05


214 PARTE II O modelo de objetos do C#

Dica Utilize estruturas para implementar conceitos simples cujas caractersticas


principais so seus valores, em vez da funcionalidade que fornecem.

Entenda as diferenas entre estrutura e classe


Uma estrutura e uma classe so sintaticamente semelhantes, mas existem algumas
diferenas importantes. Vamos examinar algumas dessas variaes:
j Voc no pode declarar um construtor padro (um construtor sem parmetros)
para uma estrutura. O exemplo a seguir seria compilado se Time fosse uma clas-
se, mas, como Time uma estrutura, a compilao falha:
struct Time
{
public Time() { ... } // erro de tempo de compilao
...
}

A razo pela qual voc no pode declarar seu prprio construtor padro em
uma estrutura que o compilador sempre gera um. Em uma classe, o compila-
dor s gerar o construtor padro se voc no escrever seu prprio construtor. O
construtor padro gerado pelo compilador para uma estrutura sempre define os
campos como 0, false ou null assim como para uma classe. Portanto, voc deve
garantir que um valor de estrutura criado pelo construtor padro se comporte
logicamente e faa sentido com esses valores padro. Isso tem algumas ramifi-
caes que sero exploradas no prximo exerccio.
Voc pode inicializar os campos com valores diferentes, fornecendo um constru-
tor no padro. Contudo, quando faz isso, seu construtor no padro deve ini-
cializar explicitamente todos os campos de sua estrutura; a inicializao padro
no acontece mais. Se isso no for feito, ocorrer um erro de tempo de compi-
lao. Por exemplo, embora o exemplo seguinte fosse compilado e inicializasse
silenciosamente seconds como 0 se Time fosse uma classe, como Time uma
estrutura, a compilao falha:
struct Time
{
private int hours, minutes, seconds;
...
public Time(int hh, int mm)
{
this.hours = hh;
this.minutes = mm;
} // erro de tempo de compilao: seconds no inicializada
}

j Em uma classe, voc pode inicializar os campos de instncia no seu ponto de


declarao. Em uma estrutura, isso no possvel. O exemplo a seguir compilaria
se Time fosse uma classe, mas, como Time uma estrutura, ele causa um erro de
tempo de compilao:
struct Time
{
private int hours = 0; // erro de tempo de compilao

_Livro_Sharp_Visual.indb 214 30/06/14 15:05


CAPTULO 9 Como criar tipos-valor com enumeraes e estruturas 215

private int minutes;


private int seconds;
...
}

A tabela abaixo resume as principais diferenas entre uma estrutura e uma classe.

Pergunta Estrutura Classe


Esse um tipo-valor ou um Uma estrutura um Uma classe um
tipo-referncia? tipo-valor. tipo-referncia.
As instncias so colocadas na As instncias de estrutura so As instncias de classe so
pilha ou no heap? chamadas valores e residem chamadas objetos e so
na pilha. colocadas no heap.
Voc pode declarar um No. Sim.
construtor padro?
Se voc declarar seu Sim. No.
constru