Você está na página 1de 220

Conceitos

básicos do
desenvolvimento
de software

Official Academic Course


This page intentionally left blank
Microsoft® Official Academic Course

Conceitos básicos do
desenvolvimento de
software, exame 98-361
Créditos
EDITOR Bryan Gambrel
DIRETOR DE VENDAS Mitchell Beaton
GERENTE EXECUTIVO DE MARKETING Chris Ruel
GERENTE DE PRODUTOS SÊNIOR DA MICROSOFT Merrick Van Dongen da Microsoft Learning
ASSISTENTE DO PROGRAMA EDITORIAL Jennifer Lartz
GERENTE DE CONTEÚDO Micheline Frederick
EDITOR DE PRODUÇÃO Amy Weintraub
DIRETOR DE CRIAÇÃO Harry Nolan
DESIGNER DA CAPA Jim O’Shea
TECNOLOGIA E MÍDIA Tom Kulesa/Wendy Ashenberg
Foto da capa: Crédito: © Pgiam/iStockphoto
Este livro foi criado em Garamond pela Aptara, Inc. e impresso e veiculado pela Bind Rite Robbinsville.
A capa foi impressa pela Bind Rite Robbinsville.
Copyright © 2012 da John Wiley & Sons, Inc. Todos os direitos reservados.
Nenhuma parte desta publicação pode ser reproduzida, armazenada em sistema de recuperação ou transmitida sob
qualquer forma ou por qualquer meio eletrônico ou mecânico, fotocópia, gravação, digitalização ou outros (exceto
conforme permitido nas seções 107 ou 108 da lei de direitos autorais dos Estados Unidos publicada em 1976)
sem permissão prévia por escrito da Editora ou autorização mediante pagamento da taxa adequada por cópia para
a Copyright Clearance Center, Inc. – 222 Rosewood Drive, Danvers, MA 01923, site: www.copyright.com. As
solicitações de permissão feitas à Editora devem ser dirigidas ao Departamento de Permissões da John Wiley & Sons,
Inc. – 111 Rio Street, Hoboken, NJ 07030-5774, (201) 748-6011, fax: (201) 748-6008, site: http://www.wiley.com/go/
permissions.
Microsoft, ActiveX, Excel, InfoPath, Microsoft Press, MSDN, OneNote, Outlook, PivotChart, PivotTable, PowerPoint,
SharePoint, SQL Server, Visio, Visual Basic, Visual C#, Visual Studio, Windows, Windows 7, Windows Mobile,
Windows Server e Windows Vista são marcas registradas ou marcas comerciais da Microsoft Corporation nos Estados
Unidos e/ou em outros países. Outros nomes de produtos e empresas mencionados neste documento podem ser marcas
registradas de seus respectivos proprietários.
Os exemplos aqui mencionados de empresas, organizações, produtos, nomes de domínio, endereços de email,
logotipos, indivíduos, locais e eventos são fictícios. Nenhuma associação a empresa, organização, produto, nome de
domínio, endereço de email, logotipo, indivíduo, local ou evento real é intencional, nem deve ser inferida.
Este livro expressa as visões e opiniões do autor. As informações contidas neste livro são fornecidas sem nenhuma
garantia expressa, estatutária ou implícita. Os autores, a John Wiley & Sons, Inc., a Microsoft Corporation e todos
os revendedores e distribuidores envolvidos não serão responsabilizados por nenhum dano causado ou supostamente
causado direta ou indiretamente por este livro.
Fundada em 1807, a John Wiley & Sons, Inc. apresenta-se como uma valiosa fonte de conhecimento e compreensão
há mais de 200 anos, ajudando pessoas ao redor do mundo a atenderem às suas necessidades e atingirem suas metas.
Nossa empresa é baseada em princípios que incluem responsabilidade para com as comunidades que servimos e onde
vivemos e trabalhamos. Em 2008, lançamos uma Iniciativa de Cidadania Corporativa, um esforço global para atender
a desafios ambientais, sociais, econômicos e éticos que enfrentamos em nossos negócios. Entre as questões com as
quais estamos lidando, estão a redução do impacto de carbono das nossas operações, o estabelecimento de padrões de
especificação e suprimento de papel, a aplicação de uma conduta ética em nossos negócios e entre nossos fornecedores
e o suporte à comunidade e organizações de caridade. Para obter mais informações, visite nosso site: www.wiley.com/
go/citizenship.
ISBN 978-0-470-88911-4
Impresso nos Estados Unidos da América
10 9 8 7 6 5 4 3 2 1

www.wiley.com/college/microsoft ou ligue para o número de chamada gratuita: 1+(888) 764-7001


(somente Canadá e Estados Unidos)
Introduction | iii
CONTRATO DE LICENÇA DE USUÁRIO
FINAL DA WILEY PARA MOAC E-BOOK E
CONTEÚDO DO INSTRUTOR
Este é o Contrato de Licença de Usuário Final limitado da John Wiley and Sons, Inc. (“Wiley”), que rege o uso que você faz do
e-book do Curso Acadêmico Oficial da Microsoft (“MOAC e-Book”) pertencente à Wiley e o conteúdo relacionado (“Conteúdo
do Instrutor”). ACESSAR, BAIXAR OU USAR O MOAC E­BOOK OU O CONTEÚDO DO INSTRUTOR REPRESENTA SUA
ACEITAÇÃO DOS TERMOS E DAS CONDIÇÕES DESTE CONTRATO. SE VOCÊ NÃO ACEITÁ-LOS, NÃO ACESSE, BAIXE NEM
USE O MOAC E­BOOK NEM O CONTEÚDO DO INSTRUTOR.
Licença:
Por meio deste, a Wiley concede ao membro, instrutor ou aluno do Programa Microsoft IT Academy que exerce os direitos de
acordo com este contrato (“você”), e você aceita uma licença não exclusiva e intransferível para usar o MOAC e-Book e o
Conteúdo do Instrutor apenas mediante os seguintes termos e condições:
a. Você reconhece que os MOAC e-Books e o Conteúdo do Instrutor estão sendo licenciados a você por
um período limitado de tempo e seu uso está sujeito aos termos e às condições deste Contrato.
b. A seguir, há dois conjuntos separados de direitos de uso. Apenas um conjunto de direitos de uso se
aplicará a você.
i. Se você for um membro ativo do Programa Microsoft IT Academy:
1. que os MOAC e-Books devem ser usados apenas por seus instrutores e seus alunos.
2. Você só poderá baixar as cópias do título do MOAC e-Book aplicável necessárias para que seus instrutores
ensinem e os alunos participem da aula que está ensinando o título do MOAC e-Book aplicável.
3. Você só poderá distribuir os títulos do MOAC e-Book para seus instrutores ensinarem e seus alunos
participarem de uma de suas aulas que está ensinando o título do MOAC e-Book aplicável e somente por:
o email
o um dispositivo USB seguro diretamente para os dispositivos pessoais dos seus alunos
o um site protegido por senha ao qual somente seus instrutores e alunos têm acesso
4. Você só poderá distribuir o Conteúdo do Instrutor para seus instrutores para preparar e ministrar uma de
suas aulas ensinando o título do MOAC e-Book associado.
5. Antes de fornecer qualquer acesso a um MOAC e-Book, você notificará cada indivíduo de que eles só
podem acessar ou usar um MOAC e-Book se eles concordarem que o uso que eles fizerem do MOAC
e-Book cumprirá os seguintes termos:
o Eles só usarão o MOAC e-Book unicamente para seu treinamento pessoal,
o Eles só instalarão o MOAC e-Book em um dispositivo que eles possuírem ou controlarem,
o Eles não copiarão, modificarão, imprimirão, transmitirão, transferirão, publicarão, postarão, exibirão, se
vincularão a, encaminharão nem distribuirão o MOAC e-Book em todo nem em parte,
o Eles só usarão o título do MOAC e-Book durante a aula da qual eles ministrarão o título do MOAC
e-Book ou pelo período de 180 (cento e oitenta dias) dias, o que for maior. Depois deste período, eles
deverão excluir com segurança todas as cópias do título do MOAC e-Book em sua posse ou sob seu
controle e
o Seu uso dos títulos do MOAC e-Book também estará compatível com quaisquer termos, condições ou
licenças adicionais aplicáveis, que acompanham ou que estão incluídas no título do MOAC e-Book.
6. Antes de fornecer qualquer acesso a qualquer Conteúdo do Instrutor, você notificará cada instrutor de que
eles só poderão acessar ou usar o Conteúdo do Instrutor seeles concordarem que o uso que eles fizerem
do Conteúdo do Instrutor cumprirá os seguintes termos:
o Eles só poderão usar o Conteúdo do Instrutor exclusivamente para se prepararem e ministrarem sua
sessão de treinamento,
o Eles só instalarão o Conteúdo do Instrutor em um dispositivo que eles possuírem ou controlarem,
o Eles não copiarão, modificarão, imprimirão, transmitirão, transferirão, publicarão, postarão, exibirão, se
vincularão a, encaminharão nem distribuirão o Conteúdo do Instrutor em todo nem em parte,
iv | Contrato de licença de usuário final da wiley para moac e-book e conteúdo do instrutor

o Eles só usarão o Conteúdo do Instrutor durante a aula da qual eles


ministrarão o título do MOAC e-Book relacionado ou pelo período de 180
(cento e oitenta dias) dias, o que for maior. Depois deste período, eles
deverão excluir com segurança todas as cópias do título do Conteúdo do
Instrutor em sua posse ou sob seu controle e
o Seu uso do Conteúdo do Instrutor também estará compatível com quaisquer
termos, condições ou licenças adicionais aplicáveis, que acompanham ou
que estão incluídas no Conteúdo do Instrutor.
ii. ii. Se você for um aluno, você reconhece e concorda que:
1. Você está participando no momento da aula de membro do Programa IT Academy
que está ensinando o MOAC e-Book.
2. Usará somente os MOAC e-Books unicamente para seu treinamento pessoal.
3. Você só instalará o MOAC e-Book em um dispositivo que você possui ou controla.
4. Você não copiará, modificará, imprimirá, transmitirá, transferirá, publicará, postará,
exibirá, se vinculará a, encaminhará nem distribuirá o MOAC e-Book em todo nem
em parte.
5. Seu uso dos títulos do MOAC e-Book também estará compatível com quaisquer
termos, condições ou licenças adicionais aplicáveis, que acompanham ou que
estão incluídas no título do MOAC e-Book.
c. Exceto conforme expressamente autorizado na seção b acima, você não poderá carregar,
copiar, modificar, transmitir, transferir, fazer trabalhos derivativos de, encaminhar nem
distribuir nenhum MOAC e-Book ou Conteúdo do Instrutor em todo ou em parte, criar
por descompilação ou, de outra forma, criar o código-fonte de qualquer MOAC e-Book
ou Conteúdo do Instrutor. Você não poderá imprimir cópias de nenhum MOAC e-Book ou
Conteúdo do Instrutor em todo; no entanto, você poderá imprimir páginas simples ou seções
dos capítulos do MOAC e-Book especificamente para uso em sala de aula. Você não poderá
usar tudo nem uma parte do MOAC e-Book ou Conteúdo do Instrutor com finalidade de obter
lucro por meio da venda, revenda, empréstimo, transferência, contratação ou outra forma de
exploração do MOAC e-Book ou Conteúdo do Instrutor. Se você transferir a posse de qualquer
MOAC e-Book ou Conteúdo do Instrutor a um terceiro, sua licença será automaticamente
rescindida. A referida rescisão ocorrerá independentemente de qualquer recurso equitativo, civil
ou outros disponíveis para a Wiley.

d. Você poderá usar o título do MOAC e-Book e Conteúdo do Instrutor aplicável somente durante
a aula que está ensinando o título do MOAC e-Book específico ou pelo período de 180 (cento
e oitenta dias) dias, o que for maior. Depois deste período, você deverá excluir com segurança
todas as cópias do título do MOAC e-Book e Conteúdo do Instrutor em sua posse ou sob seu
controle.

e. OS MOAC E-BOOKS E CONTEÚDO DO INSTRUTOR SÃO LICENCIADOS “NO ESTADO EM


QUE SE ENCONTRAM” E “MEDIANTE DISPONIBILIDADE”, SEM GARANTIAS DE QUALQUER
NATUREZA.

f. Você reconhece que todos os direitos (incluindo, sem limitação, direitos autorais, patentes
e segredos comerciais) relacionados aos MOAC e-Books e ao Conteúdo do Instrutor são de
propridade única e exclusiva da Wiley e de seus licenciadores. A aceitação deste contrato
não torna você o proprietário dos MOAC e-Books e do Conteúdo do Instrutor, mas você terá
uma licença limitada para usar o MOAC e-Book e Conteúdo do Instrutor de acordo com
as disposições deste contrato. Você concorda em proteger o MOAC e-Book e Conteúdo do
Instrutor do uso, carregamento, download, reprodução ou distribuição não autorizado. Você
concorda ainda em não traduzir, descompilar, desmontar ou, de outra forma, fazer engenharia
reversa de qualquer MOAC e-Book ou Conteúdo do Instrutor. A Wiley reserva para si todos os
outros direitos que não foram expressamente concedidos a você neste contrato.
Prefácio da editora

A visão editorial da Wiley para a série Microsoft Official Academic Course é fornecer aos
alunos e instrutores as habilidades e o conhecimento necessários para eles utilizarem a
tecnologia da Microsoft de maneira eficiente em todos os aspectos de suas vidas pessoais
e profissionais. É preciso fornecer uma instrução de qualidade para ajudar tanto os
educadores quanto os alunos a obterem o máximo das ferramentas de software da Microsoft
e se tornarem mais produtivos. Assim sendo, nossa missão é tornar nossos programas
instrucionais companheiros educacionais confiáveis para a vida toda.
Para cumprir essa missão, a Wiley e a Microsoft estabeleceram uma parceria para
desenvolver programas educacionais da mais alta qualidade para profissionais da informação,
profissionais de TI e desenvolvedores. O material criado por essa parceria leva a marca
“Microsoft Official Academic Course”, garantindo a instrutores e alunos que o conteúdo
desses livros didáticos tenha total aprovação da Microsoft e os livros forneçam informações
e instruções de extrema qualidade sobre os produtos da Microsoft. Os livros didáticos do
Microsoft Official Academic Course são “oficiais” em mais de um sentido, eles compõem
o curso sancionado oficialmente para os membros do programa Microsoft IT Academy.
A série Microsoft Official Academic Course concentra-se no desenvolvimento da força de
trabalho. Esses programas destinam-se a alunos que desejam entrar na força de trabalho,
mudar de emprego ou embarcar em novas carreiras como profissionais da informação,
profissionais de TI e desenvolvedores. Os programas Microsoft Official Academic Course
atendem às necessidades dos alunos enfatizando cenários autênticos de local de trabalho
com vários projetos, exercícios, casos e avaliações.
Os Microsoft Official Academic Courses estão ligados a uma ampla pesquisa e análise de
tarefas de trabalho da Microsoft, a mesma pesquisa e análise utilizada para criar os exames
MCITP (Microsoft Certified Information Technology Professional). Os livros didáticos têm
como foco habilidades reais para trabalhos reais. Como os alunos trabalham por meio de
projetos e exercícios nos livros, eles aprimoram seu nível de conhecimento e sua capacidade
de aplicar a tecnologia mais recente da Microsoft às tarefas do dia a dia. Esses alunos
também recebem credenciais que agregam valor ao currículo e podem ajudá-los a encontrar
um emprego, manter o emprego atual ou dar continuidade à sua formação.
Atualmente, o conceito de aprendizado contínuo é uma necessidade primordial. As funções
de trabalho, e até categorias inteiras de trabalho, estão mudando tão rápido que nenhum de
nós consegue se manter competitivo e produtivo sem atualizar continuamente as habilidades
e capacidades. As ofertas do Microsoft Official Academic Course, e seu foco na preparação
para o exame de certificação da Microsoft, fornecem um meio para as pessoas adquirirem
e atualizarem suas habilidades e seu conhecimento de forma eficiente. A Wiley ajuda os
alunos nessa investida por meio do desenvolvimento e da distribuição dos cursos como a
editora acadêmica oficial da Microsoft.
Hoje, a editoração educacional exige atenção para fornecer não só uma impressão de
qualidade, mas também conteúdo eletrônico robusto. Com a integração dos produtos do
Microsoft Official Academic Course, da WileyPLUS e das certificações da Microsoft,
estamos mais bem preparados para fornecer a alunos e professores soluções eficientes de
aprendizado.

Bonnie Lieberman
Gerente geral e vice-presidente sênior

www.wiley.com/college/microsoft ou ligue para o número de chamada gratuita: 1+(888) 764-7001


(somente Canadá e Estados Unidos) | v
Prefácio

Bem-vindo ao programa Microsoft Official Academic Course (MOAC) para Conceitos


básicos do desenvolvimento de software. O MOAC representa a colaboração entre a
Microsoft Learning e a editora John Wiley & Sons, Inc. A Microsoft e a Wiley uniram-
se para produzir uma série de livros didáticos que fornece soluções de ensino atraentes e
inovadoras para os instrutores e experiências de aprendizado excepcionais para os alunos.
Imbuídos e informados pelo conhecimento profundo dos criadores dos produtos da Microsoft
e compilados por uma editora reconhecida mundialmente pela qualidade pedagógica de
seus produtos, esses livros didáticos maximizam a transferência de habilidades em tempo
recorde. Os alunos são desafiados a atingir todo seu potencial utilizando suas novas
habilidades técnicas como membros altamente produtivos da força de trabalho.
Como essa base de conhecimentos vem diretamente da Microsoft, criadora dos exames
Microsoft Certified Technology Specialist (MCTS), Microsoft Certified Professional
(MCP) e Microsoft Technology Associate (MTA) (https://www.microsoft.com/learning/
pt-br/default.aspx), você tem a garantia de que está recebendo a cobertura de tópicos mais
relevante para seu sucesso pessoal e profissional. A participação direta da Microsoft não
garante apenas que o conteúdo do livro didático do MOAC é preciso e atual, ela também
significa que você receberá a melhor instrução possível para obter sucesso nos exames de
certificação e no local de trabalho.
■ O programa Microsoft Official Academic Course
A série Microsoft Official Academic Course é um programa completo desenvolvido para
instrutores e instituições prepararem e ministrarem cursos excepcionais sobre as tecnologias
de software da Microsoft. Com o MOAC, reconhecemos que, devido ao ritmo acelerado
das mudanças na tecnologia e no currículo desenvolvido pela Microsoft, há um conjunto
contínuo de qualificações, além das ferramentas de instrução de sala de aula, que um
instrutor precisa ter para estar apto a ministrar o curso. O programa MOAC empenha-se
para fornecer soluções que cubram todas essas qualificações de forma sistemática para
garantir uma experiência de curso recompensadora e bem-sucedida tanto para o instrutor
quanto para o aluno – treinamento técnico e de currículo para preparar o instrutor e torná-lo
apto a trabalhar com as novas versões de software; o software em si para o aluno utilizar
em casa e desenvolver habilidades práticas; avaliações; validação do desenvolvimento de
habilidades; e um grande conjunto de ferramentas para fornecer instruções na sala de aula e
no laboratório. Todos esses elementos são importantes para garantir a entrega de um curso
interessante sobre os programas de software da Microsoft, e todos eles são fornecidos com o
programa MOAC. Pensamos no modelo abaixo como um medidor para garantir que estamos
lhe dando suporte total para você atingir seu objetivo: ministrar um curso excepcional. Ao
avaliar suas opções de material instrucional, talvez seja interessante utilizar este modelo
para compará-lo com os produtos disponíveis:

www.wiley.com/college/microsoft ou ligue para o número de chamada gratuita: 1+(888) 764-7001


vi | (somente Canadá e Estados Unidos)
Tour ilustrado pelo livro

■ Recursos pedagógicos
O livro didático do MOAC para Conceitos básicos de desenvolvimento de software foi
elaborado para cobrir todos os objetivos de aprendizado do exame MTA 98-361, que é
chamado de “objetivo do exame”. Os objetivos do exame MTA (Microsoft Technology
Associate) são destacados ao longo do livro didático. Muitos recursos pedagógicos foram
desenvolvidos especificamente para o programa Microsoft Official Academic Course.
A apresentação de informações processuais e conceitos técnicos detalhados distribuídos
ao longo do livro aumenta os desafios, tanto para o aluno quanto para o instrutor. O tour
ilustrado pelo livro, mostrado a seguir, fornece um guia para os recursos avançados que
contribuem para o plano pedagógico do programa Microsoft Official Academic Course.
A seguir, temos uma lista dos principais recursos em cada lição projetada para preparar
os alunos para o sucesso enquanto dão continuidade à sua formação de TI, nos exames de
certificação e no local de trabalho.
• Cada lição começa com uma Matriz de habilidades da lição. Mais do que uma lista
padrão dos objetivos de aprendizado, a Matriz de habilidades da lição correlaciona
cada habilidade de software abordada na lição com o objetivo específico do exame.
• Exercícios passo a passo concisos e frequentes ensinam os alunos a utilizar novos
recursos e lhes oferecem a oportunidade de praticar o que foi aprendido. Etapas
numeradas fornecem instruções passo a passo detalhadas para ajudar os alunos a
desenvolver habilidades de software.
• Ilustrações– mais especificamente, imagens de tela, fornecem feedback visual
enquanto os alunos trabalham nos exercícios. As imagens reforçam conceitos
importantes, fornecem dicas visuais sobre as etapas e permitem que os alunos
verifiquem o seu progresso.
• Listas dos Principais termos são exibidas no começo de cada lição apresentando aos
alunos um vocabulário técnico importante. Esses termos são exibidos em negrito e
itálico na parte da lição em que são definidos.
• Auxílios ao leitor pontuais e envolventes, localizados em todas as lições, informam
aos alunos por que o tópico é relevante (O resultado) e fornecem dicas úteis (Tome
nota). Os Auxílios ao leitor também oferecem informações adicionais relevantes ou de
plano de fundo que agregam valor à lição.
• Os recursos Pronto para certificação ao longo do texto indicam aos alunos onde
um objetivo específico de certificação é abordado. Eles permitem que os alunos
verifiquem se entenderam um objetivo específico de MTA e, se necessário, revisem a
seção da lição na qual esse objetivo foi abordado. O MOAC oferece preparação total
para a certificação MTA.
• Perguntas no final das lições: a seção Avaliação de conhecimento fornece várias
perguntas de múltipla escolha, verdadeiro ou falso, correspondência e preenchimento
de lacunas.
• Exercícios no final das lições: os cenários de caso das seções Avaliação de competência
e Avaliação de proficiência e os exercícios de Local de trabalho pronto são projetos que
testam a capacidade de os alunos aplicarem o que aprenderam na lição.

www.wiley.com/college/microsoft ou ligue para o número de chamada gratuita: 1+(888) 764-7001 (somente Canadá e
Estados Unidos) | vii
viii | Tour ilustrado pelo livro

■ Recursos da lição

2 LIÇÃO
Introdução à
programação
orientada a objeto
M AT R I Z D E H A B I L I D A D E S D A L I Ç Ã O
Matriz de habilidades da lição
Habilidades/Conceitos Objetivo do exame MTA Número do objetivo do
exame MTA
Noções básicas sobre objetos Compreender os conceitos 2,1
básicos de classes.
Noções básicas sobre Compreender o armazenamento do 1,1
valores e referências computador e os tipos de dados.
Noções básicas sobre Compreender o encapsulamento. 2,4
encapsulamento
Noções básicas sobre herança Compreender a herança. 2,2
Noções básicas sobre polimorfismo Compreender o polimorfismo. 2,3
Noções básicas sobre interfaces Compreender o encapsulamento. 2,4

P R I N C I PA I S T E R M O S
modificador de acesso encapsulamento polimorfismo
acessadores eventos propriedades
classes abstratas
propriedades autoimplementadas
herança
interfaces
tipo de referência
classes seladas
Principais Introdução à programação | 3

classe
construtores
método
namespace
assinatura
números de estáticos
termos Por exemplo, a figura 1-1 mostra um fluxograma que insere dois números, compara-os
e gera a saída do maior número.
delegados objetos tipo de valor

Você é um desenvolvedor de software da Northwind Corporation. Você trabalha


como parte de uma equipe para desenvolver programas de computador que Figura 1-1
solucionam problemas empresariais complexos. Todos os programas que você Um fluxograma simples que
escreve devem ser fáceis de compreender e manter por um longo período. Portanto, compara dois números e gera
você precisa desenvolver programas usando técnicas que incentivem a colaboração, a saída do maior dos dois
a extensibilidade e a reutilização de código. Além disso, em vez de pensar em seus
programas principalmente como listas de métodos, você opta por modelá-los em
conceitos de negócios do mundo real, como clientes, produtos, fornecedores e as
interações entre eles.

32

Diagramas
Auxílio ao leitor de informativos
referência cruzada
Introdução à programação | 9
Como você pode ver, esse fluxograma lista todas as etapas necessárias na ordem correta
REFERÊNCIA C# fornece vários tipos de dados internos que você pode usar nos seus programas. Você para executar a operação. O fluxo de controle começa com o símbolo Iniciar e termina
CRUZADA
também pode definir novos tipos, especificando uma estrutura de dados, como uma classe
ou um struct. Este capítulo se concentra em alguns tipos de dados internos mais usados com o símbolo Parar. O processo e os símbolos das operações de entrada/saída sempre
Você poderá encontrar
mais informações com frequência. têm uma única entrada e uma única saída. Por outro lado, o símbolo de decisão tem uma
sobre como criar seus A tabela 1-3 lista vários tipos de dados internos usados com frequência e disponíveis única entrada, mas várias saídas. Você pode testar um fluxograma, executando um teste
próprios tipos de dados em C#. Os tamanhos listados na tabela referem-se a um computador que executa completo. Nesse tipo de teste, você rastreia manualmente as etapas do fluxograma com
na lição 2. um sistema operacional de 32 bits, como o Windows 7 de 32 bits. Para um sistema os dados de teste para verificar se os caminhos corretos estão sendo seguidos.
operacional de 64 bits, como o Windows 7 de 64 bits, esses tamanhos serão diferentes.

Tabela 1-3 INTRODUÇÃO ÀS TABELAS DE DECISÃO


Tipos de dados internos Tipo de dados Tamanho Intervalo de valores Quando um algoritmo envolve inúmeras condições, as tabelas de decisão estão em um
usados com frequência em C# formato mais compacto e legível para a apresentação do algoritmo. A tabela 1-2 apresenta
byte 1 byte 0 a 255
uma tabela de decisões para calcular um desconto. Essa tabela gera uma porcentagem
char 2 bytes U+0000 a U+ffff (caracteres Unicode)
de desconto dependendo da quantidade de produto adquirido. As linhas em negrito da
short 2 bytes −32,768 to 32,767 tabela de decisões dividem a tabela em quatro quadrantes. O primeiro quadrante (superior
Int 4 bytes −2,147,483,648 to 2,147,483,647 esquerdo) especifica as condições (“Quantidade < 10” etc.). O segundo quadrante
long 8 bytes −9,223,372,036,854,775,808 to (superior direito) especifica as regras. As regras são as combinações possíveis dos
9,223,372,036,854,775,807 resultados de cada condição. O terceiro quadrante (inferior esquerdo) especifica a ação
float 4 bytes ±1.5 × 10-45 a ±3.4 × 1038 (“Desconto” neste caso), e o último quadrante (inferior direito) especifica os itens de ação
correspondentes a cada regra.
double 8 bytes ±5.0e−324 a ±1.7e308
TOME NOTA
* bool 2 bytes True ou false
As versões sem sinal
de short, int e long são string - Zero ou mais caracteres Unicode
ushort, uint e ulong,
respectivamente.
Os tipos sem sinal têm Todos os tipos de dados listados na tabela 1-3 são tipos de valor, exceto string, que é um
o mesmo tamanho tipo de referência. As variáveis que são baseadas diretamente nos tipos de valor contêm
que suas versões com o valor. No caso do tipo de referência, a variável contém o endereço do local de memória
sinal, mas armazenam onde estão armazenados os dados reais. Você aprenderá mais sobre as diferenças entre
muito mais intervalos tipos de valor e tipos de referência na lição 2.
de valores somente
positivos.
NOÇÕES BÁSICAS SOBRE MATRIZES

Uma matriz é uma coleção de itens em que cada item pode ser acessado por um
índice exclusivo.

Uma matriz em C# é normalmente usada para representar uma coleção de itens de tipo
semelhante. Uma declaração de matriz de exemplo é mostrada no código a seguir:
int[] numbers = { 1, 2, 3, 4, 5 };
Essa declaração cria uma matriz identificada pelos números de nome. Essa matriz é capaz
de armazenar uma coleção de cinco números inteiros. Essa declaração também inicializa
cada um dos itens de matriz respectivamente pelos números 1 a 5.
Qualquer item de matriz pode ser diretamente acessado usando um índice. No .NET
Framework, os índices de matriz são de base zero. Isso significa que, para acessar
o primeiro elemento de uma matriz, você usa o índice 1; para acessar o segundo
elemento, você usa o índice 2 e assim por diante.
Para acessar um elemento de matriz individual, você usa o nome da matriz seguido
do índice entre colchetes. Por exemplo, numbers[0] retornará o valor 1 da matriz
declarado acima, e numbers[4] retornará o valor 5. É inválido acessar uma matriz fora

www.wiley.com/college/microsoft ou ligue para o número de chamada gratuita: 1+(888) 764-7001 (somente Canadá e Estados Unidos)
Tour ilustrado pelo livro | ix

44 | lição 2

2. Modifique o código da classe Program para:


class Program
{
static void Main(string[] args)
{
Rectangle rect = new Rectangle
{ Length = 10.0, Width = 20.0 };
Console.WriteLine(“Nome da forma: {0}, Area: {1}”,
Rectangle.ShapeName,
rect.GetArea());
}
}
3. Selecione Depurar > Iniciar sem Depuração. Uma janela de console será exibida
mostrando o nome e a área da forma.
4. SALVE seu projeto.
PAUSE. Deixe o projeto aberto para ser usado no próximo exercício.
Quando uma instância de uma classe é criada, uma cópia separada é criada para cada
campo de instância, mas apenas uma cópia de um campo estático é compartilhada por
PRONTO PARA
todas as instâncias.
CERTIFICAÇÃO Um membro estático não pode ser referenciado por meio de um objeto de instância.
Você compreende os Em vez disso, um membro estático é referenciado através do nome de classe (como
conceitos básicos das Rectangle.ShapeName no exercício acima). Observe que não é possível usar a referência
classes? de palavra-chave this com uma propriedade ou um método estático, pois a palavra-chave
2,1 this só pode ser usada para acessar objetos de instância.

■ Noções básicas sobre valores e referências

O RESULTADO
Um tipo de valor armazena diretamente um valor, ao passo que um tipo de referência
armazena apenas uma referência a um valor real. Auxílio ao leitor “O resultado”
Um tipo de valor armazena dados diretamente na própria memória. Por outro lado,
os tipos de referência armazenam apenas uma referência a um local de memória;
aqui, os dados reais são armazenados no local de memória que está sendo referenciado.
A maioria dos tipos de dados elementares internos (como bool, int, char, double etc.) 4 | Lição 1
são tipos de valor. Os tipos de dados definidos pelo usuário criados com a palavra-chave
struct também são tipos de valor. Os tipos de referência incluem os tipos criados com
as palavras-chave object, string, interface, delegate e class. Tabela 1-2
Uma tabela de decisões para Quantidade < 10 S N N N
Noções básicas sobre structs calcular descontos
Quantidade < 50 S S N N
A palavra-chave struct é usada para criar tipos definidos pelo usuário que consistem Quantidade < 100 S S S N
em pequenos grupos de campos relacionados. Os structs são tipos de valor — ao
contrário das classes, que são tipos de referência. Desconto 5% 10% 15% 20%

Os structs são definidos usando a palavra-chave struct, como mostrado abaixo:


Para descobrir qual item de ação aplicar, você deve avaliar cada condição para encontrar
public struct Point a regra de correspondência e, em seguida, escolher a ação especificada na coluna com
{ a regra de correspondência. Por exemplo, se o valor de “Quantidade” nos dados de teste
public double X, Y; for 75, a primeira regra resultará em “Não”, a segunda regra resultará em “Não”,
} e a terceira regra resultará em “Sim”. Portanto, você escolherá o item de ação da coluna
(N, N e S), que define o desconto de 15%.
Os structs podem conter a maioria dos elementos contidos pelas classes, como construtores,
métodos, propriedades etc. No entanto, como você aprenderá na próxima seção, os structs
Introdução ao C#
C# é uma linguagem de programação popular de alto nível que lhe permite escrever
programas de computador em um formato que pode ser compreendido pelo usuário.
C# é uma parte do .NET Framework e se beneficia do suporte ao tempo de execução
e das bibliotecas de classe fornecidas pelo .Framework.

Conforme discutido na seção anterior, os computadores precisam de instruções precisas


e completas para realizar uma tarefa. Esses conjuntos de instruções são denominados
programas de computador ou simplesmente programas para abreviar.
No nível mais básico, os computadores usam o sistema de número binário para
representar informações e código. Nesse sistema, cada valor é representado usando
apenas dois símbolos, 0 e 1. Um programa de computador escrito usando o sistema
de número binário é denominado código binário.
O uso de um código binário para programar um computador é conciso e extremamente
difícil de executar para qualquer tarefa não trivial. Portanto, para simplificar
Noções básicas sobre o desenvolvimento de software em geral | 77 a programação, cientistas e engenheiros de computador compilaram vários níveis
de abstrações entre computadores e seus operadores humanos. Essas abstrações incluem
software (como sistemas operacionais, compiladores e vários sistemas de tempo
O BubbleSort compara dois elementos para verificar se estão fora de ordem; se estiverem de execução) que assumem a responsabilidade pela conversão de um programa que
ele os trocará. O algoritmo continuará fazendo isso até que toda a lista esteja na ordem pode ser compreendido pelo usuário em um programa legível por máquina.
desejada. O BubbleSort recebe esse nome pelo modo que o algoritmo funciona: durante
Os programas mais modernos são escritos uma linguagem de alto nível, como C#,
a execução do algoritmo, os itens menores são “flutuados” para cima. Visual Basic ou Java. Essas linguagens permitem que você escreva instruções precisas
Vamos visualizar BubbleSort com a ajuda de um exemplo. Vamos supor que você queira em um formato que pode ser compreendido pelo usuário. Em seguida, um compilador
organizar todos os itens da lista a seguir em ordem crescente: (20, 30, 10, 40). Esses itens de linguagem converte a linguagem de alto nível em uma linguagem de nível inferior
que pode ser entendida pelo sistema de execução de tempo de execução.
devem ser organizados do menor para o maior. O algoritmo BubbleSort tenta solucionar
esse problema em um ou mais passos, com cada passo examinando completamente a lista Cada linguagem de programação fornece seu próprio conjunto de vocabulário e gramática
de itens. Se o algoritmo encontrar elementos fora de ordem, ele os trocará. O algoritmo (também conhecido como sintaxe). Neste curso, você aprenderá a programar usando
a linguagem de programação C# no .NET Framework. O .NET Framework fornece
termina quando ele examina a lista inteira sem trocar qualquer elemento. Se não houvesse um ambiente de execução em tempo de execução para o programa C#. O Framework
nenhuma permuta, nenhum dos elementos estariam fora de ordem e a lista teria sido também contém bibliotecas de classes que fornecem inúmeras funcionalidades essenciais
completamente classificada. reutilizáveis que você pode usar diretamente no seu programa C#.
MAIS INFORMAÇÕES
O .NET Framework fornece três componentes principais: um ambiente de execução de tempo
Tabela 3-1
Tabelas
de execução, um conjunto de bibliotecas de classe que fornecem uma grande quantidade de
Primeira passagem de Etapa Antes Depois Comentários funcionalidades reutilizável e compiladores de linguagem para C#, Visual Basic e Managed C++.
BubbleSort O .NET Framework oferece suporte a várias linguagens de programação e também tem suporte para

fáceis de ler
1 20, 30, 10, 40 20, 30, 10, 40 O algoritmo compara os dois primeiros adicionar outras linguagens ao sistema. Embora a sintaxe e o vocabulário de cada linguagem possam
elementos (20 e 30); como eles estão ser diferentes, cada uma ainda poderá usar as bibliotecas de classe base fornecidas pelo Framework.
na ordem correta, nenhuma permuta
é necessária.
2 20, 30, 10, 40 20, 10, 30, 40 O algoritmo compara os dois
elementos seguintes (30 e 10);
como eles estão fora de ordem, Auxílio ao leitor
os elementos são trocados.
3 20, 10, 30, 40 20, 10, 30, 40 O algoritmo compara os dois “Mais informações”
elementos seguintes (30 e 40); como
eles estão na ordem correta, nenhuma
permuta é necessária.

Conforme mostra a tabela 3-1, no final da primeira passagem, BubbleSort realizou uma
permuta, e é possível que os itens ainda não estejam totalmente classificados. Portanto,
BubbleSort dá uma outra passagem na lista, conforme ilustrado na tabela 3-2.

Tabela 3-2
Segunda passagem de Etapa Antes Depois Comentários
BubbleSort
1 20, 10, 30, 40 10, 20, 30, 40 O algoritmo compara os dois primeiros
elementos (20 e 10); como eles estão
fora de ordem, os elementos são
trocados.
2 10, 20, 30, 40 10, 20, 30, 40 O algoritmo compara os dois
elementos seguintes (20 e 30); como
eles estão na ordem correta, nenhuma
permuta é necessária.
3 10, 20, 30, 40 10, 20, 30, 40 O algoritmo compara os dois
elementos seguintes (30 e 40); como
eles estão na ordem correta, nenhuma
permuta é necessária.

www.wiley.com/college/microsoft ou ligue para www.wiley.com/college/microsoft


o número de chamada gratuita: 1+(888)
ou 764-7001 (somente Canadá e Estados Unidos)
ligue para o número de chamada gratuita: 1+(888) 764-7001 (somente Canadá e Estados Unidos)
x | Tour
Lesson
ilustrado
1 pelo livro

68 | lição 3

Noções básicas sobre teste de software


O teste de software verifica se a implementação corresponde aos requisitos do sistema.

O teste de software é usado para assegurar a qualidade do produto final. O teste pode
identificar possíveis lacunas entre as expectativas em relação ao sistema descritas no
documento de requisitos e o comportamento real do sistema.
Entre os participantes mais críticos na atividade de teste de software estão os testadores
que verificam o aplicativo em execução para se certificar de que ele atende aos requisitos
identificados. Quando esses testadores identificam qualquer falha no aplicativo, eles
atribuem cada falha a uma pessoa apropriada que possa consertá-la. Por exemplo, uma
falha de código seria atribuída de volta a um desenvolvedor para que ele (ou ela) possa
remediar o erro.

Noções básicas sobre gerenciamento de lançamento


A atividade de gerenciamento de lançamento é usada para gerenciar a implantação,
a entrega e o suporte das versões de software.

O gerenciamento de lançamento inclui atividades, como empacotamento e implantação


do software, gerenciamento de defeitos do software e gerenciamento das solicitações de
alteração do software.
Os principais players da atividade de gerenciamento de lançamento incluem estes
indivíduos:
• Gerente de lançamento: o gerente de lançamento coordena várias equipes e unidades
de negócios para garantir o lançamento em tempo hábil de um produto de software.
• Equipe de operação: os membros da equipe de operação garantem que o sistema
seja entregue conforme prometido. Isso pode envolver a gravação de DVDs
PRONTO PARA
e sua remessa à medida que os pedidos forem sendo recebidos ou pode implicar
CERTIFICAÇÃO a manutenção de um sistema SaaS (software como serviço) de forma contínua.
Você compreende A equipe de operação também é responsável por liberar qualquer atualização de
o que significa sistema (por exemplo, correções de bugs ou novos recursos).
gerenciamento do ciclo • Equipe de suporte técnico: esses funcionários interagem com os clientes e ajudam
de vida do aplicativo a solucionar seus problemas com o sistema. O suporte técnico pode gerar métricas
e suas atividades?
valiosas sobre quais áreas do sistema apresentam mais dificuldade para os usuários
3,1
e possivelmente precisarão ser atualizadas na próxima versão do aplicativo.

■ Noções básicas sobre testes

O teste de software é o processo de verificação do software com base em seus


requisitos. O teste ocorre depois que a maior parte do trabalho de desenvolvimento
Exercícios passo a passo
O RESULTADO
é concluída.
46 | lição 2
Conforme mencionado anteriormente, o teste de software é o processo que verifica se um
software funciona conforme esperado e atende a todos os requisitos comerciais e técnicos.
Quando há uma diferença entre o comportamento esperado e o comportamento real do nome da variável, o tempo de execução saberá que seu conteúdo não está armazenado na
sistema, uma falha de software (ou um “bug”) é registrada e finalmente passada para um variável, mas no local de memória apontado pela variável.
indivíduo responsável por consertá-la.
O teste de software pode envolver testes funcionais e não funcionais. O teste funcional COPIAR VALOR E TIPOS DE REFERÊNCIA
está relacionado aos requisitos funcionais do sistema e testa os recursos que constituem
USE o projeto que você salvou no exercício anterior para executar as etapas a seguir:
1. Adicione o código a seguir após a definição da classe Rectangle para criar um struct
Point:

Alerta “Pronto para struct Point


{
*
certificação”
TOME NOTA
public double X, Y;
Auxílio É possível criar um
struct sem usar o
}
operador new. Você 2. Modifique o código do método Main como mostrado abaixo:
ao leitor pode simplesmente
dizer Point p1; para
static void Main(string[] args)
{
“Tome nota” criar uma variável do
tipo struct. Point p1 = new Point();
p1.X = 10;
p1.Y = 20;
Point p2 = p1;
p2.X = 100;
Console.WriteLine(“p1.X = {0}”, p1.X);
Introdução à programação | 7
Rectangle rect1 = new Rectangle
{ Length = 10.0, Width = 20.0 };
Figura 1-3
Rectangle rect2 = rect1;
Listagem de programa com
números de linha
TOME NOTA
* rect2.Length = 100.0;
Quando você copia
Console.WriteLine(“rect1.Length = {0}”,
uma variável de tipo
de referência para rect1.Length);

Imagens
outra variável do }
mesmo tipo, apenas
as referências são 3. Selecione Depurar > Iniciar sem Depuração. Uma janela de console será exibida
mostrando os valores de p1.X e rect1.Length.
de tela copiadas. Como
resultado, após
a cópia, as duas
4. SALVE seu projeto.
PAUSE. Deixe o projeto aberto para ser usado no próximo exercício.
variáveis apontarão
para o mesmo objeto. Aqui, a primeira parte do programa cria uma cópia do tipo de valor Point, e a segunda
metade cria uma cópia do tipo de referência Rectangle.
Vamos começar analisando como a cópia de um tipo de valor é feita. Para começar,
quando a instrução a seguir for executada, uma nova variável p2 será criada na memória,
e seu conteúdo será copiado a partir da variável p1:
Point p2 = p1;
Após a execução dessa instrução, a variável p2 será criada, e o conteúdo da variável p1
será copiado para a variável p2. Tanto p1 quanto p2 têm seu próprio conjunto de valores
disponíveis em seus respectivos locais de memória. Portanto, quando a instrução a seguir
for executada:
p2.X = 100;
Um programa C# é composto por uma ou mais classes. Uma classe é um conjunto
de dados e métodos. Por exemplo, o código da figura 1-3 define uma única classe Ela só afetará o valor de X correspondente ao local de memória da variável p2. O valor de
REFERÊNCIA denominada Program nas linhas de 5 a 11. Uma classe é definida usando a palavra-chave X para a variável p1 permanece inalterado.
CRUZADA class, seguida pelo nome de classe. O conteúdo de uma classe é definido entre uma chave
de abertura ({) e uma chave de fechamento (}).
Você poderá encontrar
mais informações sobre A linha 3 do código na figura 1-3 define um namespace, Lesson01. Os namespaces são
classes na lição 2. usados para organizar classes e identificá-las com exclusividade. O namespace e os nomes
de classe são combinados para criar um nome de classe totalmente qualificado. Por
exemplo, o nome de classe totalmente qualificado da classe Program é Lesson01.Program.
C# requer que o nome totalmente qualificado de uma classe seja exclusivo. Como
resultado, você não poderá ter outra classe com nome Program no namespace Lesson01,
mas poderá ter uma classe com nome Program em outro namespace, por exemplo,
Lesson02. Aqui, a classe Program definida no namespace Lesson02 é identificada
exclusivamente pelo seu nome de classe totalmente qualificado, Lesson02.Program.
REFERÊNCIA O .NET Framework fornece inúmeras classes úteis, organizadas em vários namespaces.
CRUZADA
O namespace System contém algumas das classes base usadas com mais frequência.
Você poderá encontrar Uma classe desse tipo no namespace System é Console. A classe Console fornece
mais informações sobre funcionalidade de entrada e saída do aplicativo de console. A linha 9 do código na figura
métodos na lição 2. 1-3 refere-se à classe Console e chama seu método WriteLine. Para acessar o método
WriteLine de forma inequívoca, você deve escrevê-lo desta forma:
System.Console.WriteLine(“olá, mundo”);
TOME NOTA
* Como os nomes de classe aparecem com frequência no código, escrever sempre o nome
de classe totalmente qualificado será entediante e tornará o programa muito detalhado.
Cada instrução C#
Você pode solucionar esse problema usando a diretiva C# using (consulte o código
deve terminar com na linha 1 da figura 1-3). A diretiva using permite que você use as classes em um
ponto-e-vírgula (;). namespace sem precisar qualificar totalmente o nome de classe.
A classe Program define um único método pelo nome Main (consulte as linhas 7 a 10
da listagem de código na figura 1-3). Main é um método especial, pois também serve
como um ponto de entrada para o programa. Quando o tempo de execução executa um

www.wiley.com/college/microsoft ou ligue para o número de chamada gratuita: 1+(888) 764-7001 (somente Canadá e Estados Unidos)
Tour ilustrado pelo livro | xi

Noções básicas sobre o desenvolvimento de software em geral | 69

a funcionalidade essencial do sistema. Por exemplo, testar se os usuários podem adicionar


itens a um carrinho de compras é uma parte importante do teste funcional de um site
de comércio eletrônico. Em comparação, os testes não funcionais envolvem testes dos
atributos de software que não fazem parte da funcionalidade essencial, mas fazem parte
de requisitos não funcionais do software, como escalabilidade, usabilidade, segurança.

É importante observar que o processo de teste de software somente pode ajudar a


encontrar falhas, ele não pode garantir a ausência de falhas. Um software complexo tem
TOME NOTA
* um número imenso de caminhos de execução possíveis e vários parâmetros que podem
afetar seu comportamento. Não é viável e muitas vezes não é possível testar todas as Auxílio ao leitor
“Tome nota”
situações diferentes que esse software encontrará em um ambiente de produção.

Noções básicas sobre métodos de teste

Os métodos de teste de software são geralmente divididos em duas categorias: teste


caixa branca e teste caixa preta.

Tradicionalmente, há duas abordagens amplas para os testes de software:


• Teste caixa preta
• Teste caixa branca
O teste caixa preta trata o software como uma caixa preta, concentrando-se exclusivamente
em entradas e saídas. Com essa abordagem, qualquer conhecimento do funcionamento
interno do sistema não é utilizado durante o teste. Por outro lado, com o teste caixa branca,
os testadores usam seu conhecimento da estrutura interna do sistema ao testarem o sistema.
Por exemplo, no teste caixa branca, os testadores têm acesso ao código-fonte.
Essas duas técnicas de teste se complementam. Na maioria das vezes, o teste caixa preta
é usado para garantir que um software atenda a todos os seus requisitos, ao passo que
o teste caixa branca é usado para garantir que cada método ou função tenha casos de teste
adequados disponíveis.

Noções básicas sobre os níveis de teste Resumo de habilidades


O teste é executado em várias fases do ciclo de vida de desenvolvimento do
aplicativo. Diferentes níveis de teste especificam em que parte no ciclo de vida um
teste específico ocorre, bem como que tipo de teste está sendo executado.
Noções básicas sobre bancos de dados | 173

Os níveis de teste são definidos pela parte em que os testes ocorrem no ciclo de vida RESUMO DE HABILIDADES
de desenvolvimento do software. Há cinco níveis distintos de teste:
• Teste de unidade: o teste de unidade verifica a funcionalidade de uma unidade de Nesta lição, você aprendeu que:
código. Por exemplo, uma unidade de teste pode avaliar se um método retorna o valor
• Um banco de dados relacional organiza as informações em tabelas. Uma tabela
correto. O teste de unidade é um teste caixa branca e é realizado com frequência pelo
é uma lista de linhas e colunas.
desenvolvedor que está escrevendo o código. O teste de unidade muitas vezes usa
• Um design de banco de dados relacional é o processo que determina a estrutura de
uma ferramenta automatizada que pode simplificar o desenvolvimento dos casos e banco de dados relacional adequada para atender aos requisitos comerciais.
também acompanhar se uma modificação do código causa a falha de qualquer um • Os diagramas de relacionamento entre entidades são usados para modelar as
dos testes de unidade existentes. O Visual Studio tem suporte interno para o teste de entidades, seus atributos e os relacionamentos entre as entidades. Esses diagramas
unidade. Você também pode usar ferramentas de software livre, como o NUnit, para de relacionamento entre entidades podem ajudá-lo a determinar quais dados
automatizar os testes de unidade para o código do .NET Framework. precisam ser armazenados em um banco de dados.
• Teste de integração: o teste de integração avalia a interface entre os componentes • O processo de normalização de dados garante que um design de banco de dados não
tenha problemas que possam levar à perda da integridade dos dados. A maioria dos
de software. O teste de integração pode ser executado de forma incremental enquanto problemas de design podem ser resolvidos, garantindo que as tabelas atendam aos
requisitos da terceira forma normal.
• A linguagem SQL linguagem fornece instruções, como SELECT, INSERT, UPDATE
e DELETE, para trabalharem com dados relacionais.
• Um procedimento armazenado é um conjunto de instruções SQL que são
armazenadas em um banco de dados. Os procedimentos armazenados podem ser
usados por vários aplicativos.
• As classes XmlReader e XmlWriter fornecem uma maneira rápida, sem
armazenamento em cache e somente de encaminhamento para ler ou gravar dados
XML. A classe XmlDocument é uma representação na memória de dados XML
e permite a navegação e a edição do documento XML.
• A classe DataSet é uma representação na memória de dados relacionais.
A classe DataAdapter funciona como ponte entre a fonte de dados e o DataSet.
O DataAdapter armazena a conexão de dados e os comandos de dados necessários
para se conectar à fonte de dados.

Avaliação de ■ Avaliação de conhecimento


64 | lição 2 conhecimento Preencha as lacunas
Complete as sentenças a seguir com a(s) palavra(s) correta(s) nas lacunas fornecidas.
1. Para que uma tabela esteja na _______________, nenhuma das colunas deve ter
■ Avaliação da competência vários valores na mesma linha de dados.
2. A _______________ exige que todas as colunas que não são de chave sejam
Cenário 2-1: criando propriedades funcionalmente dependentes de toda a chave primária.
Você precisa criar uma classe denominada Product que representa um produto. A classe tem 3. A _______________ exige que não haja dependência funcional entre os atributos que
uma única propriedade denominada Name. Os usuários da classe Product devem ser capazes não são de chave.
de obter e também definir o valor da propriedade Name. No entanto, qualquer tentativa de
definir o valor de Name para uma cadeia de caracteres vazia ou um valor nulo deve gerar 4. Os blocos de construção básicos para um diagrama de relacionamento entre entidades
uma exceção. Além disso, os usuários da classe Product não devem ser capazes de acessar são _______________, _______________ e _______________.
nenhum outro membro de dados da classe Product. Como você criará essa classe? 5. A cláusula _______________ em uma instrução SELECT avalia cada linha para uma
condição e decide se deve incluí-la no conjunto de resultados.
Cenário 2-2: criando um struct 6. O objeto usado com a instrução using deve implementar a interface
Você está desenvolvendo um jogo que precisa representar o local de um destino no _______________.
espaço tridimensional. O local é identificado pelos três valores inteiros denotados por x, 7. A instrução _______________ de T-SQL pode ser usada para criar um procedimento
y e z. Você criará milhares dessas estruturas de dados em seu programa e precisa de uma armazenado.
maneira leve e eficiente de armazenar esses dados na memória. Além disso, é improvável
que você precise herdar qualquer outro tipo desse tipo de local. Como você deve
representar o local em seu programa?

■ Avaliação de proficiência
Cenário 2-1: substituindo o método ToString
Suponha que você esteja escrevendo um código para uma classe Product. A classe Product
contém o nome e o preço de um produto. Você precisa substituir o método ToString
da classe base (System.Object) para fornecer informações sobre os objetos da classe
de produto para o código de chamada. Qual código você precisa escrever para a classe
Product a fim de atender a esse requisito?

Cenário 2-2: criando e manipulando eventos


Imagine que você esteja escrevendo um código para criar e tratar eventos no seu programa.
Cenários de caso
A classe SampleClass precisa implementar a seguinte interface:
public delegate void SampleDelegate();
public interface ISampleEvents
{
event SampleDelegate SampleEvent;
void Invoke();
}
Você precisa escrever o código para SampleClass e para um método de teste que cria uma
instância de SampleClass e invoca o evento. Qual código você deve escrever?

www.wiley.com/college/microsoft ou ligue para o número de chamada gratuita: 1+(888) 764-7001 (somente Canadá e Estados Unidos)
Convenções e recursos
utilizados neste livro

Este livro utiliza fontes, símbolos e convenções de título específicos para destacar
informações importantes ou para chamar a atenção para etapas especiais. Para obter mais
informações sobre os recursos de cada lição, consulte a seção Tour ilustrado pelo livro.

Convenção Significado

Este recurso fornece um breve resumo do material coberto
na seção seguinte.
O RESULTADO

PRONTO PARA CERTIFICAÇÃO 


Esse recurso indica o ponto no texto no qual um objetivo
específico de certificação é abordado. Ele fornece uma
oportunidade para você verificar sua compreensão do
objetivo específico de MTA e, se necessário, revisar a seção
da lição na qual esse objetivo foi abordado.
 Os auxílios ao leitor aparecem em caixas sombreadas
TOME NOTA*
* encontradas no texto. Em particular, o auxílio Tome nota
fornece dicas úteis relacionadas a tarefas ou tópicos
específicos.
Essas notas apontam para informações discutidas em outra
XREF parte do livro ou descrevem recursos interessantes que não
são diretamente abordados no tópico ou exercício atual.

Alt + Tab A presença de um sinal de mais (+) entre dois nomes de


tecla indica que você precisa pressionar ambas as teclas ao
mesmo tempo. As teclas que você deve pressionar em um
exercício serão exibidas na fonte mostrada aqui.
Exemplo Os termos principais são exibidos em itálico quando definidos.

www.wiley.com/college/microsoft ou ligue para o número de chamada gratuita: 1+(888) 764-7001


xii | (somente Canadá e Estados Unidos)
Programa de apoio ao instrutor

Os programas Microsoft Official Academic Course são acompanhados por uma rica
variedade de recursos que incorporam elementos visuais detalhados para formar um
pacote coeso do ponto de vista pedagógico. Esses recursos fornecem todo o material de
que os instrutores precisam para implantar e ministrar seus cursos. Os recursos disponíveis
online para download incluem:
• O MSDN Academic Alliance (MSDN AA) foi projetado para fornecer as
ferramentas de desenvolvedor, as tecnologias e os produtos mais econômicos
e fáceis de usar para professores e alunos nos laboratórios, nas salas de aula e nos
computadores dos alunos. Uma assinatura gratuita por três anos está disponível aos
membros qualificados do MOAC.
Observação: o Microsoft Windows 2008 Server, o Microsoft Windows 7 e o
Microsoft Visual Studio podem ser baixados do MSDN AA para serem utilizados
pelos alunos neste curso.
• O Guia do Instrutor contém soluções para todos os exercícios do livro didático
e programas para vários períodos. Ele também inclui resumos de capítulo e
observações de aula. O Guia do Instrutor está disponível no site de conteúdo extra do
livro didático (http://www.wiley.com/college/microsoft).
• O Banco de teste contém centenas de perguntas de múltipla escolha, verdadeiro
ou falso, resposta curta e dissertação e está disponível para download no site de
conteúdo extra do livro didático do instrutor (www.wiley.com/college/microsoft).
Um gabarito completo também é fornecido.
• Um conjunto completo de apresentações e imagens do PowerPoint está disponível
no site de conteúdo extra do livro didático do instrutor (http://www.wiley.com/
college/microsoft) para aprimorar as apresentações em sala de aula. São fornecidos,
aproximadamente, 50 slides do PowerPoint para cada lição. Feitas sob medida para
a matriz de habilidades e os tópicos do texto, essas apresentações são criadas para
apresentar conceitos importantes que são abordados ao longo do texto. Todas as
imagens do texto estão no site de conteúdo extra do livro didático do Instrutor
(http://www.wiley.com/college/microsoft). Você pode incorporá-las nas suas
apresentações do PowerPoint ou criar suas próprias transparências e folhetos. A
utilização desses elementos visuais nas discussões de sala de aula, pode ajudar você
a chamar a atenção dos alunos para elementos-chave das tecnologias abordadas e
ajudá-los a compreender como utilizá-las de maneira eficiente no local de trabalho.
• Para aprimorar a experiência de sala de aula, nada melhor do que ouvir os colegas
para obter ideias e inspiração. A Wiley Faculty Network conecta os professores
à tecnologia, facilita a troca de melhores práticas e ajuda a aprimorar a eficiência
e a efetividade das instruções. As atividades da Faculty Network incluem treinamento
e tutoriais de tecnologia, seminários virtuais, trocas de experiências e ideias entre
colegas, consultoria pessoal e compartilhamento de recursos. Para obter detalhes,
visite o site www.WhereFacultyConnect.com.

www.wiley.com/college/microsoft ou ligue para o número de chamada gratuita: 1+(888) 764-7001


(somente Canadá e Estados Unidos) | xiii
xiv | Programa de apoio ao instrutor

MSDN ACADEMIC ALLIANCE — ASSOCIAÇÃO GRATUITA POR


TRÊS ANOS DISPONÍVEL PARA MEMBROS QUALIFICADOS!
O MSDN AA (Microsoft Developer Network Academic Alliance) foi projetado para
fornecer uma maneira mais fácil e mais barata para as universidades disponibilizarem
as ferramentas de desenvolvedor, os produtos e as tecnologias mais recentes da
Microsoft em laboratórios, salas de aula e nos computadores dos alunos. O MSDN
AA é um programa de associação anual para os departamentos de ensino dos cursos
de STEM (ciências, tecnologia, engenharia e matemática). A associação fornece uma
solução completa para manter os laboratórios acadêmicos, os professores e os alunos
na vanguarda da tecnologia.
O software disponível no programa MSDN AA é fornecido gratuitamente para os
departamentos membros por meio da parceria da editora Wiley e Microsoft.
Como um bônus para essa oferta gratuita, os professores serão apresentados
ao Faculty Connection e ao Academic Resource Center da Microsoft. É
preciso tempo e preparação para manter os alunos envolvidos e dar-lhes uma
compreensão fundamental da teoria, e o Microsoft Faculty Connection foi
projetado para ajudar professores de STEM com esta preparação, fornecendo
artigos, currículo e ferramentas que os professores podem usar para envolver
e inspirar os alunos atuais de tecnologia.
*Entre em contato com seu representante da Wiley para obter detalhes.
Para obter mais informações sobre o programa MSDN Academic Alliance, acesse:
http://msdn.microsoft.com/academic/
Observação: o Microsoft Windows Server 2008, o Microsoft Windows 7 e o
Microsoft Visual Studio podem ser baixados do MSDN AA para serem utilizados
pelos alunos neste curso.

■ Endereços web e telefones importantes


Para localizar um representante de ensino superior da Wiley na sua área, acesse o
site http://www.wiley.com/college e clique no link “Who's My Rep?” na parte superior
da página ou ligue para o número de chamada gratuita: 1 + (888) 764-7001 (somente
Canadá e Estados Unidos).
Para saber mais sobre como se tornar um Microsoft Certified Technology Specialist e
consultar a disponibilidade do exame, visite o site www.microsoft.com/learning/mcp/mcp.

www.wiley.com/college/microsoft ou ligue para o número de chamada gratuita: 1+(888) 764-7001


(somente Canadá e Estados Unidos)
Programa de apoio ao aluno

■ Recursos adicionais
Site de conteúdo extra do livro didático (www.wiley.com/college/microsoft)

O site de conteúdo extra do livro didático do aluno para a série MOAC inclui os recursos,
os arquivos de exercício e os links da Web que serão utilizados com este curso.

Wiley Desktop Editions

As Wiley Desktop Editions da série MOAC são versões eletrônicas inovadoras dos livros
didáticos impressos. Os alunos adquirem a versão para desktop por até metade do preço do
texto impresso nos Estados Unidos e ganham as vantagens de permanência e portabilidade.
As Wiley Desktop Editions oferecem aos alunos vários benefícios adicionais que não estão
disponíveis com outras soluções de texto eletrônico.
Elas NÃO são assinaturas; os alunos baixam a Wiley Desktop Edition para a área de
trabalho dos seus computadores. Os alunos poderão manter o conteúdo adquirido pelo
tempo que desejarem. Depois que a Wiley Desktop Edition é baixada para a área de trabalho
do computador, os alunos passam a ter acesso imediato a todo o conteúdo sem precisar
estar online. Os alunos também podem imprimir as seções que preferem ler impressas.
Além disso, eles têm acesso a recursos totalmente integrados na sua Wiley Desktop Edition.
Desde realçar partes do texto até fazer anotações e compartilhá-las com colegas, os alunos
podem personalizar facilmente a Wiley Desktop Edition enquanto leem ou acompanham a
aula.

■Sobre a certificação MTA (Microsoft Technology


Associate)
Preparação da força de trabalho de tecnologia para o futuro

A tecnologia desempenha um papel importante em praticamente todas as empresas ao


redor do mundo. Ter conhecimento básico de como a tecnologia funciona e entender o
impacto dela no ambiente acadêmico e profissional de hoje é cada vez mais importante,
especialmente para aqueles interessados em explorar profissões que envolvem tecnologia.
É por isso que a Microsoft criou a certificação Microsoft Technology Associate (MTA),
uma nova credencial de nível de entrada que valida o conhecimento básico de tecnologia
dos alunos que desejam seguir uma carreira em tecnologia.
A certificação Microsoft Technology Associate (MTA) é o caminho ideal e preferencial
para os programas de certificação de tecnologia da Microsoft reconhecidos mundialmente,
como o Microsoft Certified Technology Specialist (MCTS) e o Microsoft Certified
IT Professional (MCITP). A MTA tem tudo para se tornar a principal credencial para
indivíduos que desejam explorar e seguir uma carreira em tecnologia ou aumentar
seu desempenho em ocupações relacionadas, por exemplo, na área empresarial ou em

www.wiley.com/college/microsoft ou ligue para o número de chamada gratuita: 1+(888) 764-7001


(somente Canadá e Estados Unidos) | xv
xvi | Programa de apoio ao aluno

qualquer outra área na qual a tecnologia esteja presente.

Perfil do candidato à MTA


O programa de certificação MTA foi projetado especificamente para alunos com ensino
médio e superior interessados em explorar opções acadêmicas e profissionais em uma
área de tecnologia. Ele oferece aos alunos uma certificação no nível básico de TI e
desenvolvimento. Como o novo ponto de entrada recomendado para as certificações de
tecnologia da Microsoft, a certificação MTA foi projetada especialmente para os alunos que
são novos nas áreas de TI e desenvolvimento de software. Ela está disponível exclusivamente
em configurações educacionais e pode ser facilmente integrada aos currículos das aulas de
computação existentes.

MTA: capacitando os educadores, motivando os alunos

A MTA apresenta um novo padrão para medir e validar o conhecimento básico de tecnologia
dos alunos dentro da própria sala de aula mantendo intactos seu orçamento e seus recursos
de ensino. A MTA ajuda as instituições a destacarem-se como provedoras inovadoras de
credenciais requisitadíssimas no setor e é facilmente implantada com um pacote simples,
conveniente e acessível de exames de certificação de tecnologia para iniciantes. Ela também
permite que os alunos explorem caminhos de carreira na área de tecnologia sem precisar
investir muito em tempo e recursos, ao mesmo tempo que fornece uma base de carreira e
a confiança necessária para obter sucesso nos estudos avançados e nas futuras empreitadas
vocacionais.
Além de fornecer aos alunos uma certificação de nível de entrada da Microsoft, a MTA
foi projetada para ser encarada como um primeiro passo em direção às certificações
de tecnologia mais avançadas da Microsoft, como a certificação Microsoft Certified
Technology Specialist (MCTS).

Entrega dos exames MTA: a MTA Campus License

Implementar um novo programa de certificação na sua sala de aula nunca foi tão fácil
quanto agora com a MTA Campus License. Com a aquisição única de uma MTA Campus
License de 12 meses e 1.000 exames, você não precisa mais solicitar orçamentos ad hoc
nem comprar vouchers de exame regularmente. Agora você poderá planejar seu orçamento
incluindo apenas um pequeno custo para o ano todo e aplicar os exames MTA a seus alunos
e outros professores em todo o campus, onde e quando quiser.
A MTA Campus License fornece um pacote conveniente e acessível de certificações de
tecnologia de nível de entrada projetadas para capacitar os educadores e motivar os alunos
enquanto desenvolvem a base para suas carreiras.
A MTA Campus License é administrada pela Certiport (provedora de exames MTA
exclusiva da Microsoft).

www.wiley.com/college/microsoft ou ligue para o número de chamada gratuita: 1+(888) 764-7001


(somente Canadá e Estados Unidos)
Programa de apoio ao aluno | xvii

Para saber mais sobre como receber um certificado de Microsoft Technology Associate
e consultar a disponibilidade do exame, visite o site www.microsoft.com/learning/mta.

■ Ative seu teste prático GRATUITO de MTA!


A compra deste livro lhe dá direito a um teste prático gratuito de MTA no GMetrix (com
preço normal de $30). Acesse o site www.gmetrix.com/mtatests e utilize este código de
validação para resgatar seu teste gratuito: MTA98-361-A19875B7D810
O GMetrix Skills Management System oferece a você tudo o que é necessário para
praticar o conteúdo da certificação Microsoft Technology Associate (MTA).
Visão geral dos recursos de teste:
• Testes práticos relacionados aos objetivos do exame MTA (Microsoft Technology
Associate)
• Testes práticos de MTA no GMetrix que simulam o ambiente de teste MTA real
• Mais de 50 perguntas por teste cobrindo todos os objetivos
• Liberdade para realizar os testes no seu ritmo (salvar o teste e continuar mais tarde
e retornar para as perguntas que você ignorou)
• Relatório de pontuação detalhado destacando as áreas que exigem revisão
Para obter o máximo da sua preparação para MTA, aproveite o recurso do GMetrix e faça
seu teste prático gratuito de MTA hoje mesmo!
Caso tenha problemas de suporte técnico em relação à instalação do programa ou à
ativação do código, envie um email para support@gmetrix.com.

www.wiley.com/college/microsoft ou ligue para o número de chamada gratuita: 1+(888) 764-7001


(somente Canadá e Estados Unidos)
Agradecimentos

■Revisores dos conceitos básicos de tecnologia da certificação MTA no


programa MOAC

Gostaríamos de agradecer aos diversos revisores Sharon Moran, Hillsborough Community College
que analisaram cuidadosamente o documento e Keith Hoell, Briarcliffe College e Queens College –
forneceram feedbacks inestimáveis para possibilitar o CUNY
desenvolvimento de um material instrucional da mais alta Mark Hufnagel, Lee County School District
qualidade:
Rachelle Hall, Glendale Community College
Yuke Wang, Universidade do Texas em Dallas Scott Elliott, Christie Digital Systems, Inc.
Palaniappan Vairavan, Bellevue College Gralan Gilliam, Kaplan
Harold “Buz” Lamson, ITT Technical Institute Steve Strom, Butler Community College
Colin Archibald, Valencia Community College John Crowley, Bucks County Community College
Catherine Bradfield, DeVry University Online Margaret Leary, Northern Virginia Community College
Robert Nelson, Blinn College Sue Miner, Lehigh Carbon Community College
Kalpana Viswanathan, Bellevue College Gary Rollinson, Cabrillo College
Bob Becker, Vatterott College Al Kelly, University of Advancing Technology
Carol Torkko, Bellevue College Katherine James, Seneca College
Bharat Kandel, Missouri Tech
Linda Cohen, Forsyth Technical Community College
Candice Lambert, Metro Technology Centers
Susan Mahon, Collin College
Mark Aruda, Hillsborough Community College
Claude Russo, Brevard Community College
David Koppy, Baker College

www.wiley.com/college/microsoft ou ligue para o número de chamada gratuita: 1+(888) 764-7001


xviii | (somente Canadá e Estados Unidos)
Conteúdo resumido

1 Introdução à programação 1

2 Introdução à programação orientada a objeto 32

3 Noções básicas sobre o desenvolvimento de software em geral 65

4 Noções básicas sobre aplicativos Web 85

5 Noções básicas sobre aplicativos da área de trabalho 120

6 Noções básicas sobre bancos de dados 142

Apêndice A 177
Índice 179

www.wiley.com/college/microsoft ou ligue para o número de chamada gratuita: 1+(888) 764-7001


(somente Canadá e Estados Unidos) | xix
Sumário

Lição 1: Introdução à Noções básicas sobre classes abstratas e seladas 50


Herdando da classe Object 51
programação 1 Conversão entre tipos 52
Noções básicas sobre polimorfismo 53
Matriz de domínio objetiva 1 Noções básicas sobre as palavras-chave Override e
Principais termos 1 New 55
Noções básicas sobre programação de computador 2 Noções básicas sobre interfaces 56
Introduzindo algoritmos 2
Resumo de habilidades 58
Introduzindo C# 4
Avaliação de conhecimento 59
Noções básicas sobre estruturas de decisão 11
A instrução if 11 Avaliação da competência 64
A instrução if-else 13 Avaliação de proficiência 64
A instrução switch 15
Noções básicas sobre estruturas de repetição 17 Lição 3 Noções básicas sobre
Noções básicas sobre o loop while 17 o desenvolvimento de
Noções básicas sobre o loop do-while 19
Noções básicas sobre o loop for 20 software em geral 65
Noções básicas sobre o loop foreach 21
Noções básicas sobre recursão 22 Matriz de domínio objetiva 65
Noções básicas sobre tratamento de exceções 23 Principais termos 65
Tratando exceções 24 Noções básicas sobre gerenciamento do ciclo de vida
Usando try-catch-finally 25 do aplicativo 66
Resumo de habilidades 26 Noções básicas sobre análise de requisitos 66
Avaliação de conhecimento 27 Noções básicas sobre o processo de design 67
Noções básicas sobre desenvolvimento de software 67
Avaliação da competência 30 Noções básicas sobre teste de software 68
Avaliação de proficiência 31 Noções básicas sobre gerenciamento de lançamento 68
Noções básicas sobre testes 68
Lição 2: Introdução à programação Noções básicas sobre métodos de teste 69
orientada a objeto 32 Noções básicas sobre os níveis de teste 69
Noções básicas sobre as estruturas de dados 70
Matriz de domínio objetiva 32 Noções básicas sobre matrizes 70
Principais termos 32 Noções básicas sobre filas 72
Noções básicas sobre pilhas 73
Noções básicas sobre objetos 33 Listas vinculadas 74
Pensando em uma maneira orientada a objeto 33
Noções básicas sobre classes 33 Noções básicas sobre algoritmos de classificação 76
Noções básicas sobre o BubbleSort 76
Noções básicas sobre valores e referências 44 Noções básicas sobre o QuickSort 79
Noções básicas sobre structs 44
Noções básicas sobre alocação de memória 45 Resumo de habilidades 81
Noções básicas sobre encapsulamento 47 Avaliação de conhecimento 81
Noções básicas sobre modificadores de acesso 48 Avaliação da competência 83
Noções básicas sobre herança 48 Avaliação de proficiência 84

www.wiley.com/college/microsoft ou ligue para o número de chamada gratuita: 1+(888) 764-7001


(somente Canadá e Estados Unidos) | xxi
xxii | Sumário

Lição 4: Noções básicas sobre Noções básicas sobre aplicativos MDI (interface de
vários documentos) 126
aplicativos Web 85
Noções básicas sobre aplicativos de console 129
Trabalhando com parâmetros de linha de comando 130
Matriz de domínio objetiva 85
Noções básicas sobre os serviços Windows 131
Principais termos 85 Criando um serviço Windows 132
Noções básicas sobre o desenvolvimento de páginas Resumo de habilidades 137
da Web 85
Noções básicas sobre HTML 86 Avaliação de conhecimento 138
Noções básicas sobre folhas de estilos em cascata 88 Avaliação da competência 140
Noções básicas sobre JavaScript 92 Avaliação de proficiência 141
Noções básicas sobre programação do lado do cliente
versus lado do servidor 94
Noções básicas sobre o desenvolvimento de Lição 6: Noções básicas sobre bancos
aplicativos ASP.NET 95 de dados 142
Noções básicas sobre o ciclo de vida da página do ASP.
NET e o modelo de eventos 96
Matriz de domínio objetiva 142
Noções básicas sobre gerenciamento de estado 99
Principais termos 142
Noções básicas sobre a hospedagem Web do
IIS 104 Noções básicas sobre conceitos de banco de dados
Noções básicas sobre os Serviços de Informações da relacional 142
Internet 105 Noções básicas sobre bancos de dados 143
Criando diretórios virtuais e sites 105 Noções básicas sobre conceitos de banco de dados
Implantando aplicativos Web 106 relacional 143
Noções básicas sobre design de banco de dados
Noções básicas sobre o desenvolvimento de serviços relacional 144
Web 107 Noções básicas sobre diagramas de relacionamento
Introdução ao SOAP 107
entre entidades 144
Introdução ao WSDL 108
Noções básicas sobre normalização de dados 146
Criando serviços Web 108
Consumindo serviços Web 112 Noções básicas sobre os métodos de consulta de
banco de dados 149
Resumo de habilidades 115 Trabalhando com consultas SQL 150
Avaliação de conhecimento 115 Trabalhando com procedimentos armazenados 159
Avaliação da competência 118 Noções básicas sobre métodos de conexão de banco
Avaliação de proficiência 119 de dados 164
Trabalhando com arquivos simples 164
Trabalhando com XML 167
Lição 5: Noções básicas sobre Trabalhando com DataSet 170
aplicativos da área de Resumo de habilidades 173
trabalho 120 Avaliação de conhecimento 173
Avaliação da competência 176
Matriz de domínio objetiva 120 Avaliação de proficiência 176
Principais termos 120
Noções básicas sobre os aplicativos do Windows
Forms 120 Apêndice A 177
Como projetar um Windows Form 121 Índice 179
Noções básicas sobre o modelo de evento do Windows
Form 123
Usando a herança visual 123

www.wiley.com/college/microsoft ou ligue para o número de chamada gratuita: 1+(888) 764-7001


(somente Canadá e Estados Unidos)
Introdução à LIÇÃO 1
programação
M AT R I Z D E H A B I L I D A D E S D A L I Ç Ã O

Habilidades/Conceitos Objetivo do exame MTA Número do objetivo do


exame MTA
Noções básicas sobre programação Compreender o armazenamento 1.1
de computador do computador e os tipos de dados.
Noções básicas sobre estruturas Entender as estruturas de 1.2
de decisão decisão em computadores.
Noções básicas sobre estruturas Identificar o método adequado 1.3
de repetição para lidar com repetições.
Noções básicas sobre tratamento Entender o tratamento de erros. 1.4
de exceções

P R I N C I PA I S
TERMOS estruturas de decisão instrução if
algoritmo tabela de decisões instrução if-else
matriz instrução padrão métodos
código binário Loop do-while operador
sistema de número binário
exceção Recursão
maiúsculas e minúsculas
bloco finally bloco switch
classe
fluxograma Instrução switch
programas de computador
(programas) Loop for bloco try-catch-finally
constante Loop foreach variável
tipos de dados linguagem de alto nível Loop while

Imagine que você seja um desenvolvedor de software da Northwind Corporation.


Como parte do seu trabalho, você desenvolve programas de computador para
solucionar problemas empresariais. Seu trabalho inclui, por exemplo, analisar
pedidos de clientes para determinar os descontos aplicáveis, atualizar informações
de estoque dos milhares de itens em estoque de uma empresa e redigir relatórios
interativos que permitam aos usuários classificar e filtrar dados.
É importante para você ter certeza de que seus programas são projetados exatamente
de acordo com as especificações. Você também precisa garantir que todos os cálculos
estejam exatos e completos. Os programas escritos precisam ser robustos e devem ser
capazes de exibir mensagens de erro, mas continuar sendo processados.

1
2 | Lição 1

A linguagem de programação usada fornece várias ferramentas e técnicas para você


executar suas tarefas. Com base na tarefa disponível, você seleciona os tipos de
dados e as estruturas de controle mais adequados para solucionar o problema.

■ Noções básicas sobre programação de computador


Um programa de computador é um conjunto de instruções precisas para a execução
de uma tarefa. Nesta seção, você aprenderá como escrever algoritmos e programas de
computador para solucionar um problema específico. Além de escrever seu primeiro
O RESULTADO programa de computador usando a linguagem de programação C#, você também
aprenderá sobre a estrutura básica dos programas de computador e como compilar,
executar, fornecer entrada para e gerar a saída de um programa.

Introdução a algoritmos
Um algoritmo é conjunto finito e ordenado de etapas para solucionar um problema
específico.

O termo algoritmo refere-se a um método de solução de problemas. Os algoritmos podem


ser descritos em inglês, mas essas descrições muitas vezes são mal interpretadas devido
à complexidade e à ambiguidade inerentes em uma linguagem natural. Portanto,
os algoritmos são escritos com frequência em formatos simples e mais precisos, como
fluxogramas, árvores de decisão e tabelas de decisão, que representam um algoritmo como
um diagrama, uma tabela ou um gráfico. Essas técnicas são muitas vezes empregadas antes
que os programas sejam escritos para que se obtenha uma melhor compreensão da solução.
Essas ferramentas de desenvolvimento de algoritmo podem ajudá-lo a expressar uma
solução de uma maneira fácil de usar, mas elas não podem ser entendidas diretamente por
um computador. Para que um computador entenda o seu algoritmo, você precisará escrever
um programa de computador de uma maneira mais formal, usando uma linguagem
de programação como a C#. Você aprenderá sobre isso na próxima seção.
Nesse meio tempo, esta seção da lição se concentrará em duas técnicas para apresentar seus
algoritmos, ou seja, fluxogramas e tabelas de decisão, que são mais precisos do que uma
linguagem natural, mas menos formais e mais fáceis de usar do que uma linguagem de
computador.
INTRODUÇÃO AOS FLUXOGRAMAS
Um fluxograma é uma representação gráfica de um algoritmo. Um fluxograma
é geralmente desenhado usando símbolos padrão. Alguns símbolos comuns de fluxograma
são mostrados na tabela 1-1.

Tabela 1-1
Símbolos comuns
de fluxograma
Introdução à programação | 3

Por exemplo, a figura 1-1 mostra um fluxograma que insere dois números, compara-os
e gera a saída do maior número.

Figura 1-1
Um fluxograma simples que
compara dois números e gera
a saída do maior dos dois

Como você pode ver, esse fluxograma lista todas as etapas necessárias na ordem correta
para executar a operação. O fluxo de controle começa com o símbolo Iniciar e termina
com o símbolo Parar. O processo e os símbolos das operações de entrada/saída sempre
têm uma única entrada e uma única saída. Por outro lado, o símbolo de decisão tem uma
única entrada, mas várias saídas. Você pode testar um fluxograma, executando um teste
completo. Nesse tipo de teste, você rastreia manualmente as etapas do fluxograma com
os dados de teste para verificar se os caminhos corretos estão sendo seguidos.

INTRODUÇÃO ÀS TABELAS DE DECISÃO


Quando um algoritmo envolve inúmeras condições, as tabelas de decisão estão em um
formato mais compacto e legível para a apresentação do algoritmo. A tabela 1-2 apresenta
uma tabela de decisões para calcular um desconto. Essa tabela gera uma porcentagem
de desconto dependendo da quantidade de produto adquirido. As linhas em negrito da
tabela de decisões dividem a tabela em quatro quadrantes. O primeiro quadrante (superior
esquerdo) especifica as condições (“Quantidade < 10” etc.). O segundo quadrante
(superior direito) especifica as regras. As regras são as combinações possíveis dos
resultados de cada condição. O terceiro quadrante (inferior esquerdo) especifica a ação
(“Desconto” neste caso), e o último quadrante (inferior direito) especifica os itens de ação
correspondentes a cada regra.
4 | Lição 1

Tabela 1-2
Uma tabela de decisões para Quantidade < 10 S N N N
calcular descontos
Quantidade < 50 S S N N
Quantidade < 100 S S S N
Desconto 5% 10% 15% 20%

Para descobrir qual item de ação aplicar, você deve avaliar cada condição para encontrar
a regra de correspondência e, em seguida, escolher a ação especificada na coluna com
a regra de correspondência. Por exemplo, se o valor de “Quantidade” nos dados de teste
for 75, a primeira regra resultará em “Não”, a segunda regra resultará em “Não”,
e a terceira regra resultará em “Sim”. Portanto, você escolherá o item de ação da coluna
(N, N e S), que define o desconto de 15%.

Introdução ao C#
C# é uma linguagem de programação popular de alto nível que lhe permite escrever
programas de computador em um formato que pode ser compreendido pelo usuário.
C# é uma parte do .NET Framework e se beneficia do suporte ao tempo de execução
e das bibliotecas de classe fornecidas pelo .Framework.

Conforme discutido na seção anterior, os computadores precisam de instruções precisas


e completas para realizar uma tarefa. Esses conjuntos de instruções são denominados
programas de computador ou simplesmente programas para abreviar.
No nível mais básico, os computadores usam o sistema de número binário para
representar informações e código. Nesse sistema, cada valor é representado usando
apenas dois símbolos, 0 e 1. Um programa de computador escrito usando o sistema
de número binário é denominado código binário.
O uso de um código binário para programar um computador é conciso e extremamente
difícil de executar para qualquer tarefa não trivial. Portanto, para simplificar
a programação, cientistas e engenheiros de computador compilaram vários níveis
de abstrações entre computadores e seus operadores humanos. Essas abstrações incluem
software (como sistemas operacionais, compiladores e vários sistemas de tempo
de execução) que assumem a responsabilidade pela conversão de um programa que
pode ser compreendido pelo usuário em um programa legível por máquina.
Os programas mais modernos são escritos uma linguagem de alto nível, como C#,
Visual Basic ou Java. Essas linguagens permitem que você escreva instruções precisas
em um formato que pode ser compreendido pelo usuário. Em seguida, um compilador
de linguagem converte a linguagem de alto nível em uma linguagem de nível inferior
que pode ser entendida pelo sistema de execução de tempo de execução.
Cada linguagem de programação fornece seu próprio conjunto de vocabulário e gramática
(também conhecido como sintaxe). Neste curso, você aprenderá a programar usando
a linguagem de programação C# no .NET Framework. O .NET Framework fornece
um ambiente de execução em tempo de execução para o programa C#. O Framework
também contém bibliotecas de classes que fornecem inúmeras funcionalidades essenciais
reutilizáveis que você pode usar diretamente no seu programa C#.
MAIS INFORMAÇÕES
O .NET Framework fornece três componentes principais: um ambiente de execução de tempo
de execução, um conjunto de bibliotecas de classe que fornecem uma grande quantidade de
funcionalidades reutilizável e compiladores de linguagem para C#, Visual Basic e Managed C++.
O .NET Framework oferece suporte a várias linguagens de programação e também tem suporte para
adicionar outras linguagens ao sistema. Embora a sintaxe e o vocabulário de cada linguagem possam
ser diferentes, cada uma ainda poderá usar as bibliotecas de classe base fornecidas pelo Framework.
Introdução à programação | 5

Neste curso, você usará um IDE (ambiente de desenvolvimento integrado) para


desenvolver seu código. Você pode usar o Visual Studio ou a edição gratuita Visual Studio
Express para escrever seu código. Qualquer uma dessas ferramentas fornece um ambiente
altamente produtivo para você desenvolver e testar seus programas.

ESCREVER UM PROGRAMA C#

PREPARE-SE. Para escrever um programa C#, execute estas etapas:


1. Inicie o Visual Studio. Selecione Arquivo > Novo Projeto. Selecione os modelos
de aplicativo de console em Visual C#.
2. Digite IntroducingCS na caixa Nome. Verifique se o diretório Create está marcado para
a caixa de seleção de solução e digite o nome Lesson01 na caixa Nome da solução.
Clique em OK para criar o projeto.
3. Quando o projeto for criado, você perceberá que o Visual Studio já terá criado um
arquivo denominado Program.cs e escrito um modelo para você.
4. Modifique o modelo para que ele fique semelhante ao seguinte código:
using System;
namespace Lesson01
{
class Program
TOME NOTA
* {
C# é uma linguagem static void Main(string[] args)
de programação {
diferencia maiúsculas Console.WriteLine(“olá, mundo”);
de minúsculas. Como }
resultado, digitar “Classe” }
em vez de “classe” }
(por exemplo) resultará 5. Selecione Depurar > Iniciar sem Depurar ou pressione Ctrl+F5.
em um erro de sintaxe.
6. Você verá a saída do programa em um janela de comando, conforme mostra
a figura 1-2.

Figura 1-2
Saída do programa em uma
janela de comando

Você também pode executar o programa, abrindo uma janela de comando (cmd.exe)
UMA OUTRA
e, em seguida, navegando para a pasta de saída do projeto, que, por padrão,
MANEIRA é a subpasta bin\debug no local do projeto. Inicie o programa digitando o nome
dele na janela de comando e pressionando Enter.

7. Pressione uma tecla para fechar a janela de comando.


PAUSE. Deixe o projeto aberto para ser usado no próximo exercício.
6 | Lição 1

O programa que você acabou de criar tem uma função trivial, mas, no entanto, é útil para
a compreensão da estrutura, da compilação e da execução do programa. Vamos primeiro
falar sobre a parte de compilação e execução. Isso é o que acontece quando você seleciona
a opção Depurar > Iniciar sem Depurar na etapa 5 acima:
1. O Visual Studio invoca o compilador C# para converter o código C# em uma
linguagem de nível inferior, o código CIL (Common Intermediate Language).
Esse código de baixo nível é armazenado em um arquivo executável denominado
(Lesson01.exe). O nome do arquivo de saída pode ser alterado modificando as
propriedades de um projeto.
2. Em seguida, o Visual Studio gera a saída do projeto e solicita que ele seja
executado pelo sistema operacional. Neste momento, você vê a janela de comando
exibindo a saída.
3. Quando o programa termina, o Visual Studio exibe a seguinte mensagem:
“Pressione qualquer tecla para continuar. . .”. Observe que essa mensagem
só é gerada quando você executa o programa usando a opção Iniciar sem Depurar.

Quando você seleciona a opção de menu Depurar > Iniciar sem Depurar, o Visual Studio
exibe automaticamente o prompt “Pressione qualquer tecla para continuar. . .” A janela
de comando, então, fica aberta para que você examine a saída. Se, entretanto, você
*
TOME NOTA selecionar a opção Depurar > Iniciar Depuração, a janela de comando fechará assim que
for concluída a execução do programa. É importante saber que a opção Iniciar Depuração
fornece recursos de depuração, como a capacidade de pausar um programa em execução em
um determinado ponto e rever o valor das diversas variáveis na memória.

Se você não usar um IDE (ambiente de desenvolvimento integrado), como o Visual


Studio, ainda poderá compilar seu programa manualmente usando as ferramentas de linha
de comando. Obviamente, o Visual Studio facilita e agiliza o teste dos seus programas.

Antes que o código CIL (Common Intermediate Language) seja executado, ele deve ser
convertido primeiro para a arquitetura da máquina na qual será executado. O sistema de
*
TOME NOTA
execução de tempo de execução do .NET Framework se encarrega dessa conversão de
forma oculta, usando um processo denominado compilação Just-In-Time.

NOÇÕES BÁSICAS DA ESTRUTURA DE UM PROGRAMA C#

Nesta seção da lição, você aprenderá sobre os elementos estruturais do programa


C# simples criado na seção anterior.

A figura 1-3 mostra o programa criado no exercício anterior com números de linha.
Durante esta seção, esses números serão usados para se referir a diferentes estruturas
do programa.

Para habilitar a exibição de números de linha no Visual Studio, selecione o menu


*
TOME NOTA Ferramentas > Opções. Em seguida, expanda o nó Editor de Texto e selecione C#.
Finalmente, na seção Exibir, marque a opção Números de Linha.
Introdução à programação | 7

Figura 1-3
Listagem de programa com
números de linha

Um programa C# é composto por uma ou mais classes. Uma classe é um conjunto


de dados e métodos. Por exemplo, o código da figura 1-3 define uma única classe
REFERÊNCIA denominada Program nas linhas de 5 a 11. Uma classe é definida usando a palavra-chave
CRUZADA class, seguida pelo nome de classe. O conteúdo de uma classe é definido entre uma chave
de abertura ({) e uma chave de fechamento (}).
Você poderá encontrar
mais informações sobre A linha 3 do código na figura 1-3 define um namespace, Lesson01. Os namespaces são
classes na lição 2. usados para organizar classes e identificá-las com exclusividade. O namespace e os nomes
de classe são combinados para criar um nome de classe totalmente qualificado. Por
exemplo, o nome de classe totalmente qualificado da classe Program é Lesson01.Program.
C# requer que o nome totalmente qualificado de uma classe seja exclusivo. Como
resultado, você não poderá ter outra classe com nome Program no namespace Lesson01,
mas poderá ter uma classe com nome Program em outro namespace, por exemplo,
Lesson02. Aqui, a classe Program definida no namespace Lesson02 é identificada
exclusivamente pelo seu nome de classe totalmente qualificado, Lesson02.Program.
REFERÊNCIA O .NET Framework fornece inúmeras classes úteis, organizadas em vários namespaces.
CRUZADA
O namespace System contém algumas das classes base usadas com mais frequência.
Você poderá encontrar Uma classe desse tipo no namespace System é Console. A classe Console fornece
mais informações sobre funcionalidade de entrada e saída do aplicativo de console. A linha 9 do código na figura
métodos na lição 2. 1-3 refere-se à classe Console e chama seu método WriteLine. Para acessar o método
WriteLine de forma inequívoca, você deve escrevê-lo desta forma:
System.Console.WriteLine(“olá, mundo”);
TOME NOTA
* Como os nomes de classe aparecem com frequência no código, escrever sempre o nome
de classe totalmente qualificado será entediante e tornará o programa muito detalhado.
Cada instrução C#
Você pode solucionar esse problema usando a diretiva C# using (consulte o código
deve terminar com na linha 1 da figura 1-3). A diretiva using permite que você use as classes em um
ponto-e-vírgula (;). namespace sem precisar qualificar totalmente o nome de classe.
A classe Program define um único método pelo nome Main (consulte as linhas 7 a 10
da listagem de código na figura 1-3). Main é um método especial, pois também serve
como um ponto de entrada para o programa. Quando o tempo de execução executa um
8 | Lição 1

programa, ele sempre começa no método Main. Um programa pode ter várias classes,
e cada classe pode ter vários métodos, mas deve ter apenas um método Main. Um método
pode, por sua vez, chamar outros métodos. Na linha 9, o método Main está chamando
o método WriteLine da classe System.Console para exibir uma cadeia de caracteres na
janela de comando — e é desse modo que a mensagem é exibida.

O método Main deve ser declarado como static. Um método estático pode ser chamado
*
TOME NOTA em uma classe, mesmo quando nenhuma instância da classe é criada. Você aprenderá
mais sobre isso na próxima lição.

NOÇÕES BÁSICAS SOBRE VARIÁVEIS

As variáveis fornecem armazenamento temporário durante a execução de um


programa.

As variáveis em C# são espaços reservados usados para armazenar valores. Uma variável
tem um nome e um tipo de dados. O tipo de dados de uma variável determina quais
valores ele pode conter e qual tipo de operações pode ser executado nele. Por exemplo,
a declaração a seguir cria uma variável denominada number do tipo de dados int e atribui
o valor 10 à variável:
int number = 10;
Quando uma variável é declarada, um local suficientemente grande para conter o valor do
seu tipo de dados é criado na memória do computador. Por exemplo, em uma máquina de
32 bits, uma variável de tipo de dados int precisará de dois bytes de memória. O valor de
uma variável pode ser modificado por outra atribuição, como:
number = 20;
O código acima altera o conteúdo do local da memória identificado pelo número de nome.

Um nome de variável deve começar com letra ou sublinhado e pode conter apenas
*
TOME NOTA letras, números ou sublinhados. Um nome de variável não deve exceder 255 caracteres.
Uma variável também deve ser exclusiva dentro do escopo no qual está definida.

NOÇÕES BÁSICAS SOBRE CONSTANTES

As constantes são campos de dados ou variáveis locais cujo valor não pode
ser modificado.

As constantes são declaradas usando a palavra-chave const. Por exemplo, uma constante
pode ser declarada da seguinte maneira:
const int i = 10;
Isso declara uma constante i de tipo de dados int e armazena o valor 10. Depois que
a constante for declarada, seu valor não poderá ser alterado.

NOÇÕES BÁSICAS SOBRE TIPOS DE DADOS

Os tipos de dados especificam o tipo de dados com o qual você trabalha em um


programa. O tipo de dados define o tamanho de memória necessário para armazenar
os dados e os tipos de operações que podem ser executados nos dados.
Introdução à programação | 9

REFERÊNCIA C# fornece vários tipos de dados internos que você pode usar nos seus programas. Você
CRUZADA
também pode definir novos tipos, especificando uma estrutura de dados, como uma classe
Você poderá encontrar ou um struct. Este capítulo se concentra em alguns tipos de dados internos mais usados
mais informações com frequência.
sobre como criar seus A tabela 1-3 lista vários tipos de dados internos usados com frequência e disponíveis
próprios tipos de dados em C#. Os tamanhos listados na tabela referem-se a um computador que executa
na lição 2. um sistema operacional de 32 bits, como o Windows 7 de 32 bits. Para um sistema
operacional de 64 bits, como o Windows 7 de 64 bits, esses tamanhos serão diferentes.

Tabela 1-3
Tipos de dados internos Tipo de dados Tamanho Intervalo de valores
usados com frequência em C#
byte 1 byte 0 a 255
char 2 bytes U+0000 a U+ffff (caracteres Unicode)
short 2 bytes −32,768 to 32,767
Int 4 bytes −2,147,483,648 to 2,147,483,647
long 8 bytes −9,223,372,036,854,775,808 to
9,223,372,036,854,775,807
float 4 bytes ±1.5 × 10-45 a ±3.4 × 1038
double 8 bytes ±5.0e−324 a ±1.7e308
TOME NOTA
* bool 2 bytes True ou false
As versões sem sinal
de short, int e long são string - Zero ou mais caracteres Unicode
ushort, uint e ulong,
respectivamente.
Os tipos sem sinal têm Todos os tipos de dados listados na tabela 1-3 são tipos de valor, exceto string, que é um
o mesmo tamanho tipo de referência. As variáveis que são baseadas diretamente nos tipos de valor contêm
que suas versões com o valor. No caso do tipo de referência, a variável contém o endereço do local de memória
sinal, mas armazenam onde estão armazenados os dados reais. Você aprenderá mais sobre as diferenças entre
muito mais intervalos tipos de valor e tipos de referência na lição 2.
de valores somente
positivos.
NOÇÕES BÁSICAS SOBRE MATRIZES

Uma matriz é uma coleção de itens em que cada item pode ser acessado por um
índice exclusivo.

Uma matriz em C# é normalmente usada para representar uma coleção de itens de tipo
semelhante. Uma declaração de matriz de exemplo é mostrada no código a seguir:
int[] numbers = { 1, 2, 3, 4, 5 };
Essa declaração cria uma matriz identificada pelos números de nome. Essa matriz é capaz
de armazenar uma coleção de cinco números inteiros. Essa declaração também inicializa
cada um dos itens de matriz respectivamente pelos números 1 a 5.
Qualquer item de matriz pode ser diretamente acessado usando um índice. No .NET
Framework, os índices de matriz são de base zero. Isso significa que, para acessar
o primeiro elemento de uma matriz, você usa o índice 1; para acessar o segundo
elemento, você usa o índice 2 e assim por diante.
Para acessar um elemento de matriz individual, você usa o nome da matriz seguido
do índice entre colchetes. Por exemplo, numbers[0] retornará o valor 1 da matriz
declarado acima, e numbers[4] retornará o valor 5. É inválido acessar uma matriz fora
10 | Lição 1

REFERÊNCIA de seus limites definidos. Por exemplo, você obterá um erro se tentar acessar o elemento
CRUZADA
de matriz numbers[5].
O tópico de matrizes
é abordado em mais NOÇÕES BÁSICAS SOBRE OPERADORES
detalhes na lição 3,
Noções básicas sobre Os operadores são símbolos que especificam qual operação executar nos operandos
o desenvolvimento de antes de retornar um resultado.
software em geral.
Os exemplos de operadores incluem +, -, *, / etc., e os operandos podem ser variáveis,
constantes, literais etc. Dependendo de quantos operandos estiverem envolvidos, haverá
três tipos de operadores:
• Operadores unários: os operadores unários trabalham com apenas um operando.
Os exemplos incluem ++x, x++ ou isEven, onde x é do tipo de dados Integer e isEven
é do tipo de dados Boolean.
• Operadores binários: os operadores binários usam dois operandos. Por exemplo,
x + y ou x > y.
• Operadores ternários: os operadores ternários usam três operandos. Há apenas
um operador ternário, ?:, em C#.
Muitas vezes, as expressões envolvem mais de um operador. Nesse caso, o compilador
precisa determinar qual operador terá precedência sobre o(s) outro(s). A tabela 1-4 lista os
operadores C# em ordem de precedência. Quanto mais alto um operador estiver localizado
na tabela, maior será sua precedência. Os operadores com maior precedência são avaliados
antes dos operadores com menor precedência. Os operadores que aparecem na mesma linha
têm a mesma precedência.
Tabela 1-4
Precedência do operador Categoria Operadores
em C#
Primário x.y f(x) a[x] x++ x −− novo typeof marcado
desmarcado
Unário + - ! ~ ++x −−x (T)x
Multiplicativo */%
Aditivo +-
Shift << >>
Relacional e o tipo de teste < > <= >= is as
Igualdade == !=
AND lógico &
XOR lógico ^
OR lógico |
AND condicional &&
OR condicional ||
Ternário condicional ?:
Atribuição = *= /= %= += -= <<= >>= &= ^= |=

O operador de incremento unário (++) adiciona 1 ao valor de um identificador. Da mesma


forma, o operador de decremento (--) subtrai 1 do valor de um identificador. O incremento
e o decremento unários podem ser usados como prefixos ou sufixos. Por exemplo:
Introdução à programação | 11

int x = 10;
x++; //o valor de x agora é 11
++x++; //o valor de x agora é 12
Entretanto, o modo como os operadores de incremento e de decremento unários
funcionam quando usados como parte de uma atribuição pode afetar os resultados.
Em particular, quando os operadores de incremento e de decremento unários são usados
como prefixos, o valor atual do identificador é retornado antes do incremento ou do
decremento. Por outro lado, quando usado como sufixo, o valor do identificador
é retornado depois que o incremento ou decremento é concluído. Para compreender
o que isso significa, considere o exemplo de código a seguir:
int y = x++; // o valor de y é 12
int z = ++x; // o valor de z é 14
Aqui, na primeira instrução, o valor de x é retornado antes do incremento. Como
resultado, depois que a instrução é executada, o valor de y é 12 e o valor de x é 13.
Por outro lado, na segunda instrução, o valor de x é incrementado antes do retorno do
seu valor para a atribuição. Como resultado, depois que a instrução é executada, o valor
de x e z é 14.

NOÇÕES BÁSICAS SOBRE MÉTODOS

Métodos são blocos de código que contêm uma série de instruções. Os métodos
podem receber dados via argumentos e retornar um valor para o solicitante.

Na listagem de código anterior, você aprendeu sobre o método Main. Os métodos contêm
a ação em um programa. Mais precisamente, um método é um conjunto de instruções que
são executadas quando o método é chamado.
PRONTO PARA
O método Main não retorna um valor de volta para o código de chamada. Isso é indicado
CERTIFICAÇÃO
Você compreende usando a palavra-chave void. Se um método tivesse que retornar um valor, o tipo de dados
os elementos principais apropriado para o valor de retorno seria usado em vez de void.
da programação, como
variáveis, tipos de Os membros de classe podem ter modificadores, como static, public e private. Esses
dados, operadores modificadores especificam como e onde os membros de classe podem ser acessados. Você
e métodos? aprenderá mais sobre esses modificadores na lição 2.
1.1

■ Noções básicas sobre estruturas de decisão

As estruturas de decisão introduzem a capacidade de tomada de decisão em um


O RESULTADO
programa. Elas permitem que você ramifique para diferentes seções do código,
dependendo do valor truth de uma expressão booliana.

As estruturas de controle de tomada de decisão em C# são as instruções if, if-else


e switch. As seções a seguir abordam cada uma dessas instruções mais detalhadamente.

A instrução if
A instrução if somente executará uma sequência de instruções específica
se a expressão booliana correspondente resultar em true.
12 | Lição 1

Algumas vezes nos seus programas, você desejará que uma sequência de instruções
somente seja executada se uma determinada condição for verdadeira. Em C#, isso
é possível usando a instrução if. Execute as etapas a seguir para criar um programa
que use uma instrução if.

USAR A INSTRUÇÃO IF

PREPARE-SE. Para usar a instrução if, execute as seguintes tarefas:


1. Adicione um novo projeto de aplicativo de console (denominado if_Statement)
à solução Lesson01.
2. Adicione o código a seguir ao método Main da classe Program.cs:
int number1 = 10;
int number2 = 20;
if (number2 > number1)
{
Console.WriteLine(“number2 é maior que number1”);
}
3. Selecione Depurar > Iniciar sem Depurar ou pressione Ctrl+F5.
4. Você verá a saída do programa em uma janela de comando.
5. Pressione uma tecla para fechar a janela de comando.
PAUSE. Deixe o projeto aberto para ser usado no próximo exercício.
Esse código é funcionalmente equivalente ao fluxograma mostrado na figura 1-4.

Figura 1-4
Fluxograma equivalente da
instrução if de exemplo

Aqui, a instrução de saída será executada somente se a expressão booliana entre


parênteses for true. Se a expressão for false, o controle passará para a próxima instrução
após a instrução if.
Introdução à programação | 13

No código C#, os parênteses em torno da condição são necessários. No entanto, as chaves


serão opcionais se houver apenas uma instrução no bloco de código. Portanto, a instrução
if acima é equivalente ao seguinte:
if (number2 > number1)
Console.WriteLine(“number2 é maior que number1”);
Por outro lado, examine este exemplo:
if (number2 > number1)
Console.WriteLine(“number2 é maior que number1”);
Console.WriteLine(number2);
Aqui, apenas a primeira instrução Console.WriteLine faz parte da instrução if.
A segunda instrução Console.WriteLine é sempre executada independentemente
do valor da expressão booliana.
Para maior clareza, é sempre recomendável delimitar entre chaves a instrução que
precisa ser condicionalmente executada.
As instruções if também podem ser aninhadas dentro de outras instruções if, como
neste exemplo:
int number1 = 10;
if (number1 > 5)
{
Console.WriteLine(“number1 é maior que 5”);
if (number1 < 20)
{
Console.WriteLine(“number1 é menor que 20”);
}
}
Como as duas condições resultam em true, esse código geraria a seguinte saída:
number1 é maior que 5
number1 é menor que 20
Mas, o que aconteceria se o valor de number1 fosse 25 em vez de 10 antes da execução
da instrução if externa? Nesse caso, a primeira expressão booliana resultará em true,
mas a segunda expressão booliana resultará em false e a saída a seguir será gerada:
number1 é maior que 5

A instrução if-else
A instrução if-else permite que seu programa execute uma ação se a expressão
booliana resultar em true e uma ação diferente se ela resultar em false.

Execute as etapas a seguir para criar um programa de exemplo que use a instrução if-else.

USAR A INSTRUÇÃO IF-ELSE

PREPARE-SE. Para usar a instrução if-else, faça o seguinte:


1. Adicione um novo projeto de aplicativo de console (denominado ifelse_Statement)
à solução Lesson01.
14 | Lição 1

2. Adicione o código a seguir ao método Main da classe Program.cs:


TestIfElse(10);
3. Em seguida, adicione o método a seguir à classe Program.cs:
public static void TestIfElse(int n)
{
if (n < 10)
{
Console.WriteLine(“n é menor que 10”);
}
else if (n < 20)
{
Console.WriteLine(“n é menor que 20”);
}
else if (n < 30)
{
Console.WriteLine(“n é menor que 30”);
}
else
{
Console.WriteLine(“n é maior ou igual a 30”);
}
}
4. Selecione Depurar > Iniciar sem Depurar ou pressione Ctrl+F5.
5. Você verá a saída do programa em uma janela de comando.
6. Pressione uma tecla para fechar a janela de comando.
7. Modifique o código do método Main para chamar o método TestIfElse com valores
diferentes. Observe como uma ramificação diferente da instrução if-else é executada
como resultado das suas alterações.
PAUSE. Deixe o projeto aberto para ser usado no próximo exercício.
Aqui, o código no método TestIfElse combina várias instruções if-else para testar várias
condições. Por exemplo, se o valor de n for 25, as duas primeiras condições (n < 10 e
n < 20) resultarão em false, mas a terceira condição (n < 30) resultará em true. Como
resultado, o método imprimirá esta saída:
n é menor que 30
Esse programa C# é equivalente ao fluxograma mostrado na figura 1-5.
Introdução à programação | 15

Figura 1-5
Fluxograma equivalente da
instrução if-else de exemplo

A instrução switch
A instrução switch permite a ramificação multidirecional. Em muitos casos, o uso
da instrução switch pode simplificar uma combinação complexa de instruções if-else.

TOME NOTA
* A instrução switch consiste na palavra-chave switch, seguida de uma expressão entre
A expressão após parênteses e um bloco switch. O bloco switch pode incluir uma ou mais instruções case
a instrução case deve ou uma instrução default. Quando a instrução switch é executada, dependendo do valor
ser uma expressão da expressão switch, o controle é transferido para uma instrução case correspondente.
constante e deve Se a expressão não coincidir com nenhuma das instruções case, o controle será transferido
ser do tipo de dados para a instrução default. A expressão switch deve estar entre parênteses.
correspondente
à expressão switch. Execute as etapas a seguir para criar um programa que use a instrução switch para avaliar
expressões simples.

USAR A INSTRUÇÃO SWITCH

PREPARE-SE. Para usar a instrução switch, faça o seguinte:


1. Adicione um novo projeto de aplicativo de console denominado switch_Statement
à solução Lesson01.
2. Adicione o código a seguir ao método Main da classe Program.cs:
TestSwitch(10, 20, ’+’);
16 | Lição 1

3. Adicione o método a seguir à classe Program.cs:


public static void TestSwitch(int op1, int op2, char opr)
{
int result;
switch (opr)
{
case '+':
result = op1 + op2;
break;
case '-':
result = op1 − op2;
break;
case '*':
result = op1 * op2;
break;
case '/':
TOME NOTA
* result = op1 / op2;
Os métodos Console. break;
Write e Console. default:
WriteLine podem usar
Console.WriteLine(“Operador desconhecido”);
cadeias de caracteres
de formato como return;
“Resultado: {0}” para }
formatar a saída. Aqui, Console.WriteLine(“Resultado: {0}”, result);
a cadeia de caracteres
return;
{0} representa o
primeiro argumento }
fornecido após a 4. Selecione Depurar > Iniciar sem Depurar ou pressione Ctrl+F5.
cadeia de caracteres de 5. Você verá a saída do programa em uma janela de comando.
formato. No método
6. Pressione uma tecla para fechar a janela de comando.
TestSwitch, a cadeia de
caracteres de formato 7. Modifique o código do método Main para chamar o método TestSwitch com valores
“{0}” é substituída pelo diferentes. Observe como uma ramificação diferente da instrução switch é executada
valor do argumento como resultado das suas alterações.
seguinte, result. PAUSE. Deixe o projeto aberto para ser usado no próximo exercício.
Aqui, o método TestSwitch aceita dois operandos (op1 e op2) e um operador (opr)
e avalia a expressão resultante. O valor da expressão switch é comparado com as
instruções case no bloco switch. Se houver uma correspondência, as instruções após
o case correspondente serão executadas. Se nenhuma das instruções case corresponder,
o controle será transferido para a ramificação padrão opcional.
Observe que há uma instrução break após cada case. A instrução break encerra a instrução
switch e transfere o controle para a próxima instrução fora do bloco switch. Usar break
garante que apenas uma ramificação seja executada, além de ajudar a evitar erros de
programação. Na verdade, se você especificar o código após a instrução case, deverá
incluir break (ou outra instrução de transferência de controle, como return) para se
certificar de que o controle não passe de um rótulo case para outro.
Introdução à programação | 17

No entanto, se nenhum código for especificado após a instrução case, não haverá
problema se o controle passar para a instrução case subsequente. O código a seguir
demonstra como isso pode ser útil:
public static void TestSwitchFallThrough()
{
DateTime dt = DateTime.Today;
switch (dt.DayOfWeek)
{
case DayOfWeek.Monday:
case DayOfWeek.Tuesday:
case DayOfWeek.Wednesday:
case DayOfWeek.Thursday:
case DayOfWeek.Friday:
Console.WriteLine(“Hoje é um dia de semana”);
break;
default:
Console.WriteLine(“Hoje é um dia de semana”);
break;
}
PRONTO PARA
CERTIFICAÇÃO }
Você compreende
o significado de Aqui, se o valor da expressão dt.DayofWeek for DayOfWeek.Monday, o primeiro case
estruturas de decisão terá correspondência, mas, como nenhum código (ou uma instrução de transferência
do computador, como de controle) é especificado, a execução passará para a próxima instrução, resultando
ramificação e repetição? na exibição da mensagem “Hoje é um dia de semana” na janela de comando.
1.2

Você pode decidir se deseja usar instruções if-else ou uma instrução switch com base
na natureza da comparação e da legibilidade do código. Por exemplo, o código do
método TestIfElse toma decisões com base nas condições mais adequadas de uso
TOME NOTA
* com as instruções if-else. No método TestSwitch, as decisões são baseadas em valores
constantes, portanto, o código é muito mais legível quando é escrito como uma
instrução switch.

■ Noções básicas sobre estruturas de repetição

C# tem quatro estruturas de controle diferentes que permitem que os programas


O RESULTADO executem tarefas repetitivas: o loop while, o loop do-while, o loop for e o loop foreach.

Essas instruções de controle de repetição podem ser usadas para executar as instruções
no corpo do loop várias vezes, dependendo do critério de término do loop.
Um loop também pode ser terminado usando uma das várias instruções de transferência
de controle que transferem o controle fora do loop. Essas instruções são break, goto,
return ou throw. Finalmente, a instrução continue pode ser usada para passar o controle
para a próxima iteração do loop sem sair do loop.
Noções básicas sobre o loop while
O loop while executa um bloco de instruções repetidamente até que uma expressão
booliana especificada retorne false.
18 | Lição 1

A forma geral do loop while é esta:


while (boolean test)
TOME NOTA
* statement
Com o loop while,
Aqui, um teste booliano é realizado no início do loop. Se o teste resultar em true, o corpo
o teste booliano deve ser
do loop será executado e o teste será realizado novamente. Se o teste resultar em false,
colocado entre parênteses.
o loop terminará e o controle será transferido para a próxima instrução após o loop.
Se mais de uma instrução
precisar ser executada Como o teste booliano é realizado antes da execução do loop, é possível que o corpo
como parte do loop de um loop while nunca seja executado. Isso ocorrerá se o teste resultar em false
while, elas deverão ser na primeira vez.
colocadas juntas e entre
Execute as etapas a seguir para criar um programa que use o loop while.
chaves.

USAR O LOOP WHILE

PREPARE-SE. Para usar o loop while, execute as seguintes tarefas:


1. Adicione um novo projeto de aplicativo de console denominado while_Statement
à solução Lesson01.
2. Adicione o código a seguir ao método Main da classe Program.cs:
WhileTest();
3. Adicione o método a seguir à classe Program.cs:
private static void WhileTest()
{
int i = 1;
while (i <= 5)
{
Console.WriteLine(“O valor de i = {0}”, i);
i++;
}
}
4. Selecione Depurar > Iniciar sem Depurar ou pressione Ctrl+F5.
5. Você verá a saída do programa em uma janela de comando.
6. Pressione uma tecla para fechar a janela de comando.
PAUSE. Deixe o projeto aberto para ser usado no próximo exercício.
Neste exercício, a variável i recebe o valor 1. Em seguida, a condição no loop while
é avaliada. Como a condição é true (1 < = 5), o código dentro do bloco da instrução while
é executado. O valor de i é escrito na janela de comando e, em seguida, o valor de i é
aumentado em 1 e torna-se 2. O controle, então, retorna para a instrução while,
e a condição é avaliada novamente. Como a condição continua sendo true (2 < = 5),
o bloco de instrução é executado novamente. O loop continua até que o valor de i passa
a ser 6 e a condição no loop while torna-se false (6 < = 5). O método acima, quando
executado, gera esta saída:
O valor de i = 1
O valor de i = 2
O valor de i = 3
O valor de i = 4
O valor de i = 5
O fluxograma equivalente desse loop while é mostrado na figura 1-6.
Introdução à programação | 19

Figura 1-6
Fluxograma equivalente
do loop while de exemplo

A instrução no loop, que incrementa o valor de i, desempenha um papel fundamental.


Se você perder essa instrução, a condição de término nunca será alcançada e, como
resultado, você terá um loop interminável.
Na maioria dos casos, para ter um loop while bem-projetado, você deve ter três partes:
TOME NOTA
* 1. Inicializador: o inicializador define o contador de loops para o valor inicial correto.
Para evitar um loop No exemplo acima, a variável i é definida como 1 antes do início do loop.
infinito, você deve 2. Teste de loop: o teste de loop especifica a condição de término do loop. No exemplo
se certificar de que acima, a expressão (i < = 5) é a expressão de condição.
seu loop while seja
3. Expressão de término: a expressão de término altera o valor do contador de loops,
projetado de modo
de modo que a condição de término seja alcançada. No exemplo acima, a expressão
a terminar.
i++ é a expressão de término.

Noções básicas sobre o loop do-while


O loop do-while executa um bloco de instruções repetidamente até que uma
expressão booliana especificada retorne false. O loop do-while testa a condição no
TOME NOTA
* fim do loop.
Com o loop do-while,
o teste booliano deve
O loop do-while é semelhante ao loop while mas, ao contrário desse loop, o corpo do loop
ser colocado entre
do-while deve ser executado pelo menos uma vez.
parênteses. Se mais
de uma instrução A forma geral do loop do-while é esta:
precisar ser executada
do
como parte de um
loop do-while, essas statement
instruções deverão ser while (boolean test);
colocadas juntas e entre
Execute as etapas a seguir para criar um programa que use o loop do-while.
chaves.
20 | Lição 1

USAR O LOOP DO-WHILE

PREPARE-SE. Para usar o loop do-while, execute as seguintes tarefas:


1. Adicione um novo projeto de aplicativo de console denominado dowhile_Statement
à solução Lesson01.
2. Adicione o código a seguir ao método Main da classe Program.cs:
DoWhileTest();
3. Adicione o método a seguir à classe Program.cs:
private static void DoWhileTest()
{
int i = 1;
do
{
Console.WriteLine(“O valor de i = {0}”, i);
i++;
}
while (i <= 5);
}
4. Selecione Depurar > Iniciar sem Depurar ou pressione Ctrl+F5.
5. Você verá a saída do programa em uma janela de comando.
6. Pressione uma tecla para fechar a janela de comando.
PAUSE. Deixe o projeto aberto para ser usado no próximo exercício.
Neste exercício, depois que a variável i receber o valor 1, o controle entrará diretamente
em loop. Neste ponto, o código do bloco da instrução do-while é executado.
Especificamente, o valor de i é escrito na janela de comando e aumentado em 1, tornando-
se 2. Em seguida, a condição do loop do-while é avaliada. Como a condição continua
sendo true (2 < = 5), o controle retorna para a instrução do-while e o bloco de instrução é
executado novamente. O loop continua até que o valor de i passa a ser 6 e a condição do
loop do-while torna-se false (6 < = 5). O método acima, quando executado, gera a mesma
saída que o método WhileTest.
A escolha entre um loop while e um loop do-while depende se você deseja que o loop seja
executado pelo menos uma vez. Se você quiser que o loop seja executado zero ou mais
vezes, escolha o loop while. Por outro lado, se você quiser que o loop seja executado uma
ou mais vezes, escolha o loop do-while.

Noções básicas sobre o loop for


TOME NOTA
* O loop for combina os três elementos de iteração — a expressão de inicialização, a
Com o loop for, as três
expressão da condição de término e a expressão de contagem — em um código mais
expressões de controle
legível.
devem ser colocadas
entre parênteses. Se
mais de uma instrução O loop for é semelhante ao loop while; ele permite que uma instrução ou um bloco de
precisar ser executada instrução seja executado repetidamente até que uma expressão resulte em false. A forma
como parte do loop, geral do loop for é esta:
essas instruções
deverão ser colocadas for (init-expr; cond-expr; count-expr)
juntas e entre chaves. statement
Introdução à programação | 21

Como você pode ver, o loop for combina as três expressões de controle essencial de uma
iteração. Isso resulta em um código mais legível. O loop for é especialmente útil para criar
iterações que devem ser executadas um número especificado de vezes.
Execute as etapas a seguir para criar um programa que use o loop for.

USAR O LOOP FOR

PREPARE-SE. Para usar o loop for, execute as seguintes tarefas:


1. Adicione um novo projeto de aplicativo de console denominado for_Statement
à solução Lesson01.
2. Adicione o código a seguir ao método Main da classe Program.cs:
ForTest();
3. Adicione o método a seguir à classe Program.cs:
private static void ForTest()
{
for(int i = 1; i<= 5; i++)
{
Console.WriteLine(“O valor de i = {0}”, i);
}
}
4. Selecione Depurar > Iniciar sem Depurar ou pressione Ctrl+F5.
5. Você verá a saída do programa em uma janela de comando.
6. Pressione uma tecla para fechar a janela de comando.
PAUSE. Deixe o projeto aberto para ser usado no próximo exercício.
O método ForTest, quando executado, gera a mesma saída que o método WhileTest.
Aqui, a variável i é criada dentro do escopo do loop for e seu valor é atribuído a 1.
O loop continuará enquanto o valor de i for menor ou igual a 5. Após o corpo do loop,
count-expr será avaliado e o controle retornará a cond-expr.
Todas as expressões de controle de um loop for são opcionais. Por exemplo, você pode
omitir todas as expressões para criar um loop infinito como este:
for (; ;)
{
//não fazer nada
}

Noções básicas sobre o loop foreach


O loop foreach é útil para iterar nos elementos de uma coleção.

O loop foreach pode ser considerado uma versão aprimorada do loop for para iteração em
coleções, como matrizes e listas. A forma geral da instrução foreach é esta:
foreach (ElementType element in collection)
statement
22 | Lição 1

As expressões de controle para o loop foreach devem ser colocadas entre parênteses.
Se mais de uma instrução precisar ser executada como parte do loop, essas instruções
deverão ser colocadas juntas e entre chaves.
Execute as etapas a seguir para criar um programa que mostra como o loop foreach
fornece uma maneira simples de iterar em uma coleção.

USAR O LOOP FOREACH

PREPARE-SE. Para usar o loop foreach, faça o seguinte:


1. Adicione um novo projeto de aplicativo de console denominado foreach_Statement
à solução Lesson01.
2. Adicione o código a seguir ao método Main da classe Program.cs:
ForEachTest();
3. Adicione o método a seguir à classe Program.cs:
private static void ForEachTest()
{
int[] numbers = { 1, 2, 3, 4, 5 };
foreach (int i in numbers)
{
Console.WriteLine(“O valor de i = {0}”, i);
}
}
4. Selecione Depurar > Iniciar sem Depurar ou pressione Ctrl+F5.
5. Você verá a saída do programa em uma janela de comando.
6. Pressione uma tecla para fechar a janela de comando.
PAUSE. Deixe o projeto aberto para ser usado no próximo exercício.
Neste exercício, o loop é iterado sequencialmente em cada elemento da coleção, numera
-o e exibe-o na janela de comando. Esse método gera o mesmo resultado que o método
ForTest.

Noções básicas sobre recursão


Recursão é uma técnica de programação em que um método evoca a si mesmo para
calcular um resultado.

A recursão e a iteração estão relacionadas. Você pode escrever um método que gera os
mesmos resultados usando a recursão ou a iteração. Geralmente, a natureza do problema
em si o ajudará a optar por uma solução iterativa ou recursiva. Por exemplo, uma solução
recursiva é mais elegante quando você pode definir a solução de um problema em termos
de uma versão menor do mesmo problema.
Para compreender melhor esse conceito, tomemos o exemplo da operação fatorial
de matemática. A definição recursiva geral para o fatorial n (escrito n!) é a seguinte:
1 if n = 0,
n! =
(n − 1)! × n if n > 0.
De acordo com essa definição, se o número for 0, o fatorial será um. Se o número for
maior que zero, o fatorial será o número multiplicado pelo fatorial do próximo número
Introdução à programação | 23

menor. Por exemplo, você pode dividir 3! desta forma: 3! = 3 * 2! —> 3 * 2 * 1! —> 3 *
2 * 1 * 0! —> 3 * 2 * 1 * 1 —> 6.
Execute as etapas a seguir para criar um programa que apresente uma solução recursiva
para um problema de fatorial.

USAR O MÉTODO RECURSIVO

PREPARE-SE. Para usar o método recursivo, execute as seguintes ações:


1. Adicione um novo projeto de aplicativo de console denominado RecursiveFactorial
à solução Lesson01.
2. Adicione o código a seguir ao método Main da classe Program.cs:
Factorial(5);
3. Adicione o método a seguir à classe Program.cs:
public static int Factorial(int n)
{
if (n == 0)
{
return 1; //caso base
}
else
{
return n * Factorial(n - 1); //caso recursivo
}
}
4. Selecione Depurar > Iniciar sem Depurar ou pressione Ctrl+F5.
5. Você verá a saída do programa em uma janela de comando.
6. Pressione uma tecla para fechar a janela de comando.
7. Modifique o método Main para passar um valor diferente para o método Factorial
e observe os resultados.
PAUSE. Deixe o projeto aberto para ser usado no próximo exercício.
Conforme foi visto no exercício acima, uma solução recursiva tem duas partes distintas:
• Caso base: essa é a parte que especifica a condição de término e não chama
o método novamente. O caso base no método Factorial é n = = 0. Se você não
PRONTO PARA
CERTIFICAÇÃO tiver um caso base em seu algoritmo recursivo, crie uma recursão infinita. Uma
Você consegue recursão infinita fará com que o computador fique sem memória e gere uma exceção
identificar os métodos StackOverflowException.
apropriados para
• Caso recursivo: essa é a parte que move o algoritmo para o caso base. O caso
tratamento de
repetição? recursivo no método Factorial é a outra parte, onde você chamar o método
1.3 novamente, mas com um valor menor progredindo para o caso base.

■ Noções básicas sobre tratamento de exceções

O .NET Framework oferece suporte ao tratamento de exceções padrão para identificar


O RESULTADO
e lidar com erros de tempo de execução. Nesta seção, você aprenderá a usar as
palavras-chave try, catch e finally para lidar com exceções.
24 | Lição 1

Uma exceção é uma condição de erro inesperada que ocorre durante a execução de um
programa C#. Quando isso ocorre, o tempo de execução cria um objeto para representar
o erro e “lança-o”. A menos que você “capture” a exceção, escrevendo um código
de tratamento de exceção adequado, a execução do programa será encerrada.
Por exemplo, se você tentar dividir um número inteiro por zero, a exceção
DivideByZeroException será gerada. No .NET Framework, uma exceção é representada
usando um objeto da classe System.Exception ou uma de suas classes derivadas. Há
classes de exceção predefinidas que representam várias situações de erro que ocorrem
com frequência, como a DivideByZeroException mencionada anteriormente. Se estiver
criando um aplicativo que precisa gerar qualquer exceção específica do aplicativo, você
deverá criar uma classe de exceção personalizada derivada da classe System.Exception.

Tratamento de exceções
Para lidar com exceções, coloque o código que gera as exceções dentro de um bloco
try e coloque o código que lida com as exceções dentro de um bloco catch.

O exercício a seguir mostra como usar um bloco try-catch para lidar com uma exceção.
O exercício utiliza o método File.OpenText para abrir um arquivo de disco. Essa instrução
será executada sem problemas no caso normal, mas, se o arquivo (ou a permissão para ler
o arquivo) estiver ausente, uma exceção será gerada.

LIDAR COM EXCEÇÕES

PREPARE-SE. Para lidar com exceções, execute as seguintes etapas:


1. Adicione um novo projeto de aplicativo de console denominado HandlingExceptions
à solução Lesson01.
2. Adicione o código a seguir ao método Main da classe Program.cs:
ExceptionTest();
3. Adicione o método a seguir à classe Program.cs:
private static void ExceptionTest()
{
StreamReader sr = null;
try
{
sr = File.OpenText(@“c:\data.txt”);
Console.WriteLine(sr.ReadToEnd());
}
catch (FileNotFoundException fnfe)
{
Console.WriteLine(fnfe.Message);
}
catch(Exception ex)
{
Console.WriteLine(ex.Message);
}
}
Introdução à programação | 25

4. Crie um arquivo de texto (“data.txt”) usando o Bloco de Notas ou o Visual Studio na


unidade C:. É aceitável para criar o arquivo em um local diferente, mas, se você fizer
isso, lembre-se de modificar o local do arquivo no programa. Insira um texto
TOME NOTA
* no arquivo.
A classe StreamReader 5. Selecione Depurar > Iniciar sem Depurar ou pressione Ctrl+F5.
faz parte do namespace
6. Você verá o conteúdo do arquivo de texto exibido em uma janela de comando.
System.IO. Ao executar
esse código, você 7. Pressione uma tecla para fechar a janela de comando.
precisará adicionar uma 8. Exclua o arquivo data.txt e execute o programa novamente. Desta vez, você receberá
diretiva using para o uma exceção FileNotFoundException, e uma mensagem apropriada será exibida na
namespace System.IO. janela de saída.

No método ExceptionTest, é incorreto alterar a ordem dos dois blocos catch.


*
TOME NOTA As exceções mais específicas precisam ser listadas antes das exceções genéricas,
caso contrário, você receberá erros de compilação.

PAUSE. Deixe o projeto aberto para ser usado no próximo exercício.


Para lidar com uma exceção, inclua as instruções que possam causar a exceção em um
bloco try e, em seguida, adicione blocos catch para lidar com uma ou mais exceções.
Neste exemplo, além de lidar com a exceção FileNotFoundException mais específica,
estamos também usando um bloco catch com exceções mais genéricas para identificar todas
as outras exceções. O nome da exceção para um bloco catch deve ser colocado
entre parênteses. As instruções que são executadas quando uma exceção é identificada
TOME NOTA
* devem ser colocadas entre chaves.
Um bloco try deve ter
pelo menos um bloco A execução do código para quando uma exceção ocorre. O tempo de execução procura por
catch ou um bloco uma instrução catch que corresponda ao tipo de exceção. Se o primeiro bloco catch não
identificar a exceção gerada, o controle será movido para o próximo bloco catch e assim por
finally associado a ele.
diante. Se a exceção não for tratada no método, o tempo de execução verificará a instrução
catch no código de chamada e continuará para o restante da pilha de chamadas.

Usando try-catch-finally
O bloco finally é usado associado ao bloco try. O bloco finally é sempre executado,
mesmo que uma exceção seja gerada. O bloco finally é geralmente usado para
escrever um código de limpeza.

Quando uma exceção ocorre, ela geralmente significa que algumas linhas de código após
a exceção não foram executadas. Isso pode deixar seu programa em um estado instável ou
sujo. Para evitar essas situações, você pode usar a instrução finally para garantir que um
código de limpeza específico seja sempre executado. Isso pode envolver o encerramento
de conexões, a liberação de recursos ou a definição de variáveis para seus valores
esperados. Vamos examinar um bloco finally no exercício a seguir.

USAR TRY-CATCH-FINALLY

PREPARE-SE. Para usar a instrução try-catch-finally, execute as seguintes etapas:


1. Adicione um novo projeto de aplicativo de console denominado trycatchfinally
à solução Lesson01.
2. Adicione o código a seguir ao método Main da classe Program.cs:
TryCatchFinallyTest();
26 | Lição 1

3. Adicione o método a seguir à classe Program.cs:


private static void TryCatchFinallyTest()
{
StreamReader sr = null;
try
{
sr = File.OpenText(“data.txt”);
Console.WriteLine(sr.ReadToEnd());
}
catch (FileNotFoundException fnfe)
{
Console.WriteLine(fnfe.Message);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
finally
{
if (sr != null)
{
sr.Close();
}
}
}
4. Crie um arquivo de texto (“data.txt”) usando o Bloco de Notas ou o Visual Studio
na unidade C:. É aceitável para criar o arquivo em um local diferente, mas, se você
fizer isso, lembre-se de modificar o local do arquivo no programa. Insira um texto
no arquivo.
5. Selecione Depurar > Iniciar sem Depurar ou pressione Ctrl+F5.
6. Você verá o conteúdo do arquivo de texto exibido em uma janela de comando.
7. Pressione uma tecla para fechar a janela de comando.
PRONTO PARA CERTIFICAÇÃO 8. Exclua o arquivo data.txt e execute o programa novamente. Desta vez, você receberá
Você sabe como lidar com uma exceção FileNotFoundException, e uma mensagem apropriada será exibida na
erros nos seus programas? janela de saída.
1.4 Neste exercício, o programa certifica-se de que o objeto StreamReader esteja encerrado
e todos os recursos sejam liberados quando a operação for concluída. O código no bloco
finally é executado, mesmo que uma exceção seja gerada.

RESUMO DE HABILIDADES

Nesta lição, você aprendeu que:


• U m algoritmo é um conjunto de etapas ordenadas e finitas para solucionar um
problema específico. Você talvez considere útil expressar um algoritmo como um
fluxograma ou uma tabela de decisões antes de desenvolver um programa de
computador formal.
• A linguagem de programação C# é uma parte do .NET Framework e beneficia-se
do suporte ao tempo de execução e das bibliotecas de classe fornecidas
pelo .NET Framework.
• Main é um método especial, pois também serve como um ponto de entrada para um
programa. Quando o tempo de execução executa um programa, ele sempre começa
no método Main.
Introdução à programação | 27

• A s variáveis em C# são espaços reservados usados para armazenar valores.


Uma variável tem um nome e um tipo de dados. O tipo de dados de uma
variável determina qual valor ele pode conter e qual tipo de operações pode
ser executado nele.
• Os operadores são símbolos, como +, -, *, e /, que especificam qual operação
executar em um ou mais operandos antes de retornar um resultado.
• As instruções if-else permitem que seu programa execute uma ação se a expressão
booliana resultar em true e uma ação diferente se ela resultar em false.
• A instrução switch permite a ramificação multidirecional. Em muitos casos, o uso da
instrução switch pode simplificar uma combinação complexa de instruções if-else.
• C# tem quatro estruturas de controle diferentes que permitem que os programas
executem tarefas repetitivas: o loop while, o loop do-while, o loop for e o loop
foreach.
• Os loops while e do-while executam repetidamente um bloco de instruções até que
uma expressão booliana especificada seja retornada como false. O loop do-while
testa a condição no fim do loop.
• O loop for combina os três elementos da iteração — a instrução de inicialização,
a condição de encerramento e a instrução de incremento/decremento — para um
código mais legível.
• O loop foreach é útil para iterar nos elementos de uma coleção.
• Recursão – é uma técnica de programação em que um método evoca a si mesmo
para calcular um resultado.

■ Avaliação de conhecimento
• O .NET Framework oferece suporte ao tratamento de exceções padrão para
identificar e lidar com erros de tempo de execução. Para lidar com exceções, coloque
o código que gera as exceções dentro de um bloco try e coloque o código que lida
com as exceções dentro de um bloco catch.
• O bloco finally é usado associado ao bloco try. O bloco finally é sempre executado,
mesmo que uma exceção seja gerada. O bloco finally é geralmente usado para
escrever um código de limpeza.

Preencha as lacunas

Complete as frases a seguir com a(s) palavra(s) correta(s) nas lacunas fornecidas.
1. A instrução seleciona para execução uma lista de instruções que tem um
rótulo associado que corresponde ao valor de uma expressão.
2. O loop testa a condição no fim do loop, e não no início.
3. O único operador que usa três argumentos é o operador.
4. O loop é a maneira mais compacta de iterar nos itens de uma coleção.
5. Em um computador de 32 bits, uma variável do tipo de dados int ocupa
bytes de memória.
28 | Lição 1

6. Para acessar o primeiro elemento de uma matriz, use um índice de .


7. é uma técnica de programação em que um método chama a si mesmo para
calcular um resultado.
8. são campos de dados ou variáveis locais cujo valor não pode ser
modificado.
9. Quando um algoritmo envolve um grande número de condições, um(a) é um
formato compacto e legível para a apresentação do algoritmo.
10. Um(a) é uma representação gráfica de um algoritmo.

Múltipla escolha

Assinale a letra que corresponde à melhor resposta.


1. Escreva o seguinte trecho de código:
int n = 20;
int d = n++ + 5;
Qual será o valor de d após a execução deste trecho de código?
a. 25
b. 26
c. 27
d. 28
2. Escreva o seguinte trecho de código:
private static void WhileTest()
{
int i = 1;
while (i < 5)
{
Console.WriteLine(“O valor de i = {0}”, i);
i++;
}
}
Quantas vezes o loop while será executado neste trecho de código?
a. 0
b. 1
c. 4
d. 5
3. Escreva o seguinte trecho de código:
int number1 = 10;
int number2 = 20;
if (number2 > number1)
Console.WriteLine(“number1”);
Console.WriteLine(“number2”);

Qual saída será exibida após a execução deste trecho de código?


a. number1
b. number2
c. number1
Introdução à programação | 29

number2
d. number2
number1
4. Em uma instrução switch, se nenhuma das instruções de caso coincidir com a
expressão switch, o controle será transferido para qual instrução?
a. break
b. continue
c. default
d. return
5. Você precisa escrever um código que encerre uma conexão com um banco de dados
e precisa assegurar que esse código seja sempre executado, mesmo que ocorra ou não
uma exceção. Onde você deve escrever esse código?
a. Dentro de um bloco try
b. Dentro de um bloco catch
c. Dentro de um bloco finally
d. Dentro do método Main
6. Você precisa armazenar valores entre 0 e 255. Também precisa garantir que seu
programa minimize o uso de memória. Que tipo de dados você deve usar para
armazenar esses valores?
a. byte
b. char
c. short
d. Int
7. Se você não tiver um caso base case no seu algoritmo recursivo, crie uma recursão
infinita. Uma recursão infinita levará o programa a gerar uma exceção. Que exceção
será gerada nesse caso?
a. OutOfMemoryException
b. StackOverflowException
c. DivideByZeroException
d. InvalidOperationException
8. Você está aprendendo a desenvolver algoritmos repetitivos em C#. Escreva o seguinte
método:
private static void ForTest()
{
for(int i = 1; i < 5;)
{
Console.WriteLine(“O valor de i = {0}”, i);
}
}
Quantas repetições o loop for executará nesse código?
a. 0
b. 4
c. 5
d. Repetições infinitas
9. Qual dos seguintes recursos C# você deve usar para organizar um código e criar tipos
globalmente exclusivos?
a. Montagem
b. Namespace
30 | Lição 1

■ Avaliação da competência
c. Classe
d. Tipo de dados
10. Você escreve o seguinte trecho de código:
int[] numbers = {1, 2, 3, 4};

Quantidade < 10 S N N N
Quantidade < 50 S S N N
Quantidade < 100 S S S N
Desconto 5% 10% 15% 20%

int val = numbers[1];


Você também cria uma variável do tipo RectangleHandler como esta:
RectangleHandler handler;
Introdução à programação | 31

■ Avaliação de proficiência
Qual é o valor da variável val após a execução desse trecho de código?
a. 1
b. 2
c. 3
d. 4

Cenário 1-1: Como converter uma tabela de decisões em um programa C#


Você está desenvolvendo um aplicativo de faturamento que calcula porcentagens de
desconto com base na quantidade comprada de um produto. A lógica para calcular
descontos é listada na tabela de decisões a seguir. Se você precisar elaborar um método
C# que use a mesma lógica para calcular o desconto, como você redigiria esse programa?

Cenário 1-2: Como converter um fluxograma em um programa C#


Você está desenvolvendo uma biblioteca de funções matemáticas. Primeiro você
desenvolve o seguinte fluxograma para descrever o algoritmo de cálculo do fatorial
de um número. E precisa elaborar um programa C# equivalente para esse fluxograma.
Como você escreveria esse programa?

Cenário 1-3: Tratamento de exceções


Você está escrevendo código para uma biblioteca aritmética simples. Você decide criar
um método denominado Divide que usa dois argumentos, x e y, e retorna o valor de x/y.
Você precisa identificar qualquer exceção aritmética que possa ser gerada por erros em
conversões aritméticas, de transmissão ou de tipo de dados. Também precisa identificar
qualquer outro tipo de exceção gerada pelo código. Para cumprir esse requisito, você
precisa criar um código de tratamento de exceções bem estruturado. Como você escreveria
esse programa?

Cenário 1-4: Como criar um algoritmo recursivo


Você está desenvolvendo uma biblioteca de funções utilitárias para o seu aplicativo.
Precisa elaborar um método que receba um número inteiro e conte quantos dígitos
significativos existem nele. Precisa também criar um programa recursivo para resolver
esse problema. Como você escreveria esse programa?
2 LIÇÃO
Introdução à
­programação
­orientada a objeto
M AT R I Z D E H A B I L I D A D E S D A L I Ç Ã O

Habilidades/Conceitos Objetivo do exame MTA Número do objetivo do


exame MTA
Noções básicas sobre objetos Compreender os conceitos 2,1
básicos de classes.
Noções básicas sobre Compreender o armazenamento do 1,1
valores e referências computador e os tipos de dados.
Noções básicas sobre Compreender o encapsulamento. 2,4
encapsulamento
Noções básicas sobre herança Compreender a herança. 2,2
Noções básicas sobre polimorfismo Compreender o polimorfismo. 2,3
Noções básicas sobre interfaces Compreender o encapsulamento. 2,4

P R I N C I PA I S T E R M O S
modificador de acesso encapsulamento polimorfismo
acessadores eventos propriedades
classes abstratas herança tipo de referência
propriedades autoimplementadas interfaces classes seladas
classe método assinatura
construtores namespace números de estáticos
delegados objetos tipo de valor

Você é um desenvolvedor de software da Northwind Corporation. Você trabalha


como parte de uma equipe para desenvolver programas de computador que
­solucionam problemas empresariais complexos. Todos os programas que você
escreve devem ser fáceis de compreender e manter por um longo período. Portanto,
você precisa d­ esenvolver programas usando técnicas que incentivem a colaboração,
a ­extensibilidade e a reutilização de código. Além disso, em vez de pensar em seus
programas principalmente como listas de métodos, você opta por modelá-los em
conceitos de negócios do mundo real, como clientes, produtos, fornecedores e as
interações entre eles.

32
Introdução à programação orientada a objeto | 33

■ Noções básicas sobre objetos

A programação orientada a objeto é uma técnica de programação que utiliza objetos.


Os objetos são estruturas de dados autocontidas que consistem em propriedades,
O RESULTADO métodos e eventos. As propriedades especificam os dados representados por um objeto,
os métodos especificam o comportamento de um objeto e os eventos estabelecem
comunicação entre objetos.

Pensando em uma maneira orientada a objeto

Um objeto de software é conceitualmente semelhante a um objeto do mundo real.

Uma ótima maneira de começar a pensar em uma maneira orientada a objeto é observar os
objetos do mundo real, como carros, telefones, players de música etc. Você notará que todos
esses objetos têm estado e comportamento. Por exemplo, os carros não só têm vários estados
(por exemplo, nome de modelo, cor, velocidade atual, nível de combustível), mas também
diversos comportamentos (como aceleração, freio, mudança de marcha). Da mesma forma,
você perceberá que alguns objetos são simples, enquanto outros são complexos. Os objetos
mais complexos (como um carro) são constituídos por objetos menores que, por sua vez,
têm seu próprio estado e comportamento. Você notará também que, apesar de um carro ser
um objeto complexo, só é necessário conhecer alguns itens para interagir com ele. Ao dirigir
um carro, por exemplo, você simplesmente invoca um comportamento, como aceleração
ou freio; você não tem conhecimento de muitos milhares de detalhes internos do trabalho
­existente sob o capô.
Um objeto de software é conceitualmente semelhante a um objeto do mundo real.
No ambiente de software, um objeto armazena seu estado em campos e expõe seu
­comportamento por meio de métodos. Quando um método é chamado em um objeto, você
obtém uma funcionalidade bem-definida sem precisar se preocupar com a complexidade
interna do objeto ou com o método em si. Esse conceito de ocultar a complexidade
é denominado encapsulamento e é uma das muitas características da programação
orientada a objeto sobre a qual você aprenderá mais nesta lição.

Noções básicas sobre classes

A classe é o modelo do qual são criados os objetos individuais.

No mundo real, os objetos precisam de um modelo que defina como eles devem ser c­ ompilados.
Todos os objetos criados usando o mesmo modelo têm aparência e comportamento semelhantes.
Por exemplo, imagine uma determinada marca e modelo de carro.
No mundo do software, uma classe é o modelo do qual são criados os objetos individuais.
Um objeto também é conhecido como uma instância de uma classe.

CRIAR UMA CLASSE

PREPARE-SE. Antes de iniciar estas etapas, certifique-se de iniciar o Microsoft Visual


Studio e abra um novo projeto de aplicativo de console denominado Lesson02.
Em ­seguida, execute as seguintes tarefas:
1. Adicione uma nova classe do Visual C# denominada Rectangle ao projeto.
2. Substitua o código da classe Rectangle por este:
class Rectangle
{
private double length;
34 | lição 2

private double width;


public Rectangle(double l, double w)
{
length = l;
width = w;
}
public double GetArea()
{
return length * width;
}
}
3. Selecione Compilar > Lesson02 para compilar o projeto. Certifique-se de que não haja
erros.
PAUSE. Deixe o projeto aberto para ser usado no próximo exercício.
TOME NOTA
* Você acabou de criar uma nova classe C# denominada Rectangle. Uma nova classe
Cada classe é uma é definida usando a palavra-chave class. Aqui, a classe Rectangle tem dois campos de
definição de um novo dados, length e width. Esses campos são definidos usando o modificador de acesso ­private.
tipo de dados. Portanto, Um modificador de acesso especifica qual região do código terá acesso a um campo.
uma definição de classe Por exemplo, o modificador de acesso public não limitará o acesso, mas o m ­ odificador
algumas vezes também de acesso private limitará o acesso dentro da classe na qual o campo está definido.
é referida como um tipo.
Essa classe também define um método denominado GetArea. Mas, o que, exatamente,
é um método?
NOÇÕES BÁSICAS SOBRE MÉTODOS

Um método é um bloco de código que contém uma série de instruções.

No mundo do software, um método define as ações ou as operações com suporte de uma


classe. Um método é definido, especificando o nível de acesso, o tipo de retorno, o nome
do método e uma lista opcional de parâmetros entre parênteses, seguidos por um bloco de
código entre chaves. Por exemplo, no exemplo anterior, a classe Rectangle define um único
método denominado GetArea. Para GetArea, o nível de acesso é public, o tipo de retorno
TOME NOTA
* é double, o nome do método é GetArea, a lista de parâmetros está vazia e o bloco de código
O nome de um método, é uma única instrução return.
sua lista de parâmetros
e a ordem dos tipos de Um método pode retornar um valor para o código de chamada. Se um método não pretende
dados dos parâmetros retornar nenhum valor, seu tipo de retorno é especificado pela palavra-chave void. O método
são coletivamente deve usar uma instrução return para retornar um valor. A instrução return t­ermina a
reconhecidos como a execução do método e retorna o valor especificado para o código de chamada. O tipo de
assinatura do método. dados do valor retornado de um método deve coincidir com o tipo de retorno especificado
Uma assinatura de na linha de declaração do método.
método deve ser Para retornar ao exemplo anterior, o tipo de retorno do método GetArea é double, o que significa
exclusiva dentro de que o método GetArea deve retornar um valor do tipo double. O método GetArea atende a esse
uma classe. requisito, retornando a expressão length * width, que é um valor double.
O código a seguir define um método InitFields que usa dois parâmetros do tipo double
e retorna void:
public void InitFields(double l, double w)
{
length = l;
width = w;
}
Introdução à programação orientada a objeto | 35

O método InitFields usa dois parâmetros e os valores de parâmetro para atribuir,


­respectivamente, os campos de dados length e width. Quando o tipo de retorno do método
é void, uma instrução de retorno sem valor pode ser usada. Se uma instrução return não for
usada, como no método InitFields, o método interromperá a execução quando atingir o final
do bloco de código. O método InitFields pode ser usado para inicializar c­ orretamente o
valor dos campos de dados, mas, como você aprenderá na seção a seguir, os construtores já
oferecem uma maneira de inicializar uma classe.

NOÇÕES BÁSICAS SOBRE CONSTRUTORES

Os construtores são usados para inicializar os membros de dados do objeto.

Os construtores são métodos de classe especiais executados quando uma nova instância
de uma classe é criada. Eles são usados para inicializar os membros de dados do objeto.
Eles devem ter exatamente o mesmo nome da classe e não têm um tipo de retorno. Vários
construtores, cada um com uma assinatura exclusiva, podem ser definidos para uma classe.
Um construtor que não usa argumentos é denominado construtor padrão. Se uma classe for
definida sem qualquer construtor, um construtor padrão invisível que não tem absolutamente
nenhuma função será automaticamente gerado.
Muitas vezes, é útil ter construtores adicionais para fornecer outras maneiras de inicializar um
objeto. A classe Rectangle, definida anteriormente, é apenas uma maneira de criar e inicializar
seu objeto: chamando o construtor que aceita dois parâmetros, ambos do tipo de dados padrão.

CRIANDO OBJETOS

Os objetos são criados a partir de modelos definidos por classes.

CRIAR UM OBJETO

PREPARE-SE. Para esta atividade, use o projeto de aplicativo de console (Lesson 02) que
você criou no exercício anterior. Em seguida, execute estas etapas:
1. Modifique o código da classe Program para:
class Program
{
static void Main(string[] args)
{
Rectangle rect = new Rectangle(10.0, 20.0);
double area = rect.GetArea();
Console.WriteLine(“Área do retângulo: {0}”,
area);
}
}
2. Selecione Depurar > Iniciar sem Depuração. Uma janela de console exibirá a área do
retângulo.
3. SALVE seu projeto.
PAUSE. Deixe o projeto aberto para ser usado no próximo exercício.
A classe Rectangle fornece apenas uma única maneira de construir uma instância da classe:
chamando um construtor com dois argumentos do tipo de dados double. Aqui, você pode
criar um objeto usando a palavra-chave new seguida pela chamada do construtor de classe
apropriado.
36 | lição 2

Quando o código for executado, um objeto do tipo Rectangle será criado na memória
TOME NOTA
* heap. Uma referência a essa memória é armazenada dentro da variável rect, e a variável
As classes e os objetos rect é armazenada na pilha. Posteriormente neste bloco de código, você poderá usar rect
são diferentes. Uma para manipular e se referir ao objeto recém-criado.
classe define o modelo
de um objeto, mas não O uso da referência do objeto permite que você acesse os membros de classe. Por exemplo,
é um objeto. Por outro o código chama o método GetArea no objeto, e o valor retornado pelo método é armazenado
lado, um objeto é uma na área variável. Os campos de dados, length e width, do objeto rect não são acessíveis aqui,
instância concreta de pois estão marcados como private na definição de classe.
uma classe, mas não
é uma classe. NOÇÕES BÁSICAS SOBRE PROPRIEDADES

As propriedades permitem que você acesse dados de classe com segurança e flexibilidade.
TOME NOTA
* As propriedades são membros de classe que podem ser acessados como campos de dados,
As propriedades
são muitas vezes mas contêm código, como um método. Em geral, as propriedades são utilizadas para
chamadas de campos expor os campos de dados de uma classe de uma maneira mais controlada. Por exemplo,
“inteligentes”, pois um campo private pode ser exposto por meio de uma propriedade public, mas não
podem incluir código é necessário usar propriedades dessa maneira.
para verificar a Uma propriedade tem dois acessadores, get e set. O acessador get é usado para
consistência ou a retornar o valor de propriedade, e o acessador set é usado para atribuir um novo valor
validade dos dados. à propriedade. Uma propriedade é muitas vezes definida como public e, por convenção,
sempre tem um nome que começa com letra maiúscula. Em contraste, a convenção de
nomeação dos campos de dados private consiste em iniciar com letra minúscula.

CRIAR PROPRIEDADES

USE o projeto que você salvou no exercício anterior. Em seguida, execute as seguintes tarefas:
1. Modifique o código da classe Rectangle como mostrado abaixo. Nesse código,
o construtor é removido e duas propriedades são inseridas:
class Rectangle
{
private double length;
private double width;
public double Length
{
get
{
return length;
}
set
{
if ( value > 0.0)
length = value;
}
}
public double Width
{
get
{
return width;
}
Introdução à programação orientada a objeto | 37

set
{
if ( value > 0.0)
width = value;
}
}
public double GetArea()
{
return length * width;
}
}
2. Em seguida, modifique o código da classe Program para:
class Program
{
static void Main(string[] args)
{
Rectangle rect = new Rectangle();
rect.Length = 10.0;
rect.Width = 20.0;
double area = rect.GetArea();
Console.WriteLine(
“Área do retângulo: {0}”, area);
}
}
3. Selecione Depurar > Iniciar sem Depuração. Uma janela de console exibirá a área do
retângulo.
4. SALVE seu projeto.
PAUSE. Deixe o projeto aberto para ser usado no próximo exercício.
TOME NOTA
* Nesse exercício, você modificou a classe Rectangle para introduzir duas propriedades,
O padrão de Length e Width. As propriedades são muitas vezes definidas com um modificador de
­programação normal acesso public. No código para a propriedade Length, o acessador get simplesmente retorna
é que todos os ­campos o valor do campo de dados length. No entanto, o acessador set verifica o valor atribuído
de dados de uma classe (usando a palavra-chave value) à propriedade e modificará o campo de dados length
sejam declarados apenas se o valor for positivo. Os campos privados length e width também são chamados
como private, e que campos de suporte para as propriedades que respectivamente os expõem.
o acesso a esses A classe Rectangle também não declara qualquer construtor explícito. Nesse caso, os
campos privados usuários da classe (o método Main) precisam usar o construtor padrão e depender das
seja feito através de propriedades para inicializar os dados de classe.
­propriedades públicas
que ­verifiquem os O método Main usa as propriedades Length e Width para definir os dados do objeto rect.
valores dos dados para A tentativa de definir Length ou Width para um valor negativo será ignorada e, nesse
fins de validade. caso, os campos de dados continuarão mantendo seu valor original 0.
Ao definir propriedades, você pode excluir o acessador set ou get. Se não incluir um
acessador set, você não permitirá definir o valor da propriedade e, como resultado, terá uma
propriedade somente leitura. Por outro lado, se não incluir o acessador get, você não poderá
obter o valor da propriedade e, como resultado, terá uma propriedade somente gravação.

NOÇÕES BÁSICAS SOBRE PROPRIEDADES AUTOIMPLEMENTADAS

As propriedades autoimplementadas simplificam as declarações de propriedade.


38 | lição 2

C# introduziu as propriedades autoimplementadas a partir da versão 3 para simplificar


a declaração de propriedade quando não há qualquer lógica adicional especificada nos
acessadores get e set. Por exemplo, sem as verificações de validação, as propriedades
Length e Width são definidas assim:
private double length;
private double width;
public double Length
{
get
{
return length;
}
set
{
length = value;
}
}
public double Width
{
get
{
return width;
}
set
{
width = value;
}
}
Em comparação, com as propriedades autoimplementadas C#, a sintaxe simplificada da
declaração de propriedade passa a ser:
public double Length { get; set; }
public double Width { get; set; }
Nesse caso, os campos de suporte para as propriedades são definidas de forma oculta
e não são diretamente acessíveis pelo código.
As propriedades autoimplementadas usadas com construtores padrão também podem
simplificar a criação e a inicialização de objetos. Por exemplo, agora um objeto pode
ser criado e inicializado desta forma:
static void Main(string[] args)
{
Rectangle rect = new Rectangle
{ Length = 10.0, Width = 20.0 };
Console.WriteLine(
“Área do retângulo: {0}”, rect.GetArea());
}

USANDO A PALAVRA-CHAVE THIS

A palavra-chave this pode ser usada para acessar membros a partir de construtores,
métodos de instância e acessadores de propriedades de instância.
Introdução à programação orientada a objeto | 39

A palavra-chave this é uma referência à instância atual da classe. Você pode usar a
palavra-chave this para se referir a qualquer membro do objeto atual. Por exemplo,
no início deste capítulo, a classe Rectangle foi escrita desta forma:
class Rectangle
{
private double length;
private double width;
public Rectangle(double l, double w)
{
length = l;
width = w;
}
public double GetArea()
{
return length * width;
}
}
No entanto, ela poderia ter sido escrita assim:
class Rectangle
{
private double length;
private double width;
public Rectangle(double l, double w)
{
this.length = l;
this.width = w;
}
public double GetArea()
{
return this.length * this.width;
}
}
Como você pode ver, no segundo exemplo, a palavra-chave this foi usada dentro do
construtor e do método GetArea para se referir aos campos de dados do objeto atual
da classe Rectangle. Embora não tenha sido necessário usar a palavra-chave this nesse
TOME NOTA
* caso, sua utilização fornece mais flexibilidade na nomeação dos parâmetros de método.
Em C#, os caracteres Por exemplo, você poderia definir o construtor da seguinte forma:
// são usados para public Rectangle(double length, double width)
adicionar comentários
{
de linha única ao
código. O texto após os // o comprimento e a largura dos nomes de parâmetros
caracteres // é ignorado // cobrem o comprimento e a largura dos membros de classe
pelo compilador. Os // neste escopo
comentários de várias this.length = length;
linhas começam com os this.width = width;
caracteres /* e terminam
com os caracteres */. }
Dentro do escopo da definição do construtor Rectangle, os nomes length e width agora
se referirão ao parâmetro que está sendo passado. Os nomes dos campos de dados foram
sombreados e só podem ser acessados usando a palavra-chave this.
40 | lição 2

NOÇÕES BÁSICAS SOBRE DELEGADOS

Delegados são tipos especiais usados para encapsular um método com uma
assinatura específica.

Os delegados são objetos especiais que podem conter uma referência a um método com
uma assinatura específica. Um delegado é definido usando a palavra-chave delegate.
Por exemplo, você pode definir um delegado da seguinte forma:
public delegate void RectangleHandler(Rectangle rect);
A definição de delegado especifica a assinatura do método cuja referência pode ser
armazenada por um objeto delegate. Por exemplo, no código acima, você define um
delegado RectangleHandler que pode conter referências a um método que retorna void
e aceita um único parâmetro do tipo Rectangle.
Portanto, se você tiver um método com uma assinatura semelhante, ele será um candidato
ideal para ser atribuído a uma instância delegate. Por exemplo:
public void DisplayArea(Rectangle rect)
{
Console.WriteLine(rect.GetArea());
}
O tipo de delegado pode ser usado para declarar uma variável que pode se referir a
qualquer método com a mesma assinatura do delegado. Por exemplo, você pode dizer:
RectangleHandler handler;
E, em seguida, pode atribuir o método ao delegado usando esta sintaxe:
handler += new RectangleHandler(DisplayArea);
Se preferir, você poderá usar a sintaxe de atalho mostrada abaixo:
handler += DisplayArea;
Observe que a sintaxe usa a operação de adição. Isso significa que você pode associar
mais de um método (de assinatura compatível), criando, assim, uma lista de invocação
de um ou mais métodos.
Finalmente, uma chamada para um delegado pode ser feita por uma sintaxe de chamada
de método, como esta:
Rectangle rect = new Rectangle (10, 20);
handler(rect);
Quando o delegado é chamado dessa forma, ele invoca todos os métodos em sua lista de
invocação. Neste exemplo específico, o objeto handler se refere apenas a um método DisplayArea,
e portanto, o método DisplayArea será invocado com o objeto rect como parâmetro.
Entre várias outras aplicações, os delegados formam a base das declarações de evento,
conforme será discutido na próxima seção.
NOÇÕES BÁSICAS SOBRE EVENTOS

Os eventos são uma maneira de uma classe notificar outras classes ou objetos quando
algo de interesse ocorre. A classe que envia a notificação é chamada de editor do
evento. A classe que recebe a notificação é chamada de assinante do evento.

Os eventos são fáceis de serem compreendidos no contexto de uma GUI (interface gráfica
do usuário). Por exemplo, quando um usuário clica em um botão, ocorre um evento
Click. Vários elementos de interface do usuário podem se inscrever nesse evento e alterar
Introdução à programação orientada a objeto | 41

seu estado visual apropriadamente (por exemplo, alguns controles são habilitados ou
­desabilitados). Nesse tipo de comunicação de evento, os editores de eventos não precisam
saber quais objetos se inscreverão nos eventos que estão sendo gerados.
Os eventos não são limitados apenas à programação da GUI. Na verdade, os eventos
desempenham um papel importante nas bibliotecas de classes do .NET Framework como
uma maneira de os objetos sinalizarem qualquer mudança em seu estado. Você trabalhará
com eventos em praticamente todos os programas.
Ao definir os eventos, você geralmente precisa de duas informações:
• Um delegado que conecte o evento ao seu(s) método(s) handler
• Uma classe que contenha os dados do evento. Em geral, essa classe é derivada da
classe EventArgs
Para definir um evento, você pode usar um delegado personalizado. No entanto, na maioria
dos casos, se o seu evento não tiver dados específicos de evento, a utilização do delegado
predefinido EventHandler será suficiente. O delegado EventHandler é definido desta forma:
public delegate void EventHandler(Object sender, EventArgs e);
Aqui, o parâmetro sender é uma referência ao objeto que gera o evento, e o parâmetro
e é uma referência a um objeto de dados event que não contém dados do evento.
A classe EventArgs é usada pelos eventos que não passam quaisquer informações relacionadas
ao evento para um manipulador de eventos quando um evento é gerado. Se o manipulador
de eventos necessitar de informações relacionadas ao evento, o aplicativo deverá derivar uma
classe da classe EventArgs para armazenar os dados relacionados ao evento.
PUBLICAR E INSCREVER-SE EM EVENTOS

USE o projeto que você salvou no exercício anterior para executar as tarefas a seguir:
1. Modifique o código da classe Rectangle como mostrado abaixo:
class Rectangle
{
public event EventHandler Changed;
private double length;
public double Length
{
get
{
return length;
TOME NOTA
* }
O campo EventArgs. set
Empty representa um {
evento sem dados de length = value;
evento. Esse campo Changed(this, EventArgs.Empty);
equivale a ter uma
}
instância somente leitura
da classe EventArgs. }
}
2. Modifique o código da classe Program para:
class Program
{
static void Main(string[] args)
{
Rectangle r = new Rectangle();
42 | lição 2

r.Changed += new EventHandler(r_Changed);


r.Length = 10;
}
static void r_Changed(object sender, EventArgs e)
{
Rectangle r = (Rectangle)sender;
TOME NOTA
* Console.WriteLine(
O código no método
“Valor alterado: Length = {0}”,
r_Changed usa um
operador de conversão r.Length);
para converter um tipo }
de dados de objeto }
no tipo de dados
Rectangle. A conversão 3. Selecione Depurar > Iniciar sem Depuração. Uma janela de console será exibida
será explicada mostrando que o valor da propriedade Length foi alterado.
posteriormente nesta 4. SALVE seu projeto.
lição, na seção intitulada
“Conversão entre tipos”. PAUSE. Deixe o projeto aberto para ser usado no próximo exercício.
No exemplo que você acabou de concluir, a classe Rectangle define um evento Changed
que é invocado quando a propriedade Length do objeto Rectangle é alterada. O delegado
do evento Changed é do tipo EventHandler. Na classe Rectangle, o evento Changed
é invocado quando o acessador set da propriedade Length é chamado.
Você se inscreve no evento Changed dentro do método Main, anexando o método
r Changed como um manipulador do evento usando o código a seguir:
r.Changed += new EventHandler(r_Changed);
A assinatura do método r_Changed corresponde aos requisitos do delegado EventHandler.
O método r_Changed é invocado assim que você define o valor da propriedade Length no
método Main.
O código acima usa o operador +=, em vez do operador de atribuição simples (=),
para anexar o manipulador de eventos. Ao usar o operador +=, você garante que esse
manipulador de eventos será adicionado a uma lista de manipuladores de eventos já
anexados com o evento. Essa técnica permite que você tenha vários manipuladores de
eventos que podem responder a um evento. Se você usar o operador de atribuição (=) para
atribuir o novo manipulador de eventos, ele substituirá qualquer manipulador de eventos
existente anexado ao evento e, como resultado, o manipulador de eventos recém-anexado
será o único disparado quando o evento for invocado.

NOÇÕES BÁSICAS SOBRE NAMESPACES

Um namespace permite que você organize o código e crie nomes de classe exclusivos.

Um namespace é um elemento de linguagem que permite organizar o código e criar


nomes de classe globais exclusivos. Suponha que você crie uma classe de nome Widget.
É possível que alguma outra empresa também envie um código contendo uma classe de
nome Widget. Nesse caso, como você lidará com a ambiguidade nos nomes? A solução
é organizar o código dentro de um namespace. Uma convenção comum requer o uso do
nome da empresa no namespace. Por exemplo, você pode fazer o seguinte:
namespace CompanyA
{
public class Widget { … }
}
Introdução à programação orientada a objeto | 43

and
namespace CompanyB
{
public class Widget { … }
}
Aqui, a classe do namespace CompanyA pode ser excepcionalmente referida pelo seu
nome de classe totalmente qualificado CompanyA.Widget, enquanto o outro Widget pode
ser identificado exclusivamente como CompanyB.Widget.
O .NET Framework usa namespaces para organizar liberalmente todas as suas classes.
Por exemplo, o namespace System agrupa todas as classes fundamentais. O namespace
System.Data organiza as classes para acesso a dados. O namespace System.Web é usado
para as classes relacionadas à Web.
É evidente que, com o uso de namespaces, você pode acabar tendo nomes de classe
totalmente qualificados realmente longos que podem resultar em programas detalhados
e muita digitação. C# resolve esse inconveniente através da diretiva using. Você pode usar
a diretiva using na parte superior do arquivo de classe desta forma:
using System.Text;
Após incluir a diretiva using para um namespace, você não precisará qualificar totalmente
as classes desse namespace no arquivo.

NOÇÕES BÁSICAS SOBRE MEMBROS ESTÁTICOS

Os membros estáticos pertencem a uma classe, em vez de a objetos individuais.

Os membros de classe discutidos até este momento nesta seção (por exemplo, campos de
dados, métodos e propriedades) operam todos em objetos individuais. Esses membros são
chamados como membros de instância por poderem ser usados apenas depois que uma
instância de uma classe for criada. Por outro lado, a palavra-chave static é usada para declarar
os membros que não pertencem a objetos individuais, mas a uma classe. Esses membros de
classe são chamados como membros estáticos. Um exemplo comum de um membro estático
é o método familiar Main que serve como ponto de entrada para o seu programa.

CRIAR MEMBROS ESTÁTICOS

USE o projeto que você salvou no exercício anterior. Em seguida, execute as seguintes etapas:
1. Modifique o código da classe Rectangle como mostrado abaixo:
class Rectangle
{
public static string ShapeName
{
get { return “Rectangle”; }
}
public double Length { get; set; }
public double Width { get; set; }
public double GetArea()
{
return this.Length * this.Width;
}
}
44 | lição 2

2. Modifique o código da classe Program para:


class Program
{
static void Main(string[] args)
{
Rectangle rect = new Rectangle
{ Length = 10.0, Width = 20.0 };
Console.WriteLine(“Nome da forma: {0}, Area: {1}”,
Rectangle.ShapeName,
rect.GetArea());
}
}
3. Selecione Depurar > Iniciar sem Depuração. Uma janela de console será exibida
mostrando o nome e a área da forma.
4. SALVE seu projeto.
PAUSE. Deixe o projeto aberto para ser usado no próximo exercício.
Quando uma instância de uma classe é criada, uma cópia separada é criada para cada
campo de instância, mas apenas uma cópia de um campo estático é compartilhada por
PRONTO PARA
todas as instâncias.
CERTIFICAÇÃO Um membro estático não pode ser referenciado por meio de um objeto de instância.
Você compreende os Em vez disso, um membro estático é referenciado através do nome de classe (como
conceitos básicos das Rectangle.ShapeName no exercício acima). Observe que não é possível usar a referência
classes? de palavra-chave this com uma propriedade ou um método estático, pois a palavra-chave
2,1 this só pode ser usada para acessar objetos de instância.

■ Noções básicas sobre valores e referências


Um tipo de valor armazena diretamente um valor, ao passo que um tipo de referência
O RESULTADO armazena apenas uma referência a um valor real.

Um tipo de valor armazena dados diretamente na própria memória. Por outro lado,
os tipos de referência armazenam apenas uma referência a um local de memória;
aqui, os dados reais são armazenados no local de memória que está sendo referenciado.
A ­maioria dos tipos de dados elementares internos (como bool, int, char, double etc.)
são tipos de valor. Os tipos de dados definidos pelo usuário criados com a palavra-chave
struct também são tipos de valor. Os tipos de referência incluem os tipos criados com
as ­palavras-chave object, string, interface, delegate e class.
Noções básicas sobre structs

A palavra-chave struct é usada para criar tipos definidos pelo usuário que consistem
em pequenos grupos de campos relacionados. Os structs são tipos de valor — ao
contrário das classes, que são tipos de referência.

Os structs são definidos usando a palavra-chave struct, como mostrado abaixo:


public struct Point
{
public double X, Y;
}
Os structs podem conter a maioria dos elementos contidos pelas classes, como construtores,
métodos, propriedades etc. No entanto, como você aprenderá na próxima seção, os structs
Introdução à programação orientada a objeto | 45

são tipos de valor, ao passo que as classes são tipos de referência. Ao contrário de uma
TOME NOTA
* classe, o struct não pode ser herdado de outra classe ou struct.
Os structs são
principalmente usados Noções básicas sobre alocação de memória
para criar tipos simples.
Se você estiver criando
Após inserir um valor ou um texto em uma célula, você poderá modificá-lo de várias
um struct muito
maneiras. Em particular, você pode remover o conteúdo completamente, inserir um
complexo, considere
valor diferente para substituir o conteúdo anterior ou alterar o que digitou.
o uso de uma classe.
Uma boa maneira de compreender como os tipos de valor diferem dos tipos de referência
é visualizar como cada um deles é representado na memória. A figura 2-1 mostra como
os tipos de valor são criados na memória. Quando você cria uma variável do tipo int, por
exemplo, um local de memória nomeado é criado e você pode usá-lo para armazenar um
valor do tipo int. Inicialmente, quando você não atribui um valor explicitamente, o valor
padrão do tipo de dados (para int, o valor padrão é 0) é armazenado no local de memória.
Em seguida, quando uma atribuição for feita, o endereço de memória identificado pelo nome
da variável será atualizado com o novo valor (10 no caso da atribuição da figura 2-1).

Figura 2-1
Exibição do código Exibição da memória
Visualizando um tipo de
valor na memória number

int number; 0

number

number = 10; 10

Agora, examine a figura 2-2, que mostra um tipo de referência — especificamente, o tipo
de dados string. Quando você cria uma variável do tipo string, um local de memória é
criado e será identificado por esse nome. No entanto, esse local de memória não conterá
o conteúdo da cadeia de caracteres. Nesse caso, essa variável armazenará o endereço
de memória (uma referência) do local em que a cadeia de caracteres está realmente
armazenada.
Figura 2-2
Exibição do código Memory view
Visualizando um tipo de
referência na memória name

string name; null address data

name

name = "Northwind"; m100 m100 "Northwind"

Inicialmente, quando nenhum valor é atribuído, a variável tem o valor null (uma r­ eferência
nula; em outras palavras, essa variável não faz referência a um endereço de memória válido).
Em seguida, na próxima instrução, quando você diz:
name = “Northwind”;
A cadeia de caracteres “Northwind” é criada em um local de memória específico (para
simplificar, suponha que o endereço de memória seja m100), e esse endereço de memória
é armazenado no nome de variável. Posteriormente, no momento de recuperar o valor do
46 | lição 2

nome da variável, o tempo de execução saberá que seu conteúdo não está armazenado na
variável, mas no local de memória apontado pela variável.

COPIAR VALOR E TIPOS DE REFERÊNCIA

USE o projeto que você salvou no exercício anterior para executar as etapas a seguir:
1. Adicione o código a seguir após a definição da classe Rectangle para criar um struct
Point:
struct Point
{
TOME NOTA
* public double X, Y;
É possível criar um }
struct sem usar o
operador new. Você 2. Modifique o código do método Main como mostrado abaixo:
pode simplesmente static void Main(string[] args)
dizer Point p1; para
criar uma variável do {
tipo struct. Point p1 = new Point();
p1.X = 10;
p1.Y = 20;
Point p2 = p1;
p2.X = 100;
Console.WriteLine(“p1.X = {0}”, p1.X);
Rectangle rect1 = new Rectangle
{ Length = 10.0, Width = 20.0 };
Rectangle rect2 = rect1;
TOME NOTA
* rect2.Length = 100.0;
Quando você copia
Console.WriteLine(“rect1.Length = {0}”,
uma variável de tipo
de referência para rect1.Length);
outra variável do }
mesmo tipo, apenas
as referências são 3. Selecione Depurar > Iniciar sem Depuração. Uma janela de console será exibida
copiadas. Como mostrando os valores de p1.X e rect1.Length.
resultado, após 4. SALVE seu projeto.
a cópia, as duas PAUSE. Deixe o projeto aberto para ser usado no próximo exercício.
variáveis apontarão
para o mesmo objeto. Aqui, a primeira parte do programa cria uma cópia do tipo de valor Point, e a segunda
metade cria uma cópia do tipo de referência Rectangle.
Vamos começar analisando como a cópia de um tipo de valor é feita. Para começar,
quando a instrução a seguir for executada, uma nova variável p2 será criada na memória,
e seu conteúdo será copiado a partir da variável p1:
Point p2 = p1;
Após a execução dessa instrução, a variável p2 será criada, e o conteúdo da variável p1
será copiado para a variável p2. Tanto p1 quanto p2 têm seu próprio conjunto de valores
disponíveis em seus respectivos locais de memória. Portanto, quando a instrução a seguir
for executada:
p2.X = 100;
Ela só afetará o valor de X correspondente ao local de memória da variável p2. O valor de
X para a variável p1 permanece inalterado.
Introdução à programação orientada a objeto | 47

Agora, vamos analisar como a cópia funciona entre os tipos de referência. Nesse caso,
quando a instrução a seguir for executada, uma nova variável rect2 será criada e, assim
como antes, o conteúdo de rect1 será copiado para o local de memória de rect2:
Rectangle rect2 = rect1;
Entretanto, como a classe Rectangle é um tipo de referência, o conteúdo da variável rect1
é, na verdade, uma referência a um local de memória que contém um objeto Rectangle.
Portanto, após a inicialização acima, tanto rect1 quanto rect2 apontarão para o mesmo
local de memória e, por sua vez, para o mesmo objeto Rectangle. Em outras palavras,
há apenas um objeto rectangle na memória, e tanto rect1 quanto rect2 estão se referindo
a ele. A próxima instrução modifica o comprimento do objeto rectangle:
rect2.Length = 100.0;
PRONTO PARA Essa instrução faz referência ao local de memória apontado por rect2 (que passa a ser o
CERTIFICAÇÃO
mesmo local de memória apontado por rect1) e modifica o comprimento do objeto Rectangle.
Você compreende
Agora, se tentar fazer referência ao mesmo local de memória através do objeto rect1, você
o que são tipos de
obterá o objeto modificado e o código a seguir exibirá o valor “rect1.Length = 100”:
dados e alocação de
memória? Console.WriteLine(“rect1.Length = {0}”,
1,1 rect1.Length);

✚ MAIS INFORMAÇÕES
A memória aloca ocorre sempre nos objetos no heap. O heap é a memória disponível para um
programa em tempo de execução para alocação de memória dinâmica. Por outro lado, alguns itens
de dados podem ser criados na pilha de execução ou na pilha de chamadas. Os itens criados na pilha
são os parâmetros de método e as variáveis locais declaradas dentro de um método. A memória
da pilha é recuperada quando a pilha é esvaziada (quando um método retorna, por exemplo).
A memória alocada no heap é automaticamente recuperada pelo coletor de lixo quando os objetos
não estão mais em uso (ou seja, nenhum outro objeto está armazenando uma referência a ele).

■ Noções básicas sobre encapsulamento

O encapsulamento é um mecanismo para ocultar informações que facilita


O RESULTADO a manutenção e a compreensão do código.

O encapsulamento é um mecanismo que restringe o acesso a uma classe ou aos membros


de classe para ocultar as decisões de design que provavelmente serão alteradas. Ele permite
que os designers de classe tenham flexibilidade para modificar uma seção de código, quando
necessário, sem alterar todo o outro código que usa esse código. Além disso, ao ocultar
informações, você oculta a complexidade associada a elas. Como resultado, com a ajuda do
encapsulamento, você poderá escrever um código de mais fácil compreensão e manutenção.
Nos exercícios anteriores, você viu o encapsulamento em operação ao declarar os
membros de dados como private e impor a inicialização do campo de dados através
de um construtor. Como os membros de dados estão ocultos aos usuários da classe,
o desenvolvedor da classe Rectangle pode alterar os nomes dos campos de dados sem
exigir nenhuma alteração no código de chamada.
As propriedades oferecem uma ótima maneira de encapsular campos de dados, junto
com qualquer lógica de acompanhamento. Além disso, os modificadores de acesso, como
private e public, permitem que você controle o nível de acesso de um membro de classe
ou da própria classe.
Nesta seção, você aprenderá mais sobre modificadores de acesso e como eles funcionam.
48 | lição 2

Noções básicas sobre modificadores de acesso

TOME NOTA
* Os modificadores de acesso controlam onde um tipo ou um membro de tipo pode ser usado.
Você deve usar o nível
de acesso mais restritivo Todos os tipos e os membros de tipo têm um nível de acesso que especifica onde essa
que faça sentido para classe ou seus membros podem ser usados no seu código. O nível de acesso pode ser
um membro de tipo. definido usando um dos modificadores de acesso especificados na tabela 2-1.

Tabela 2-1
Modificadores de acesso

Modificador de acesso Descrição


public O acesso não é restrito.
private O acesso é restrito à classe contentora.
protected O acesso é restrito à classe contentora e a qualquer classe derivada direta ou indiretamente
da classe contentora. (Você aprenderá mais sobre classes derivadas posteriormente, no final
desta lição, na seção intitulada “Noções básicas sobre herança”.)
internal O acesso é restrito ao código no mesmo assembly.
protected internal  ma combinação de protected e internal, ou seja, o acesso é restrito a qualquer código no
U
mesmo assembly e apenas às classes derivadas em outro assembly.

Quando o código C# é compilado, o código de saída executável contido em um arquivo


TOME NOTA
* .dll ou .exe também é chamado de assembly. Um assembly é uma unidade de código
executável que pode ser instalada e ter versão independente.

Os modificadores de acesso não são permitidos em declarações de namespace; o acesso


PRONTO PARA público é implícito para namespaces. As classes de nível superior (declaradas diretamente
CERTIFICAÇÃO sob um namespace) podem ser apenas public ou internal. O modificador de acesso
Você compreende internal será o padrão de uma classe se nenhum modificador de acesso for especificado.
o que significa (Por exemplo, a classe Rectangle definida no exercício anterior tem, como padrão, um
encapsulamento? acesso interno.) A acessibilidade de uma classe aninhada não pode ser menos restritiva
2,4 do que a acessibilidade da classe contentora.

■ Noções básicas sobre herança

A herança é um recurso da programação orientada a objeto que permite que


você desenvolva uma classe uma única vez e, depois disso, reutilize esse código
repetidamente como a base de novas classes. A herança permite que você crie novas
O RESULTADO
classes que reutilizam, estendem e modificam a funcionalidade definida nas classes
existentes. A classe que herda a funcionalidade é denominada classe derivada,
e a classe cuja funcionalidade é herdada é denominada classe base. Uma classe
derivada herda toda a funcionalidade da classe base e também pode definir os recursos
adicionais que a tornam diferente da classe base.
Introdução à programação orientada a objeto | 49

Suponha que queremos criar um conjunto de classes que descreva polígonos, como
TOME NOTA
* retângulos ou triângulos. Essas classes terão algumas propriedades comuns, como
Diferentemente das largura e comprimento. Para esse caso, você pode criar uma classe base Polygon com as
classes, os structs propriedades Width e Length, e as classes derivadas Rectangle e Triangle herdarão essas
não oferecem suporte propriedades ao fornecerem sua própria funcionalidade. O exercício a seguir explica esse
à herança. conceito em mais detalhes.

CRIAR CLASSES DERIVADAS

USE o projeto que você salvou no exercício anterior para executar as ações a seguir:
1. Adicione uma nova classe denominada Polygon como mostrado abaixo:
class Polygon
{
public double Length { get; protected set; }
public double Width { get; protected set; }
}

2. Modifique a classe Rectangle como mostrado abaixo:


class Rectangle: Polygon
{
public Rectangle(double length, double width)
{
Length = length;
Width = width;
}
public double GetArea()
{
return Width * Length;
}
}

3. Agora, modifique o código do método Main como mostrado abaixo:


static void Main(string[] args)
{
Rectangle rect = new Rectangle(10, 20);
Console.WriteLine(
“Width={0}, Length={1}, Area = {2}”,
rect.Width, rect.Length, rect.GetArea());
}

4. Selecione Depurar > Iniciar sem Depuração. Uma janela de console será exibida
mostrando a largura, o comprimento e a área do retângulo.
5. SALVE seu projeto.
PAUSE. Deixe o projeto aberto para ser usado no próximo exercício.
Para definir uma classe derivada, você pode colocar dois-pontos após o nome da classe
derivada, seguido do nome da classe base. Aqui, a classe Polygon é a classe base da classe
Rectangle.
50 | lição 2

As propriedades Length e Width na classe Polygon são declaradas com um modificador


de acesso protegido para o acessador set. Isso significa que o acesso ao acessador set está
disponível somente dentro da classe Polygon e suas classes derivadas. Você ainda poderá
obter o valor das propriedades Length e Width no método Main, mas receberá um erro se
tentar atribuir um valor a essas propriedades.
A classe Rectangle herda todos os dados não privados e o comportamento da classe
Polygon. Além disso, a classe Rectangle define uma funcionalidade adicional (método
GetArea) que não está disponível na classe base.

Noções básicas sobre classes abstratas e seladas

As classes abstratas fornecem uma definição comum de uma classe base que pode
ser compartilhada por várias classes derivadas. Por outro lado, as classes seladas
fornecem funcionalidade completa, mas não podem ser usadas como classes base.

No exercício anterior, você definiu um método GetArea na classe Rectangle. Suponha que
você queira criar outra classe, Triangle, que seja do tipo Polygon. Aqui, você precisará de
um método GetArea na classe Triangle que calculará a área de um triângulo.
Muitas vezes, as classes base funcionam como repositório da funcionalidade comum.
No caso de Polygon, o polígono não saberá como calcular a área sem o conhecimento
do tipo de forma. Mas, em geral, espera-se que todas as classes do tipo Polygon sejam
capazes de calcular sua área. Essas expectativas podem ser passadas para a classe base
com a ajuda de uma palavra-chave abstract.
CRIAR CLASSES ABSTRATAS
USE o projeto que você salvou no exercício anterior e execute as etapas a seguir.
1. Modifique a classe Polygon como mostrado abaixo:
abstract class Polygon
{
public double Length { get; protected set; }
public double Width { get; protected set; }
abstract public double GetArea();
}
2. Modifique a classe Rectangle como mostrado abaixo:
class Rectangle: Polygon
{
public Rectangle(double length, double width)
{
Length = length;
Width = width;
}
public override double GetArea()
{
return Width * Length;
}
}
3. Observe que nenhuma modificação no método Main é necessária.
4. Selecione Depurar > Iniciar sem Depuração. Uma janela de console será exibida
mostrando a largura, o comprimento e a área do retângulo.
5. SALVE seu projeto.
PAUSE. Deixe o projeto aberto para ser usado no próximo exercício.
Introdução à programação orientada a objeto | 51

Essa versão da classe Polygon define um método denominado GetArea. O principal


­motivo para a inclusão desse método na classe base é que, agora, a classe base pode
fornecer um modelo comum de funcionalidade para as classes derivadas. Mas, como já
discutimos, a classe base Polygon não tem informações suficientes para calcular a área da
TOME NOTA
* forma. Essa situação pode ser resolvida, marcando o método como abstract. Um método
Você não pode criar abstrato fornece uma definição, mas não oferece qualquer implementação (o corpo do
instâncias de uma método). Se qualquer um dos membros de uma classe for abstrato, a classe precisará ser
classe abstrata. marcada como abstrata. Uma classe abstrata não pode ser instanciada.
As classes derivadas podem fornecer uma implementação de uma classe abstrata para
criar uma classe concreta (uma classe não abstrata). As classes derivadas podem oferecer
uma implementação de um método abstrato, substituindo-o em uma classe derivada.
Por exemplo, a classe Rectangle substitui o método abstrato GetArea da classe base e
fornece uma implementação completa. Como resultado, a classe Rectangle não é mais
uma classe abstrata e pode ser instanciada diretamente.
As classes seladas, por outro lado, são definidas quando sua implementação está completa
e você não quer que uma classe seja herdada. Uma classe selada pode ser criada usando
a palavra-chave sealed, como neste exemplo:
sealed class Rectangle: Polygon
{
// membros de classe entram aqui
}
Como Rectangle é uma classe selada, ela não pode ser usada como uma classe base.
Também é possível marcar os membros de classe selecionados como sealed para evitar
TOME NOTA
* que sejam substituídos em uma classe derivada. Por exemplo, você poderia dizer:
C# não oferece suporte sealed public override double GetArea()
à herança de mais de {
uma classe base, muitas
vezes chamada de return Width * Length;
herança múltipla. }
Essa declaração garante que o método GetArea não possa ser substituído em uma classe
derivada.

Herdando da classe Object

A classe Object é a classe base final de todas as classes no .NET Framework.

Todas as classes no .NET Framework são herdadas direta ou indiretamente da classe


Object. Por exemplo, quando você declarou a classe a seguir no início desta lição:
class Polygon
{
public double Length { get; protected set; }
public double Width { get; protected set; }
}
Era funcionalmente equivalente à seguinte declaração:
class Polygon: Object
{
public double Length { get; protected set; }
public double Width { get; protected set; }
}
52 | lição 2

No entanto, você não precisa declarar a classe Polygon na última maneira, pois a herança
da classe Object é assumida implicitamente. Como parte dessa herança, uma classe
derivada pode substituir os métodos da classe Object. Dois dos métodos mais comuns
para isso são:
• Equals: oferece suporte à comparação entre dois objetos e retornará true se os dois
objetos tiverem o mesmo valor.
• ToString: retorna uma representação de cadeia de caracteres da classe. Por padrão,
ele retorna o nome completo da classe. Muitas vezes, é útil substituir esse método
para que ele retorne uma representação de cadeia de caracteres do estado atual do
objeto.
O exemplo a seguir mostra como você pode substituir o método ToString na classe
Rectangle:
class Rectangle: Polygon
{
public Rectangle(double length, double width)
{
Length = length;
Width = width;
}
public override double GetArea()
{
return Width * Length;
}
public override string ToString()
{
return String.Format(
“Width = {0}, Length = {1}”,
Width, Length);
}
}

Conversão entre tipos


Em C#, o tempo de execução permite que você converta um objeto em qualquer um
de seus tipos base.

As classes derivadas têm uma relação “é um” com sua classe base. Por exemplo,
podemos dizer que Rectangle é um Polygon. Assim, um objeto da classe Rectangle tem
efetivamente dois tipos de dados neste caso: o objeto é um Rectangle, e o objeto também
é um Polygon.
Em C#, o tempo de execução permite que você converta um objeto em sua classe ou
em qualquer uma de suas classes base. Por exemplo, você pode dizer:
Polygon p = new Rectangle(10, 20);
Aqui, um novo objeto Rectangle é criado e é convertido em seu tipo base Polygon.
C# não exige qualquer sintaxe especial para isso, pois a conversão em um tipo base
é considerada uma conversão segura.
Introdução à programação orientada a objeto | 53

A conversão também é possível do modo contrário. Por exemplo, você pode dizer:
Object o = new Rectangle(10, 20);

Rectangle r = (Rectangle) o;
Aqui, um objeto Rectangle é atribuído primeiro a um Object (a classe base definitiva)
e, em seguida, o objeto resultante é convertido de volta como um Rectangle. Quando
a ­última atribuição acontece, uma conversão explícita é necessária, pois você está
­convertendo um objeto mais geral em um objeto menos geral. O tempo de execução
verifica se o valor da variável o é compatível com a classe Rectangle. Se, no tempo de
execução o valor de o não for compatível com a classe Rectangle, o tempo de execução
gerará System.InvalidCastException.

USANDO O OPERADOR IS
Para evitar erros de tempo de execução, como InvalidCastException, o operador is
pode ser usado para verificar se a conversão é permitida antes de realmente executar
a ­conversão, como neste exemplo:
if (o is Rectangle)
{
Rectangle r = (Rectangle) o;
}
TOME NOTA
* Aqui, o tempo de execução verifica o valor do objeto o. Em seguida, a instrução de
Se estiver usando
­conversão somente será executada se o contiver um objeto Rectangle.
o operador as para
converter um tipo, você
USANDO O OPERADOR AS
não precisará verificar o
operador is. Você poderá Outro operador de conversão útil é as. O operador as é semelhante à operação de
simplesmente verificar ­conversão, mas, no caso de as, se a conversão de tipo não for possível, null será retornado,
o valor de retorno em em vez de gerar uma exceção. Por exemplo, considere o código a seguir:
relação a nulo. Rectangle r = o as Rectangle;
if (r != null)
{
PRONTO PARA // fazer alguma coisa
CERTIFICAÇÃO
}
Você compreende o
significado de herança? Se, no tempo de execução, não for possível converter o valor da variável o em um
2,2 ­retângulo, um valor null será atribuído à variável r. Nenhuma exceção será gerada.

■ Noções básicas sobre polimorfismo

Polimorfismo é a capacidade de as classes derivadas compartilharem uma


O RESULTADO funcionalidade comum com as classes base, mas, ainda assim, definir seu próprio
comportamento exclusivo.

Você está desenvolvendo um aplicativo que permite que os usuários trabalhem com
­diferentes tipos de polígonos. Você tem uma coleção que contém vários tipos de
polígonos, como um retângulo, um triângulo e um quadrado. Cada polígono fornece sua
própria implementação do método Draw. Ao trabalhar com essa coleção, você não sabe
54 | lição 2

exatamente com qual forma está trabalhando, mas deseja que o método Draw correto seja
sempre invocado. O polimorfismo permite que você faça exatamente isso.
Ele permite que os objetos de uma classe derivada sejam tratados em tempo de execução
como objetos da classe base. Quando um método é invocado em tempo de execução,
o seu tipo exato é identificado, e o método apropriado é invocado da classe derivada.

USAR O POLIMORFISMO

USE o projeto que você salvou no exercício anterior para executar as etapas a seguir:
1. Modifique a classe Polygon como mostrado abaixo:
class Polygon
{
public virtual void Draw()
{
Console.WriteLine(“Drawing: Polygon”);
}
}

2. Modifique a classe Rectangle como mostrado abaixo:


class Rectangle: Polygon
{
public override void Draw()
{
Console.WriteLine(“Drawing: Rectangle”);
}
}
3. Adicione uma nova classe denominada Triangle, conforme mostrado abaixo:
class Triangle: Polygon
{
public override void Draw()
{
Console.WriteLine(“Drawing: Triangle”);
}
}

4. Modifique o método Main da seguinte forma:


static void Main(string[] args)
{
List<Polygon> polygons = new List<Polygon>();
polygons.Add(new Polygon());
polygons.Add(new Rectangle());
polygons.Add(new Triangle());
Introdução à programação orientada a objeto | 55

foreach (Polygon p in polygons)


{
p.Draw();
}
}
5. Selecione Depurar > Iniciar sem Depuração. Uma janela de console será exibida
mostrando a mensagem de desenho para cada polígono.
6. SALVE seu projeto.
PAUSE. Deixe o projeto aberto para ser usado no próximo exercício.
Neste exercício, as definições das classes Polygon e Rectangle são simplificadas para
enfatizar o conceito de polimorfismo. A classe base fornece um único método Draw.
Um item importante a ser observado aqui é a palavra-chave virtual. Essa palavra-chave
­permite que as classes derivadas substituam o método.
As classes Rectangle e Triangle substituem o método Draw da classe base pela sua própria
definição, usando a palavra-chave override. Quando executado, o método Main gera
esta saída:
Drawing: Polygon
Drawing: Rectangle
Drawing: Triangle
O tipo de dados List<Polygon> é capaz de armazenar uma coleção de objetos que são
do tipo Polygon ou dos tipos derivados de Polygon. O loop foreach está iterando uma
coleção de objetos de Polygon. O tipo subjacente do primeiro objeto é Polygon, mas
o segundo e terceiros objetos da coleção são, na verdade, Rectangle e Triangle, que
também estão definidos como Polygon. O tempo de execução examinará o tipo subjacente
real e invocará o método substituído da classe derivada. É por isso que a versão de classe
derivada do método Draw é chamada para os objetos Rectangle e Triangle.

Noções básicas sobre as palavras-chave Override e New


A palavra-chave override substitui um membro de classe base em uma classe
derivada. A palavra-chave new cria um novo membro de mesmo nome na classe
derivada e oculta a implementação da classe base.

Quando uma classe base define um membro virtual, a classe derivada pode lidar com isso
de duas maneiras: especificamente, a classe derivada pode usar a palavra-chave ­override
ou new. A palavra-chave override tem prioridade sobre a definição de classe base do
membro. Aqui, o objeto de classe derivada chamará o membro substituído em vez do
membro de classe base.
Em comparação, se a palavra-chave new for usada, uma nova definição do membro
será criada e o membro de classe base será oculto. No entanto, se a classe derivada for
­convertida em uma instância da classe base, os membros ocultos da classe ainda poderão
ser chamados.
56 | lição 2

Para compreender melhor esses conceitos, modifique o método Triangle do exercício


TOME NOTA
* ­anterior para o seguinte:
Se o método na classe
derivada não for class Triangle: Polygon
precedido pela palavra- {
chave new ou override, public new void Draw()
o compilador emitirá
um aviso e o método {
se comportará como se Console.WriteLine(“Drawing: Triangle”);
a palavra-chave new }
estivesse presente. }
Em seguida, modifique o código na classe Main para o seguinte:
Triangle t = new Triangle();
t.Draw();
Polygon p = t;
p.Draw();
O programa produzirá a seguinte saída:
Drawing: Triangle
Drawing: Polygon
PRONTO PARA
CERTIFICAÇÃO Aqui, quando o método Draw é invocado diretamente no objeto de classe derivada, a
Você compreende o nova versão do método é usada. No entanto, se o método for executado quando a classe
que é polimorfismo? derivada for convertida como uma classe base, a versão de classe base oculta do método
2,3 Draw será executada.

A classe System.Object fornece um método ToString. Por convenção, você deve usar
esse método para retornar a representação compreendida pelo usuário para uma classe.
TOME NOTA
* Ao criar seus tipos, é recomendável que você substitua esse método para retornar
informações legíveis sobre os objetos.

■ Noções básicas sobre interfaces

As interfaces são usadas para estabelecer contratos através dos quais os objetos podem
O RESULTADO interagir entre si sem conhecer os detalhes da implementação.

As interfaces são definidas usando a palavra-chave interface. Uma definição de interface


TOME NOTA
* consiste em um conjunto de assinaturas para métodos, propriedades, delegados, eventos
Por convenção, todas
ou indexadores. Uma definição de interface não pode consistir em campos de dados ou
as interfaces definidas
detalhes de implementação, como corpos de método.
no .NET Framework
começam com I Uma interface comum definida no namespace System é o namespace IComparable.
maiúsculo. Embora Esta é uma interface simples, definida conforme a seguir:
você possa nomear suas
interface IComparable
interfaces livremente
como desejar, convém {
seguir a convenção do int CompareTo(object obj);
Framework. }
Introdução à programação orientada a objeto | 57

A interface IComparable tem um único método (CompareTo) que aceita um objeto


e retorna um int. O valor de retorno desse método indica o resultado da comparação
do parâmetro específico com o objeto atual. De acordo com a documentação do método
CompareTo:
• Se a instância for igual ao parâmetro, CompareTo retornará 0.
• Se o valor do parâmetro for menor do que a instância ou se o parâmetro for null,
um valor positivo será retornado.
• Se o valor do parâmetro for maior do que a instância, um valor negativo será
retornado.
• Se o parâmetro não for do tipo compatível, um ArgumentException será gerado.

Como IComparable decide como comparar dois objetos Rectangle ou dois objetos
Employee? Ele não decide. As classes interessadas nessas comparações devem
implementar a interface IComparable, fornecendo um corpo de método para o método
CompareTo. Cada classe que implementa IComparable é livre para fornecer sua própria
lógica de comparação personalizada dentro do método CompareTo.

USAR A INTERFACE ICOMPARABLE

USE o projeto que você salvou no exercício anterior para executar as etapas a seguir:
1. Modifique a classe Rectangle como mostrado abaixo:
class Rectangle: Polygon, IComparable
{
public double Length { get; set; }
public double Width { get; set; }
public override void Draw()
{
Console.WriteLine(“Drawing: Rectangle”);
}
public double GetArea()
{
return Length * Width;
}
public int CompareTo(object obj)
{
if (obj == null)
return 1;
if (!(obj is Rectangle))
throw new ArgumentException();
Rectangle target = (Rectangle)obj;
double diff = this.GetArea() - target.GetArea();
58 | lição 2

if (diff == 0)
return 0;
else if (diff > 0)
return 1;
else return -1;
}
}
3. Em seguida, modifique o método Main, conforme mostrado abaixo:
static void Main(string[] args)
{
Rectangle rect1 = new Rectangle
{ Length = 10, Width = 20 };
Rectangle rect2 = new Rectangle
{ Length = 100, Width = 200 };
Console.WriteLine(rect1.CompareTo(rect2));
}
4. Selecione Depurar > Iniciar sem Depuração. Uma janela de console será exibida
mostrando o valor – 1, pois a área de rect1 é menor do que a área de rect2.
5. SALVE seu projeto.
Aqui, a classe Rectangle deriva da classe Polygon e implementa a interface IComparable.
Uma classe que implementa uma interface deve implementar todos os métodos declarados
nessa interface.
Uma interface é semelhante a uma classe abstrata, mas existem algumas diferenças
­perceptíveis. Por um lado, uma classe abstrata fornece implementação incompleta, ao
passo que uma interface não fornece nenhuma implementação. Uma classe também pode
implementar várias interfaces, mas está limitada a herdar de apenas uma única classe base.
Então, como decidir se você deve usar uma interface ou uma classe abstrata? Uma
PRONTO PARA maneira é verificar se existe uma relação “é um” entre os dois conceitos. Por exemplo,
­C ERTIFICAÇÃO se existir uma relação de herança entre um SalariedEmployee e um Employee, você
Você compreende poderá usar uma classe abstrata para padronizar a funcionalidade comum entre as
o que significa classes derivadas. Por outro lado, não há nenhuma relação “é um” entre um Employee
encapsulamento? e o IComparable. Portanto, a melhor forma de implementar a funcionalidade de
2,4
comparação é como uma interface.

RESUMO DE HABILIDADES

Nesta lição, você aprendeu que:


• A programação orientada a objeto é uma técnica de programação que utiliza objetos.
Os objetos são estruturas de dados autocontidas que consistem em propriedades,
métodos e eventos. As propriedades especificam os dados representados por um
objeto, os métodos especificam o comportamento de um objeto e os eventos
estabelecem comunicação entre os objetos.
• Uma classe é o modelo do qual são criados os objetos individuais.
• Os construtores são usados para inicializar os membros de dados de um objeto.
Introdução à programação orientada a objeto | 59

• A palavra-chave this pode ser usada para acessar os membros a partir de


construtores, métodos de instância e acessadores de propriedades de instância.
• Os delegados são tipos especiais usados para encapsular um método com uma
assinatura específica.
• Os eventos são uma maneira de uma classe notificar outras classes ou objetos
quando algo de interesse ocorre. A classe que envia uma notificação é chamada
de editor do evento, e a classe que recebe a notificação é chamada de assinante
do evento.
• Os namespaces permitem que você organize o código e crie nomes de classe exclusivos.
• A palavra-chave static é usada para declarar os membros que não pertencem
a objetos individuais, mas a uma classe.
• Um tipo de valor armazena diretamente um valor, ao passo que um tipo de referência
armazena apenas uma referência a um valor real.
• A palavra-chave struct é usada para criar tipos definidos pelo usuário que consistem
em pequenos grupos de campos relacionados. Os structs são tipos de valor, ao passo
que as classes são tipos de referência.
• O encapsulamento é um mecanismo que restringe o acesso a uma classe ou aos
membros de classe para ocultar as decisões de design que provavelmente serão
alteradas. Ele permite que os designers de classe tenham flexibilidade para modificar
uma seção de código, conforme necessário, sem alterar todo o outro código que usa
esse código.
• Um modificador de acesso especifica qual região do código terá acesso a um
campo. Por exemplo, um modificador de acesso public não limita o acesso, mas um
modificador de acesso private limita o acesso dentro da classe em que o campo está
definido.
• A herança permite que você crie novas classes que reutilizam, estendem e modificam
a funcionalidade definida nas classes existentes. A classe que herda a funcionalidade
é denominada classe derivada, e a classe cuja funcionalidade é herdada
é denominada classe base.
• Polimorfismo é a capacidade de as classes derivadas compartilharem uma
funcionalidade comum com as classes base, mas, ainda assim, definir seu próprio
comportamento exclusivo.
• A palavra-chave override substitui um membro de classe base em uma classe
derivada. A palavra-chave new cria um novo membro do mesmo nome na classe
derivada e oculta a implementação da classe base.

■ Avaliação de conhecimento
Preencha as lacunas
Complete as sentenças a seguir com a(s) palavra(s) correta(s) nas lacunas fornecidas.
1. Um(a) __________ é um plano gráfico de um objeto.
2. Uma classe que não fornece uma implementação completa deve ser declarada com
a palavra-chave __________.
3. As classes que desejam dar suporte à comparação devem implementar a interface
IComparable e fornecer um corpo para o método __________.
4. Você pode usar o operador __________ para verificar se ele é válido para converter
um tipo em outro.
60 | Lição 2

5. Três principais características de uma linguagem de programação orientada a objeto


são _________, __________ e _ _________.
6. Você pode usar __________ para agrupar classes relacionadas e reduzir as colisões
de nomes.
7. A palavra-chave __________ refere-se à instância atual de uma classe.
8. Um(a) __________ é um tipo que referencia um método.
9. Um(a) __________ é um tipo de valor, ao passo que um(a) __________ é um tipo de
referência.
10. Você pode usar a palavra-chave __________ para declarar um membro pertencente
à classe, em vez de um objeto específico.
Múltipla escolha
Assinale a letra que corresponde à melhor resposta.
1. Você deseja restringir o acesso de um método à classe contentora ou a uma classe
derivada dessa classe. Qual modificador de acesso você deve usar para esse método?
a. public
b. private
c. protected
d. internal
2. Em uma classe, você definiu um método denominado Render. Esse método fornece
a funcionalidade de renderização de arquivos de bitmap na tela. Você quer que as classes
derivadas substituam essa funcionalidade para dar suporte à renderização de formatos
de imagem adicionais. Você também quer que o método Render das classes derivadas
seja executado mesmo que uma classe derivada seja convertida como a classe base.
Qual palavra-chave você deve usar com a definição do método Render na classe base?
a. abstract
b. virtual
c. new
d. overrides
3. Você definiu uma classe AdvMath que determina a funcionalidade de matemática
avançada. Você não quer que a funcionalidade dessa classe seja herdada para as
classes derivadas. Qual palavra-chave você deve usar para definir a classe AdvMath?
a. sealed
b. abstract
c. private
d. internal
4. Você precisa fornecer a funcionalidade de consulta a várias de suas classes. O
algoritmo para a consulta de cada classe provavelmente será diferente. Além disso,
nem todas as classes têm uma relação “é um” entre si. Como você deve dar suporte
a essa funcionalidade?
a. Adicionar a funcionalidade de consulta a uma classe base com o modificador
de acesso public
b. Fazer com que todas as classes sejam herdadas de uma classe base abstrata
e substituir o método da classe base para fornecer sua própria funcionalidade
de consulta
c. Fazer com que todas as classes sejam herdadas de uma classe base que fornece
a funcionalidade de consulta
d. Criar uma interface comum que seja implementada por todas as classes
Introdução à programação orientada a objeto | 61

5. Qual dos seguintes elementos de classe a seguir você deve usar para definir
o comportamento de uma classe?
a. Método
b. Propriedade
c. Evento
d. Delegado
6. Você está escrevendo um código para uma classe denominada Product. Você
precisa ter certeza de que os membros de dados da classe serão inicializados para
seus valores corretos assim que criar um objeto da classe Product. O código de
inicialização deve ser sempre executado. O que você deve fazer?
a. Criar um método estático na classe Product para inicializar os membros de dados
b. Criar um construtor na classe Product para inicializar os membros de dados
c. Criar uma propriedade estática na classe Product para inicializar os membros de dados
d. Criar um evento na classe Product para inicializar os membros de dados
7. Você está criando uma nova classe denominada Square que é derivada da classe
Polygon. A classe Polygon tem o seguinte código:
class Polygon
{
public virtual void Draw()
{
// código adicional. . .
}
}
O método Draw na classe Square deve fornecer nova funcionalidade, mas também
ocultar a implementação da classe Polygon do método Draw. Qual segmento de
código você deve usar para realizar essa tarefa?
a. class Square: Polygon
{
public override void Draw()
{
// código adicional. . .
}
}
b. class Square: Polygon
{
public new void Draw()
{
// código adicional. . .
}
}
c. class Square: Polygon
{
public virtual void Draw()
{
// código adicional. . .
}
}
62 | Lição 2

d. class Square: Polygon


{
public static void Draw()
{
// código adicional. . .
}
}
8. Você está criando uma nova classe denominada Rectangle. Você escreve o seguinte código:
class Rectangle: IComparable
{
public double Length { get; set; }
public double Width { get; set; }
public double GetArea()
{
return Length * Width;
}
public int CompareTo(object obj)
{
// to be completed
}
}
Você precisa concluir a definição do método CompareTo para permitir a comparação
dos objetos Rectangle. Qual dos códigos a seguir você deve escrever?
a. public int CompareTo(object obj)
{
Rectangle target = (Rectangle)obj;
double diff = this.GetArea() − target.GetArea();
if (diff == 0)
return 0;
else if (diff > 0)
return 1;
else return −1;
}
b. public int CompareTo(object obj)
{
Rectangle target = (Rectangle)obj;
double diff = this.GetArea() − target.GetArea();
if (diff == 0)
return 1;
else if (diff > 0)
return −1;
else return 0;
}
Introdução à programação orientada a objeto | 63

c. public int CompareTo(object obj)


{
Rectangle target = (Rectangle)obj;
if (this == target)
return 0;
else if (this > target)
return 1;
else return −1;
}
d. public int CompareTo(object obj)
{
Rectangle target = (Rectangle)obj;
if (this == target)
return 1;
else if (this > target)
return −1;
else return 0;
}
9. Você está escrevendo um código para um novo método denominado Process:
void Process(object o)
{
}
O código recebe um parâmetro do tipo Object. Você precisa converter esse objeto
em um tipo Rectangle. Às vezes, o valor “o” que é passado para o método pode não
ser um valor Rectangle válido. Você precisa ter certeza de que o código não gera
erros System.InvalidCastException ao fazer as conversões. Qual das linhas de código
a seguir você deve usar dentro do método Process para atingir essa meta?
a. Rectangle r = (Rectangle) o;
b. Rectangle r = o as Rectangle;
c. Rectangle r = o is Rectangle;
d. Rectangle r = (o != null) ? o as rectangle: (Rectangle) o;
10. Você está escrevendo um código para manipular os eventos em seu programa.
Você define um delegado denominado RectangleHandler como este:
public delegate void RectangleHandler(Rectangle rect);
Você também cria uma variável do tipo RectangleHandler desta forma:
RectangleHandler handler;
Posteriormente no programa, você precisará adicionar um método denominado
DisplayArea à lista de invocação de método da variável handler. A assinatura do
método DisplayArea corresponde à assinatura do método RectangleHandler.
Qualquer código escrito não deve afetar nenhum código de manipulação de eventos
existente. Com base nessa restrição, qual dos códigos a seguir você deve escrever?
a. handler = new RectangleHandler(DisplayArea);
b. handler = DisplayArea;
c. handler += DisplayArea;
d. handler −= DisplayArea;
64 | lição 2

■ Avaliação da competência
Cenário 2-1: criando propriedades
Você precisa criar uma classe denominada Product que representa um produto. A classe tem
uma única propriedade denominada Name. Os usuários da classe Product devem ser capazes
de obter e também definir o valor da propriedade Name. No entanto, qualquer tentativa de
definir o valor de Name para uma cadeia de caracteres vazia ou um valor nulo deve gerar
uma exceção. Além disso, os usuários da classe Product não devem ser capazes de acessar
nenhum outro membro de dados da classe Product. Como você criará essa classe?

Cenário 2-2: criando um struct


Você está desenvolvendo um jogo que precisa representar o local de um destino no
espaço tridimensional. O local é identificado pelos três valores inteiros denotados por x,
y e z. Você criará milhares dessas estruturas de dados em seu programa e precisa de uma
maneira leve e eficiente de armazenar esses dados na memória. Além disso, é improvável
que você precise herdar qualquer outro tipo desse tipo de local. Como você deve
representar o local em seu programa?

■ Avaliação de proficiência
Cenário 2-1: substituindo o método ToString
Suponha que você esteja escrevendo um código para uma classe Product. A classe Product
contém o nome e o preço de um produto. Você precisa substituir o método ToString
da classe base (System.Object) para fornecer informações sobre os objetos da classe
de produto para o código de chamada. Qual código você precisa escrever para a classe
Product a fim de atender a esse requisito?

Cenário 2-2: criando e manipulando eventos


Imagine que você esteja escrevendo um código para criar e tratar eventos no seu programa.
A classe SampleClass precisa implementar a seguinte interface:
public delegate void SampleDelegate();
public interface ISampleEvents
{
event SampleDelegate SampleEvent;
void Invoke();
}
Você precisa escrever o código para SampleClass e para um método de teste que cria uma
instância de SampleClass e invoca o evento. Qual código você deve escrever?
Noções básicas sobre LIÇÃO 3
o desenvolvimento
de software em geral
M AT R I Z D E H A B I L I D A D E S D A L I Ç Ã O

Habilidades/Conceitos Objetivo do exame MTA Número do objetivo do


exame MTA
Noções básicas sobre Compreender o gerenciamento 3,1
gerenciamento do ciclo de vida do ciclo de vida do aplicativo.
do aplicativo
Noções básicas sobre testes Compreender o gerenciamento 3,1
do ciclo de vida do aplicativo.
Noções básicas sobre as Compreender algoritmos 3,3
estruturas de dados e estruturas de dados.
Noções básicas sobre algoritmos Compreender algoritmos 3,3
de classificação e estruturas de dados.

PRINCIPAIS TERMOS
teste de aceitação teste de integração teste de software
ALM (gerenciamento do ciclo de lista vinculada algoritmos de classificação
vida do aplicativo) QuickSort pilha
matrizes fila teste de sistema
teste caixa preta teste de regressão teste de unidade
Bubblesort gerenciamento de lançamento teste caixa branca
estruturas de dados análise de requisitos
processo de design desenvolvimento de software

Você é um desenvolvedor de software da Northwind Corporation. Você trabalha como


parte de uma equipe para desenvolver programas de computador que solucionam
problemas empresariais complexos. Como desenvolvedor, você precisa estar ciente
das diferentes fases do ciclo de vida do aplicativo por desempenhar um papel
importante em várias partes desse ciclo. Por exemplo, você não só participa das
partes de design e desenvolvimento do ciclo, mas, muitas vezes, precisa interagir com
a equipe de teste de software durante a parte de teste do ciclo. Às vezes, você até
mesmo participa do teste, portanto, precisa ter uma compreensão geral desse processo.

65
66 | lição 3

Ao desenvolver um software, você usa vários tipos de algoritmos e estruturas


de dados. Portanto, você precisa saber quais estruturas de dados usar para a tarefa
disponível e quais são as implicações de desempenho da sua escolha. Você também
deve ter uma compreensão geral dos vários métodos de classificação.

■ Noções básicas sobre gerenciamento do ciclo de vida do aplicativo

O ALM (gerenciamento do ciclo de vida do aplicativo) é o conjunto de atividades


O RESULTADO que giram em torno de um novo produto de software, desde o seu início até o seu
amadurecimento e, talvez, sua desativação.

O desenvolvimento de um aplicativo de software envolve mais do que apenas a escrita


do código. Várias outras atividades também precisam ser executadas na ordem certa para
desenvolver um aplicativo com êxito. Coletivamente, essas atividades são conhecidas
como ALM (gerenciamento do ciclo de vida do aplicativo). Algumas das atividades que
fazem parte do processo ALM são mostradas na figura 3-1, incluindo requisitos, design,
desenvolvimento, teste, entrega e gerenciamento de lançamento.
Figura 3-1
Gerenciamento do ciclo
de vida do aplicativo Requisitos

Manutenção Design

Testes Desenvolvimento

Nesta seção, você aprenderá sobre as diferentes atividades e funções envolvidas em cada
estágio do processo ALM.
O ciclo de vida do aplicativo inicia quando é identificada a necessidade de um novo
aplicativo de software. Em geral, um gerente comercial é o patrocinador do projeto.
Ele ou ela analisa a necessidade, verifica como o projeto se encaixa na estratégia geral
do negócio, organiza o financiamento e inicia o processo de recrutamento para o projeto.
Um gerente de projeto provavelmente é a primeira pessoa contratada pelo gerente
comercial. O gerente de projeto é responsável pela execução geral do projeto. Suas
principais responsabilidades são garantir que o projeto permaneça dentro do orçamento
e seja concluído dentro do prazo. O gerente de projeto também é responsável pela
contratação de membros da equipe e por facilitar a cooperação dentro da equipe.

Noções básicas sobre análise de requisitos


A análise de requisitos é o processo que consiste em determinar os requisitos
comerciais detalhados para um novo sistema de software.
Noções básicas sobre o desenvolvimento de software em geral | 67

A análise de requisitos é uma das etapas mais importantes do ciclo de vida do aplicativo.
Requisitos precisos, completos e bem-documentados são essenciais para o sucesso do
projeto. Esses requisitos podem ser funcionais ou não funcionais. Os requisitos funcionais
especificam exatamente o que o sistema está projetado para realizar. Por outro lado,
os requisitos não funcionais são requisitos de qualidade, como escalabilidade, segurança,
confiabilidade etc.
Um analista de negócios é responsável por analisar as necessidades comerciais e convertê-
las em requisitos que possam ser executados pela equipe de desenvolvimento.

Noções básicas sobre o processo de design


O processo de design é usado para criar planos, modelos e arquitetura para o modo
como o software será implementado.

O processo de design gera especificações técnicas detalhadas que serão usadas para
desenvolver o sistema. A saída do processo de design é um conjunto de modelos técnicos
e especificações que fornecem orientação para os desenvolvedores e outros membros da
equipe durante a atividade de desenvolvimento do software. A saída do processo de design
é mais abstrata do que concreta. Neste momento, não há nenhum sistema real com o qual
você possa interagir.
Alguns dos participantes mais importantes neste estágio do processo ALM incluem um
arquiteto e um designer de experiência do usuário:
• Arquiteto: um arquiteto projeta o plano gráfico técnico do sistema. Isso inclui
a identificação de componentes e serviços, seu comportamento e como eles
interagem entre si e com o mundo externo.
• Designer de experiência do usuário: um designer de experiência do usuário cria a
experiência do usuário do sistema. Isso inclui o projeto dos elementos de IU (interface
do usuário), o projeto da navegação entre vários formulários, telas ou páginas etc.

Noções básicas sobre desenvolvimento de software


A atividade de desenvolvimento de software envolve a implementação do design através
da criação de código de software, bancos de dados e outro conteúdo relacionado.

O desenvolvimento de software é a parte do processo ALM em que os requisitos


comerciais são implementados no código de trabalho com base no projeto criado na
atividade anterior. No final dessa atividade, você terá uma saída concreta na forma de
um sistema de software com o qual os usuários poderão interagir.
Participantes fundamentais no desenvolvimento de software:
• Desenvolvedores: os desenvolvedores escrevem código com base nos requisitos
reunidos pela analista de negócios, na arquitetura definida pelo arquiteto e na
experiência do usuário desenvolvida pelo designer de experiência do usuário.
• DBAs (administradores de banco de dados): os DBAs são responsáveis pela
implementação e pela manutenção dos bancos de dados do software. Os DBAs
também planejam a integridade, a segurança e a velocidade dos dados.
• Escritores técnicos: os escritores técnicos desenvolvem manuais e arquivos de ajuda
do sistema que serão entregues junto com o aplicativo.
• Desenvolvedores de conteúdo: os desenvolvedores de conteúdo são especialistas
no assunto que desenvolvem o conteúdo do sistema. Por exemplo, se o aplicativo for
um site de crítica de filmes, não basta você implantar o site; você também deve ter
certeza de que o site contém conteúdo suficiente para atrair o interesse do usuário.
68 | lição 3

Noções básicas sobre teste de software


O teste de software verifica se a implementação corresponde aos requisitos do sistema.

O teste de software é usado para assegurar a qualidade do produto final. O teste pode
identificar possíveis lacunas entre as expectativas em relação ao sistema descritas no
documento de requisitos e o comportamento real do sistema.
Entre os participantes mais críticos na atividade de teste de software estão os testadores
que verificam o aplicativo em execução para se certificar de que ele atende aos requisitos
identificados. Quando esses testadores identificam qualquer falha no aplicativo, eles
atribuem cada falha a uma pessoa apropriada que possa consertá-la. Por exemplo, uma
falha de código seria atribuída de volta a um desenvolvedor para que ele (ou ela) possa
remediar o erro.

Noções básicas sobre gerenciamento de lançamento


A atividade de gerenciamento de lançamento é usada para gerenciar a implantação,
a entrega e o suporte das versões de software.

O gerenciamento de lançamento inclui atividades, como empacotamento e implantação


do software, gerenciamento de defeitos do software e gerenciamento das solicitações de
alteração do software.
Os principais players da atividade de gerenciamento de lançamento incluem estes
indivíduos:
• Gerente de lançamento: o gerente de lançamento coordena várias equipes e unidades
de negócios para garantir o lançamento em tempo hábil de um produto de software.
• Equipe de operação: os membros da equipe de operação garantem que o sistema
seja entregue conforme prometido. Isso pode envolver a gravação de DVDs
PRONTO PARA
e sua remessa à medida que os pedidos forem sendo recebidos ou pode implicar
CERTIFICAÇÃO a manutenção de um sistema SaaS (software como serviço) de forma contínua.
Você compreende A equipe de operação também é responsável por liberar qualquer atualização de
o que significa sistema (por exemplo, correções de bugs ou novos recursos).
gerenciamento do ciclo • Equipe de suporte técnico: esses funcionários interagem com os clientes e ajudam
de vida do aplicativo a solucionar seus problemas com o sistema. O suporte técnico pode gerar métricas
e suas atividades?
valiosas sobre quais áreas do sistema apresentam mais dificuldade para os usuários
3,1
e possivelmente precisarão ser atualizadas na próxima versão do aplicativo.

■ Noções básicas sobre testes

O teste de software é o processo de verificação do software com base em seus


O RESULTADO requisitos. O teste ocorre depois que a maior parte do trabalho de desenvolvimento
é concluída.

Conforme mencionado anteriormente, o teste de software é o processo que verifica se um


software funciona conforme esperado e atende a todos os requisitos comerciais e técnicos.
Quando há uma diferença entre o comportamento esperado e o comportamento real do
sistema, uma falha de software (ou um “bug”) é registrada e finalmente passada para um
indivíduo responsável por consertá-la.
O teste de software pode envolver testes funcionais e não funcionais. O teste funcional
está relacionado aos requisitos funcionais do sistema e testa os recursos que constituem
Noções básicas sobre o desenvolvimento de software em geral | 69

a funcionalidade essencial do sistema. Por exemplo, testar se os usuários podem adicionar


itens a um carrinho de compras é uma parte importante do teste funcional de um site
de comércio eletrônico. Em comparação, os testes não funcionais envolvem testes dos
atributos de software que não fazem parte da funcionalidade essencial, mas fazem parte
de  requisitos não funcionais do software, como escalabilidade, usabilidade, segurança.

É importante observar que o processo de teste de software somente pode ajudar a


encontrar falhas, ele não pode garantir a ausência de falhas. Um software complexo tem
*
TOME NOTA um número imenso de caminhos de execução possíveis e vários parâmetros que podem
afetar seu comportamento. Não é viável e muitas vezes não é possível testar todas as
situações diferentes que esse software encontrará em um ambiente de produção.

Noções básicas sobre métodos de teste

Os métodos de teste de software são geralmente divididos em duas categorias: teste


caixa branca e teste caixa preta.

Tradicionalmente, há duas abordagens amplas para os testes de software:


• Teste caixa preta
• Teste caixa branca
O teste caixa preta trata o software como uma caixa preta, concentrando-se exclusivamente
em entradas e saídas. Com essa abordagem, qualquer conhecimento do funcionamento
interno do sistema não é utilizado durante o teste. Por outro lado, com o teste caixa branca,
os testadores usam seu conhecimento da estrutura interna do sistema ao testarem o sistema.
Por exemplo, no teste caixa branca, os testadores têm acesso ao código-fonte.
Essas duas técnicas de teste se complementam. Na maioria das vezes, o teste caixa preta
é usado para garantir que um software atenda a todos os seus requisitos, ao passo que
o teste caixa branca é usado para garantir que cada método ou função tenha casos de teste
adequados disponíveis.

Noções básicas sobre os níveis de teste

O teste é executado em várias fases do ciclo de vida de desenvolvimento do


aplicativo. Diferentes níveis de teste especificam em que parte no ciclo de vida um
teste específico ocorre, bem como que tipo de teste está sendo executado.

Os níveis de teste são definidos pela parte em que os testes ocorrem no ciclo de vida
de desenvolvimento do software. Há cinco níveis distintos de teste:
• Teste de unidade: o teste de unidade verifica a funcionalidade de uma unidade de
código. Por exemplo, uma unidade de teste pode avaliar se um método retorna o valor
correto. O teste de unidade é um teste caixa branca e é realizado com frequência pelo
desenvolvedor que está escrevendo o código. O teste de unidade muitas vezes usa
uma ferramenta automatizada que pode simplificar o desenvolvimento dos casos e
também acompanhar se uma modificação do código causa a falha de qualquer um
dos testes de unidade existentes. O Visual Studio tem suporte interno para o teste de
unidade. Você também pode usar ferramentas de software livre, como o NUnit, para
automatizar os testes de unidade para o código do .NET Framework.
• Teste de integração: o teste de integração avalia a interface entre os componentes
de software. O teste de integração pode ser executado de forma incremental enquanto
70 | lição 3

os componentes estiverem sendo desenvolvidos ou pode ser realizado de uma única


vez quando todos os componentes estiverem prontos para trabalhar em conjunto.
A primeira abordagem é preferível à última, pois reduz o risco e aumenta a confiança
dos participantes à medida que o sistema está sendo desenvolvido. O teste de
integração também pode envolver o teste da interação do componente com um
sistema externo. Por exemplo, se um componente se basear nos dados de um serviço
Web externo, o teste de integração garantirá que o componente esteja funcionando
bem com o aplicativo externo.
• Teste de sistema: o teste de sistema é o teste geral do sistema de software. Neste
ponto, todos os componentes do sistema são desenvolvidos e estão trabalhando
juntos e com qualquer sistema externo.
• Teste de aceitação: esse nível de teste é realizado com frequência pelos próprios
TOME NOTA
* clientes. Geralmente, há dois níveis de teste de aceitação antes do lançamento geral
A economia será muito de um produto: o teste alfa e o teste beta. O teste alfa é realizado por um grupo
maior se os defeitos limitado de usuários e é uma oportunidade de fornecer uma visão antecipada do
forem detectados com produto aos clientes mais importantes e coletar feedback. Os lançamentos alfa podem
antecedência (e não não ter alguns recursos e geralmente não apresentam vários atributos não funcionais,
posteriormente) no ciclo como desempenho. No próximo nível de teste, o teste beta, você lançará o produto
de desenvolvimento do para um público-alvo de clientes mais amplo e solicitará seus comentários. Em
produto. termos de funcionalidade, a versão beta do software é muito semelhante à versão
final. No entanto, as equipes de desenvolvimento ainda poderão trabalhar para
a melhoria do desempenho e a correção das falhas conhecidas.
PRONTO PARA • Teste de regressão: à medida que as falhas em um software vão sendo informadas
CERTIFICAÇÃO e consertadas, é importante que você se certifique de que cada nova correção
Você compreende os
não interrompa algo que estava funcionamento anteriormente. É nesse momento
vários métodos de teste
que o teste de regressão é útil. A cada nova correção, os testadores de software
de software?
3,1 geralmente executam uma bateria de testes de regressão para garantir que cada
funcionalidade que antes funcionava corretamente ainda esteja em operação.

■ Noções básicas sobre as estruturas de dados

As estruturas de dados são técnicas de organização e armazenamento de dados na


memória do computador. O modo como os dados são armazenados afeta como os dados
O RESULTADO são recuperados e manipulados. A compreensão de uma estrutura de dados envolve não
só compreender o padrão de armazenamento, mas também saber quais métodos são
usados para criar, acessar e manipular a estrutura de dados.

As estruturas de dados são os blocos de construção da maioria dos programas de


computador e permitem que os desenvolvedores implementem funcionalidades complexas.
A maioria das estruturas de programação fornecem suporte interno para uma variedade
de estruturas de dados e métodos associados ao manipular essas estruturas de dados.
Nesta seção, você aprenderá sobre vários tipos distintos de estruturas de dados para se
familiarizar com as técnicas gerais de manipulação dessas estruturas.

Noções básicas sobre matrizes


Uma matriz é uma coleção de itens armazenados em um local de memória contígua
e endereçado usando um ou mais índices.
Noções básicas sobre o desenvolvimento de software em geral | 71

Uma matriz é uma estrutura de dados comum que representa uma coleção de itens de um
tipo semelhante. Os itens de uma matriz são armazenados em locais de memória contígua.
Uma matriz é uma estrutura de dados homogênea, pois todos os itens de uma matriz são
do mesmo tipo de dados. Qualquer item de matriz pode ser diretamente acessado usando
um índice. No .NET Framework, os índices de matriz são de base zero.

REPRESENTAÇÃO INTERNA
No código a seguir, a primeira instrução cria uma variável de matriz, e a segunda
instrução inicializa a variável com uma matriz de quatro números inteiros:
int[] numbers;
numbers = new int[4];
No início, os números variáveis são definidos como null, pois a matriz ainda não foi
inicializada. No entanto, a segunda instrução inicializa a matriz, alocando um espaço
contíguo de memória grande o suficiente para armazenar quatro números inteiros no
heap de memória. O endereço inicial na alocação de memória é armazenado na variável
de matriz numbers, conforme mostra a figura 3-2. Todos os elementos da matriz são
inicializados nesse caso com o valor 0, pois 0 é o valor padrão de um número inteiro.

Figura 3-2
Pilha Heap
Representação interna de
uma estrutura de dados de
int [] numbers; null
matriz

numbers = new int [4]; addr 0 0 0 0

A variável numbers, então, age como uma referência ao local de memória atribuído
à matriz. O nome de matriz pode ser usado para acessar diretamente cada um dos itens
de matriz. No .NET Framework, todas as matrizes são de base zero, ou seja, o primeiro
item da matriz é acessado usando um índice numbers[0], o segundo item é acessado por
numbers[1] e assim por diante.
Também é possível ter matrizes multidimensionais. Uma matriz bidimensional pode
ser comparada a uma tabela na qual cada célula é um elemento de matriz e pode ser
endereçada usando os números de linha e coluna à qual pertence. Tanto o número de linha
quanto o número de coluna são indexados por zero. Por exemplo, a expressão table[2, 3]
se refere a um item na terceira linha e na quarta coluna de uma matriz pelo nome table.

OPERAÇÕES COMUNS
As matrizes dão suporte às seguintes operações:
• Alocação
• Acesso
Para trabalhar com uma matriz, você primeiro deve alocar a memória, criando e
inicializando a matriz, conforme mostrado anteriormente. Após a alocação da matriz,
você poderá acessar qualquer elemento da matriz em qualquer ordem desejada, referindo-
se diretamente ao seu índice. Por exemplo, o código a seguir atribui o valor 10 ao quarto
item da matriz, e o dobro desse valor é atribuído à variável calc:
number[3] = 10;
int calc = number[3] * 2;
72 | lição 3

DESEMPENHO E USO
O conteúdo de uma matriz é disposto como um bloco contíguo de memória e pode ser
acessado diretamente, usando o índice de matriz. Assim, a leitura de uma matriz ou
a gravação nela são procedimentos extremamente rápidos. No entanto, as matrizes são
­limitados pelos requisitos de homogeneidade e de tamanho fixo. Embora o tamanho da
matriz possa ser aumentado, isso requer a realocação de todos os elementos da matriz
e é uma operação demorada.
As matrizes funcionam melhor quando o número de itens na coleção é predeterminado
e um acesso rápido e direto a cada item é necessário.
No .NET Framework, você pode usar a classe ArrayList para contornar os requisitos
de homogeneidade e tamanho fixo de uma matriz. Um ArrayList é um tipo de coleção
que pode armazenar itens de qualquer tipo de dados e expandir dinamicamente quando
necessário. No entanto, um ArrayList não é tão rápido quanto uma matriz.

Noções básicas sobre filas


Uma fila é uma coleção de itens em que o primeiro item adicionado à coleção
é o primeiro a ser removido.

A estrutura de dados da fila imita uma fila da vida real. Em uma fila, os itens são
processados na ordem de sua adição à fila. Em particular, os itens são sempre
adicionados ao final da fila e removidos do início da fila. Isso também é conhecido
como processamento FIFO (primeiro a entrar, primeiro a sair). A capacidade de uma
fila é o número de itens que a fila pode conter. Entretanto, à medida que forem sendo
adicionados elementos à fila, a capacidade aumentará automaticamente. Uma fila
também é uma estrutura de dados heterogêneos, o que significa que os itens de uma fila
podem ser de diferentes tipos de dados.

REPRESENTAÇÃO INTERNA
Para evitar a realocação excessiva do espaço de memória e permitir um gerenciamento
fácil, uma fila muitas vezes é implementada internamente como uma matriz circular de
objetos, conforme mostra a figura 3-3.

Figura 3-3 8 1
Representação interna Head
null null
de uma estrutura de
dados de fila 7 2
null Item 1

Item 5 Item 2
6 3
Item 4 Item 3

Tail
5 4

Dentro de uma fila, o índice de cabeça aponta para o primeiro item, e o índice de cauda
aponta para o último item. Na figura 3-3, por exemplo, o índice de cabeça aponta para
o local 2 na fila. Como a fila é circular, se você conseguir acompanhar os ponteiros de
cabeça e cauda, o início da fila não importará. Quando um item é removido, a cabeça
Noções básicas sobre o desenvolvimento de software em geral | 73

move-se para o próximo item na fila. Quando um novo item é adicionado, ele sempre
TOME NOTA
* aparece no final da fila, e a cauda começa a apontar para o item recém-adicionado.
Uma versão genérica Qualquer slot nulo em uma fila (incluindo o representado na figura 3-3) é o ponto vazio
da classe Queue está que pode ser preenchido antes que a fila necessite de uma realocação de memória.
disponível como parte
O .NET Framework fornece uma implementação da estrutura de dados da fila como parte
do namespace System.
da classe Queue no namespace System.Collections. Nas linguagens de programação que
Collections.Generic.
não fornecem uma implementação de uma fila, você pode escrever sua própria classe Queue
Essa versão genérica
usando uma estrutura de dados semelhante a uma matriz e simulando as operações de fila.
é usada para criar uma
fila de itens que são do
mesmo tipo de dados. OPERAÇÕES COMUNS
Uma fila oferece suporte a estas operações comuns:
• Enfileiramento: a operação de enfileiramento primeiro verifica se há capacidade
disponível suficiente na fila para adicionar mais um item. Se houver capacidade
disponível, o item será adicionado à parte final da fila. Se não houver espaço
disponível na fila, a matriz será realocada por um fator de crescimento
pré-especificado, e o novo item será adicionado à fila.
• Remoção da fila: a operação de remoção da fila remove o elemento atual na frente
da fila e define a cabeça para apontar para o próximo elemento.
• Espiada: a operação espiada permite que você veja o item atual na posição inicial
sem removê-lo realmente da fila.
• Contém: a operação contém permite que você determine se um item específico
existe na fila.

DESEMPENHO E USO
Uma fila é uma estrutura de dados de finalidade especial que é mais adequada a um
aplicativo em que é necessário processar os itens na ordem de seu recebimento. Alguns
exemplos podem incluir spoolers de impressão, sistemas de mensagens e agendadores
de trabalhos. Ao contrário de uma matriz, uma fila não pode ser usada para acessar os
elementos aleatoriamente. As operações, como enfileiramento e remoção da fila,
realmente adicionam e removem itens da fila.

Noções básicas sobre pilhas


Uma pilha é uma coleção de itens em que o último item adicionado à coleção
é o primeiro a ser removido.

Ao contrário de uma fila, uma pilha é uma estrutura de dados LIFO (último a entrar,
primeiro a sair). Pense em uma pilha como semelhante a uma pilha de pratos de jantar
em uma mesa de bufê; aqui, o último prato a ser adicionado é também o primeiro prato
a ser removido. A capacidade de uma pilha refere-se ao número de itens que ela pode
conter. No entanto, como os elementos são adicionados a uma pilha, a capacidade da
pilha aumenta automaticamente. Uma pilha é uma estrutura de dados heterogêneos,
o que significa que os itens dentro dela podem ser de diferentes tipos de dados.

REPRESENTAÇÃO INTERNA
Assim como uma fila, uma pilha geralmente é implementada como um buffer circular
para evitar realocação excessiva do espaço de memória e permitir um gerenciamento mais
fácil. Uma pilha pode ser visualizada exatamente como a fila mostrada na figura 3-3,
exceto pelo fato de a parte final agora ser chamada de topo da pilha e a parte inicial agora
ser chamada de fundo da pilha.
74 | lição 3

Novos itens são sempre adicionados sobre uma pilha e, quando isso acontece, a parte
TOME NOTA
* superior da pilha começa a apontar para o elemento que acabou de ser adicionado.
Uma versão genérica Os itens também são removidos de cima da pilha e, quando isso acontece, a parte
da classe Stack está superior da pilha é ajustada para apontar para o próximo item da pilha.
disponível como parte
do namespace System. O .NET Framework fornece uma implementação da estrutura de dados da pilha como
Collections.Generic. parte da classe Stack no namespace System.Collections. Nas linguagens de programação
Essa versão genérica que não fornecem uma implementação da pilha, você pode escrever sua própria
é usada para criar uma classe Stack usando uma estrutura de dados semelhante a uma matriz e simulando
pilha de itens que são as operações de pilha.
do mesmo tipo de
dados. OPERAÇÕES COMUNS
Uma pilha oferece suporte a estas operações comuns:
• Push: a operação de envio por push primeiro verifica se há capacidade disponível
suficiente na pilha para adicionar mais um item. Se houver capacidade disponível,
o item será adicionado ao topo da pilha. Se não houver espaço disponível na pilha,
a matriz será realocada por um fator de crescimento pré-especificado, e o novo item
será adicionado à pilha.
• Pop: a operação pop remove o elemento no topo da pilha e define o topo para
apontar para o próximo elemento na pilha.
• Espiada: a operação espiada permite que você veja o item atual na parte superior
da pilha sem removê-lo realmente da pilha.
• Contém: a operação contém permite que você determine se um item específico
existe na pilha.

DESEMPENHO E USO
Uma pilha é uma estrutura de dados de finalidade especial que é mais adequada para as
aplicações em que você precisa processar os itens na ordem último a entrar, primeiro
a sair. As pilhas são estruturas úteis por causa de suas aplicações de gerenciamento de
memória de tempo de execução, avaliação de expressão, acompanhamento de chamada
de método de rastreamento etc. Ao contrário de uma matriz, uma pilha não pode ser
usada para acessar elementos aleatoriamente. As operações, como push e pop, na verdade,
adicionam e removem itens da pilha.

Listas vinculadas
Uma lista vinculada é uma coleção de nós organizados de modo que cada um deles
contenha um link para o próximo nó da sequência.

Uma lista vinculada é uma coleção de nós em que cada nó contém uma referência (ou um
link) para o próximo nó da sequência. Ao contrário de uma matriz, os itens de uma lista
vinculada não precisam ser contíguos; portanto, uma lista vinculada não requer realocação
do espaço de memória para a lista inteira quando for necessário adicionar mais itens.

REPRESENTAÇÃO INTERNA
Na memória, uma lista vinculada pode ser visualizada como uma coleção de nós, como
mostra a figura 3-4.

Figura 3-4
A B C
Representação interna de
uma estrutura de dados de
lista vinculada única Head Null
Noções básicas sobre o desenvolvimento de software em geral | 75

Cada nó de uma lista vinculada contém dois tipos de informações: os dados


correspondentes ao nó e o link para o próximo nó. O primeiro nó da lista é chamado de nó
da cabeça. Ao usar o link no nó de cabeça, você consegue atingir o próximo nó e continuar
percorrendo os nós até que o link final seja um valor nulo. Muitas vezes, o termo cauda é
usado para se referir à lista apontada pelo nó de cabeça, ou seja, refere-se a tudo após o nó
de cabeça. Assim, na figura 3-4, a cauda é a lista vinculada a partir do nó B.
Várias outras implementações de listas vinculadas também podem ser utilizadas
dependendo dos requisitos. Por exemplo, em uma lista vinculada circular, o último nó da
lista aponta de volta para o primeiro nó para criar um círculo. Por outro lado, em uma lista
duplamente vinculada, cada nó contém dois links, como mostra a figura 3-5.

Figura 3-5 Null


Representação interna de
A B C
uma estrutura de dados de
lista duplamente vinculada

Head Null

Em cada nó de uma lista duplamente vinculada, um link é uma referência direta que
aponta para o próximo nó da sequência, e o outro link é uma referência regressiva que
aponta para o nó anterior na sequência. Como você pode imaginar, uma lista duplamente
vinculada é fácil de ser percorrida em qualquer direção.
O .NET Framework fornece uma classe LinkedList como parte do namespace System.
Collections.Generic. Essa classe implementa uma lista duplamente vinculada homogênea
do tipo de dados especificado. Você também pode escrever suas próprias classes para
implementar um tipo diferente de implementação de lista vinculada.

OPERAÇÕES COMUNS
Uma lista vinculada oferece suporte a estas operações comuns:
• Adicionar: a adição ou a inserção de um item em uma lista vinculada consiste em
alterar links, conforme mostra a figura 3-6. Suponha que você queira inserir um
novo nó (com valor Z) entre os nós com valores A e B. Primeiro, você precisa alocar

Figura 3-6
Z Novo nó
Adicionando um novo nó a
uma lista vinculada

A B C

Head Null

Z Novo nó

A B C

Head Null
76 | lição 3

memória para o novo nó e atribuir o valor Z à seção de dados do nó. Em seguida,


você deve copiar a seção de link do nó A para a seção de link do nó Z, para que
o nó Z esteja apontando para o nó B. Finalmente, você deve copiar o endereço do
nó Z recém-criado para a seção de link do nó A, para que o nó A comece a apontar
para o nó Z.
• Remover: semelhante à operação de adição, a operação de remoção ou exclusão
também consiste na alteração de links. Por exemplo, para excluir o terceiro nó na
figura 3-4, você alteraria o link do segundo nó para um valor nulo. O terceiro nó
agora será uma parte da memória sem referência e finalmente será retornado ao
pool de memória disponível.
• Localizar: a operação de localização encontra um nó com um determinado valor na
lista vinculada. Para localizar um valor, você geralmente começa a partir do nó da
cabeça e verifica se o valor corresponde. Se ele não corresponder, siga o link para
o próximo nó e continue a operação de localização até atingir o final da lista, o que
acontece quando você encontra um link nulo.

DESEMPENHO E USO
Uma lista vinculada não permite acesso aleatório aos seus itens. A única maneira de acessar
um item é começar do nó da cabeça e seguir os links a partir dele. Como resultado, as listas
vinculadas demoram a recuperar os dados. No entanto, para as operações de inserção e
exclusão, as listas vinculadas são extremamente rápidas, pois a inserção ou a exclusão de
um nó envolve simplesmente a alteração de um link. As listas vinculadas também não têm
capacidade máxima após a qual seu conteúdo precisará ser realocado.
PRONTO PARA
CERTIFICAÇÃO Na verdade, uma lista vinculada fornece uma maneira alternativa de implementar a fila
Você compreende as e as estruturas de dados de pilha. Se suas necessidades exigirem acesso frequente a dados,
estruturas de dados mas você raramente precisa inserir ou excluir dados, uma matriz será a implementação
comuns? preferida. Se, no entanto, suas necessidades exigirem operações frequentes de inserção
3,2 e exclusão, uma lista vinculada poderá ser uma melhor implementação.

■ Noções básicas sobre algoritmos de classificação

Os algoritmos de classificação, como BubbleSort e QuickSort, organizam os itens de


O RESULTADO uma lista em uma ordem específica. A compreensão dos algoritmos de classificação
pode ajudá-lo a entender, analisar e comparar diferentes métodos de solução de
problemas.

Os algoritmos de classificação organizam os itens em uma lista em uma ordem específica.


Por exemplo, você pode usar um algoritmo de classificação para classificar uma lista de
alunos em ordem crescente de seu sobrenome. Nos primeiros dias de processamento de dados,
a classificação foi um problema importante que atraiu muita pesquisa. Nesses dias, você
poderá encontrar recursos de classificação básicos já incorporados às bibliotecas e às estruturas
de dados mais populares. Por exemplo, no .NET Framework, você pode usar o método Array.
Sort para classificar uma matriz. No entanto, ainda é importante considerar a classificação
como uma maneira de compreender a solução de problemas e a análise de algoritmo.
Nesta seção, você examinará dois algoritmos de classificação comuns, BubbleSort
e QuickSort.

Noções básicas sobre o BubbleSort


O algoritmo BubbleSort usa uma série de operações de comparação e permuta para
organizar os elementos de uma lista na ordem correta.
Noções básicas sobre o desenvolvimento de software em geral | 77

O BubbleSort compara dois elementos para verificar se estão fora de ordem; se estiverem
ele os trocará. O algoritmo continuará fazendo isso até que toda a lista esteja na ordem
desejada. O BubbleSort recebe esse nome pelo modo que o algoritmo funciona: durante
a execução do algoritmo, os itens menores são “flutuados” para cima.
Vamos visualizar BubbleSort com a ajuda de um exemplo. Vamos supor que você queira
organizar todos os itens da lista a seguir em ordem crescente: (20, 30, 10, 40). Esses itens
devem ser organizados do menor para o maior. O algoritmo BubbleSort tenta solucionar
esse problema em um ou mais passos, com cada passo examinando completamente a lista
de itens. Se o algoritmo encontrar elementos fora de ordem, ele os trocará. O algoritmo
termina quando ele examina a lista inteira sem trocar qualquer elemento. Se não houvesse
nenhuma permuta, nenhum dos elementos estariam fora de ordem e a lista teria sido
completamente classificada.

Tabela 3-1
Primeira passagem de Etapa Antes Depois Comentários
BubbleSort
1 20, 30, 10, 40 20, 30, 10, 40 O algoritmo compara os dois primeiros
elementos (20 e 30); como eles estão
na ordem correta, nenhuma permuta
é necessária.
2 20, 30, 10, 40 20, 10, 30, 40 O algoritmo compara os dois
elementos seguintes (30 e 10);
como eles estão fora de ordem,
os elementos são trocados.
3 20, 10, 30, 40 20, 10, 30, 40 O algoritmo compara os dois
elementos seguintes (30 e 40); como
eles estão na ordem correta, nenhuma
permuta é necessária.

Conforme mostra a tabela 3-1, no final da primeira passagem, BubbleSort realizou uma
permuta, e é possível que os itens ainda não estejam totalmente classificados. Portanto,
BubbleSort dá uma outra passagem na lista, conforme ilustrado na tabela 3-2.

Tabela 3-2
Segunda passagem de Etapa Antes Depois Comentários
BubbleSort
1 20, 10, 30, 40 10, 20, 30, 40  algoritmo compara os dois primeiros
O
elementos (20 e 10); como eles estão
fora de ordem, os elementos são
trocados.
2 10, 20, 30, 40 10, 20, 30, 40  algoritmo compara os dois
O
elementos seguintes (20 e 30); como
eles estão na ordem correta, nenhuma
permuta é necessária.
3 10, 20, 30, 40 10, 20, 30, 40  algoritmo compara os dois
O
elementos seguintes (30 e 40); como
eles estão na ordem correta, nenhuma
permuta é necessária.
78 | lição 3

No final da segunda passagem, BubbleSort realizou mais uma permuta, portanto, ele ainda
não pode garantir que a lista esteja completamente classificada. Dessa forma, BubbleSort
realiza uma outra passagem na lista, conforme mostra a tabela 3-3.

Tabela 3-3
Terceira passagem de Etapa Antes Depois Comentários
BubbleSort
1 10, 20, 30, 40 10, 20, 30, 40  algoritmo compara os dois primeiros
O
elementos (10 e 20); como eles estão
TOME NOTA
* na ordem correta, nenhuma permuta é
Quando você usar necessária.
BubbleSort, uma 2 10, 20, 30, 40 10, 20, 30, 40  algoritmo compara os dois
O
matriz será certamente elementos seguintes (20 e 30); como
classificada em uma eles estão na ordem correta, nenhuma
passagem a menos do permuta é necessária.
que o número de itens.
Portanto, se houver 3 10, 20, 30, 40 10, 20, 30, 40  algoritmo compara os dois
O
quatro itens (como no elementos seguintes (30 e 40); como
cenário de exemplo), a eles estão na ordem correta, nenhuma
matriz será classificada permuta é necessária.
(independentemente da
sua ordem de início)
No final da terceira passagem, BubbleSort não realizou nenhuma permuta. Isso garante
em três passagens.
que a lista agora está na ordem de classificação e que o algoritmo pode terminar.
No C#, o algoritmo BubbleSort pode ser expresso pelo seguinte método:
static int[] BubbleSort(int[] numbers)
{
bool swapped;
do
{
swapped = false;
for (int i = 0; i < numbers.Length − 1; i++)
{
if (numbers[i] > numbers[i + 1])
{
//trocar
int temp = numbers[i + 1];
numbers[i + 1] = numbers[i];
numbers[i] = temp;
swapped = true;
}
}
} while (swapped == true);
return numbers;
}
Noções básicas sobre o desenvolvimento de software em geral | 79

Noções básicas sobre o QuickSort


O algoritmo QuickSort usa as operações de particionamento e comparação para
organizar os elementos de uma lista na ordem correta.

O algoritmo QuickSort usa a técnica dividir e conquistar para particionar uma lista
continuamente até que o tamanho do problema seja pequeno e raramente exija
classificação. As etapas a seguir explicam esse processo em mais detalhes:
• Uma lista de tamanho zero ou um sempre é classificada por si só.
• Para obter uma lista maior, escolha qualquer elemento da lista como um elemento
pivô. Em seguida, particione a lista de modo que todos os elementos menores que
ou iguais ao elemento pivô sejam inseridos na lista esquerda e todos os elementos
maiores do que o elemento pivô sejam inseridos na lista direita. Agora, a combinação
da lista esquerda, do elemento pivô e da lista direita estará sempre em ordem
classificada se as listas esquerda e direita estiverem em ordem classificada.
• O problema agora é particionado em duas listas menores, a lista esquerda e a lista
direita.
• Ambas são solucionadas usando a técnica descrita nos marcadores acima.
• Finalmente, todas as pequenas listas classificadas são mescladas para criar a lista
classificada completa final.
A tabela a seguir explica o algoritmo QuickSort com um breve exemplo.

Tabela 3-4
Visualizando o QuickSort Etapa Dados a serem classificados Comentários
1 50, 10, 30, 20, 40 Comece com uma lista não classificada
e escolha um elemento pivô — neste
caso, 30.
2 20, 10 30 50, 40 Particione a lista, inserindo os itens
menores do que o pivô na lista
esquerda e os itens maiores do que o
pivô na lista direita. Em seguida, para
classificar a lista esquerda, escolha um
pivô (neste caso, 10). Da mesma forma,
para classificar a lista direita, escolha
um pivô (neste caso, 40) para essa lista.
3 - 10 20 30 - 40 50  a lista esquerda, 20 é maior do que
N
10 e, na lista direita, 50 é maior do que
40; portanto, tanto 20 quanto 50 serão
inseridos na lista direita. Isso resulta
em listas de apenas um número, que
são todas classificadas por definição.
4 10, 20, 30, 40, 50 Todas as pequenas listas classificadas
são mescladas para criar a lista
classificada final completa.

Até agora, a principal deficiência do algoritmo QuickSort parece ser a memória adicional
necessária à criação de listas menores separadas. No entanto, a criação de listas separadas
não é necessária. Usando uma técnica ligeiramente modificada, a matriz pode ser
particionada no local, como mostra a listagem de código a seguir:
static int Partition (int[] numbers, int left,
int right, int pivotIndex)
80 | lição 3

{
int pivotValue = numbers[pivotIndex];
// mover elemento pivô para o final
int temp = numbers[right];
numbers[right] = numbers[pivotIndex];
numbers[pivotIndex] = temp;
// newPivot armazena o índice do primeiro
// número maior do que o pivô
int newPivot = left;
for (int i = left; i < right; i++)
{
if (numbers[i] <= pivotValue)
{
temp = numbers[newPivot];
numbers[newPivot] = numbers[i];
numbers[i] = temp;
newPivot++;
}
}
//mover o elemento pivô para sua posição classificada
temp = numbers[right];
numbers[right] = numbers[newPivot];
numbers[newPivot] = temp;
return newPivot;
}
Com essa técnica, primeiro o elemento pivô é movido para o final da matriz. Em seguida,
todos os elementos menores que ou iguais ao elemento pivô são movidos para a frente
da matriz. Finalmente, o elemento pivô é colocado antes do elemento maior do que ele
próprio, particionando efetivamente a matriz.
Esse algoritmo de particionamento pode ser usado por QuickSort para particionar a lista,
reduzir o problema em problemas menores e solucioná-lo recursivamente:
static int[] QuickSort(int[] numbers,
int left, int right)
{
if (right > left)
{
int pivotIndex = left + (right − left) / 2;
//partição da matriz
pivotIndex = Partition(
numbers, left, right, pivotIndex);
//classificar a partição esquerda
QuickSort(
numbers, left, pivotIndex − 1);
// classificar a partição direita
QuickSort(
Noções básicas sobre o desenvolvimento de software em geral | 81

numbers, pivotIndex + 1, right);


PRONTO PARA
}
CERTIFICAÇÃO return numbers;
Você compreende o }
que são algoritmos de
classificação comuns? Devido à sua abordagem de particionamento, o algoritmo QuickSort é muito mais rápido
3,3 do que o algoritmo BubbleSort.

RESUMO DE HABILIDADES

Nesta lição, você aprendeu que:


• O ALM (gerenciamento do ciclo de vida do aplicativo) refere-se a várias atividades
que giram em torno de um novo produto de software, desde o seu início até o seu
amadurecimento e, talvez, sua desativação.
• O teste de software é o processo de verificação do software com base em seus requisitos.
O teste ocorre depois que a maior parte do trabalho de desenvolvimento é concluída.
• As estruturas de dados são técnicas de organização e armazenamento de dados na
memória do computador. O modo como os dados são armazenados afeta como os
dados são recuperados e manipulados. A compreensão de uma estrutura de dados
envolve não só compreender o padrão de armazenamento, mas também entender
os métodos usados para criar, acessar e manipular a estrutura de dados.
• Uma matriz é uma coleção de itens do mesmo tipo de dados que são armazenados
em um local de memória contígua e endereçados usando um ou mais índices.
• Uma fila é uma coleção de itens em que o primeiro item adicionado à coleção
é o primeiro a ser removido.
• Uma pilha é uma coleção de itens em que o último item adicionado à coleção
é o primeiro a ser removido.
• Uma lista vinculada é uma coleção de nós organizados de modo que cada um deles
contenha um link para o próximo nó da sequência.
• O algoritmo BubbleSort usa uma série de operações de comparação e permuta para
organizar os elementos de uma lista na ordem correta.
• O algoritmo QuickSort usa operações de particionamento e comparação para
organizar os elementos de uma lista na ordem correta.

■ Avaliação de conhecimento
Preencha as lacunas
Complete as sentenças a seguir com a(s) palavra(s) correta(s) nas lacunas fornecidas.
1. No teste ______, os testadores usam seu conhecimento da estrutura interna do
sistema para avaliar o sistema.
2. Em geral, a cada nova correção, os testadores de software executam uma bateria de
______ para garantir que toda a funcionalidade que antes estava funcionando ainda
esteja em operação.
3. O algoritmo BubbleSort usa uma série de operações de ______ e ______ para
organizar os elementos de uma lista na ordem correta.
82 | lição 3

4. Um(a) ______ é uma coleção de itens em que o último item adicionado à coleção
é o primeiro a ser removido.
5. ______ é o processo que consiste em determinar os requisitos comerciais detalhado
para um novo sistema de software.
6. Uma lista vinculada é uma coleção de nós organizados de modo que cada nó
contenha um(a) ______ para o próximo nó da sequência.
7. A operação de ______ adiciona um item a uma fila, ao passo que a operação de
______ da fila remove um item de uma fila.
8. O algoritmo QuickSort usa operações de ______ e comparação para organizar os
elementos de uma lista na ordem correta.
9. Um(a) ______ é responsável por analisar as necessidades comerciais e convertê-las
em requisitos que possam ser executados pela equipe de desenvolvimento.
10. Os testes alfa e beta fazem parte do teste de ______ de um sistema.

Múltipla escolha
Assinale a letra que corresponde à melhor resposta.
1. O produto que você está desenvolvendo ainda não está concluído, mas você deseja
lançá-lo para um público-alvo maior do cliente para testá-lo e obter feedback.
Em qual dos níveis de teste a seguir essa atividade se enquadraria?
a. Teste de integração
b. Teste de sistema
c. Teste de aceitação
d. Teste de regressão
2. Os testadores de um software têm acesso ao seu código-fonte e planejam escrever
casos de teste que garantam que os métodos retornem valores corretos. Em qual
dos níveis de teste a seguir essa atividade se enquadraria?
a. Teste de integração
b. Teste de unidade
c. Teste alfa
d. Teste beta
3. Qual das estruturas de dados a seguir permite acesso direto a todos os seus itens?
a. Matriz
b. Pilha
c. Fila
d. Lista vinculada
4. Qual das atividades a seguir do ciclo de vida do aplicativo é usada por um arquiteto
para criar o plano gráfico técnico de um sistema?
a. Análise de requisitos
b. Design
c. Desenvolvimento
d. Manutenção
5. No seu aplicativo, você está usando uma estrutura de dados de fila para manipular as
informações. Você precisa descobrir qual item de dados será processado em seguida,
mas não deseja realmente processá-lo. Qual das operações de fila a seguir você usará?
a. Enfileiramento
b. Remoção da fila
c. Espiada
d. Contém
Introdução à programação orientada a objeto | 83

6. Você está desenvolvendo um programa que requer o acompanhamento das chamadas


de método. Você só pode invocar um método de cada vez. Entretanto, uma chamada
de método pode, por sua vez, invocar outros métodos. Quando um método terminar,
ele retornará o controle de volta para o método de chamada. Que estrutura de dados
você deve usar para acompanhar essas chamadas de método?
a. Fila
b. Matriz
c. Lista vinculada
d. Pilha
7. Você está desenvolvendo um programa que simula um processador de trabalhos.
Em geral, os trabalhos são executados mais rápido do que o seu processamento e,
nesse caso, eles aguardam sua vez de serem processados. Você precisa garantir que
o trabalho que chegou primeiro seja também o primeiro a ser processado. Qual das
estruturas de dados a seguir é mais adequada a esse requisito?
a. Matriz
b. Fila
c. Lista vinculada
d. Pilha
8. Você escreve o seguinte código em um programa:
int[] numbers = {2, 3, 1, 4};
numbers [2] = 4;
Qual será o conteúdo da matriz depois que a segunda instrução for executada?
a. {2, 4, 1, 4}
b. {2, 3, 4, 4}
c. {2, 4, 1, 2}
d. {4, 3, 1, 4}
9. Você está desenvolvendo um programa que executa operações frequentes de inserção
e exclusão nos dados. Seu requisito também determina a capacidade de acessar os
registros anteriores e posteriores quando o usuário pressionar o botão Anterior ou
Próximo. Qual das estruturas de dados a seguir será mais adequada aos seus requisitos?
a. Matriz
b. Lista vinculada circular
c. Lista vinculada
d. Lista duplamente vinculada
10. Você está desenvolvendo um programa que executa operações frequentes de inserção
e exclusão nos dados. Os itens de dados precisam ser acessados como uma pilha
com a funcionalidade “último a entrar, primeiro a sair”. Sua solução deve necessitar
do mínimo de memória possível. Qual das estruturas de dados a seguir será mais
adequada a esses requisitos?
a. Matriz
b. Lista vinculada circular
c. Lista vinculada
d. Lista duplamente vinculada

■ Avaliação da competência
Cenário 3-1: Usando matrizes
Você está escrevendo um programa que usa uma matriz bidimensional. A matriz tem
quatro linhas e cinco colunas. Você precisa imprimir o maior elemento de cada linha da
matriz. Como você escreveria esse programa?
84 | lição 3

Cenário 3-2: Usando filas


Você está escrevendo um programa que usa duas filas. Os dados de cada fila já estão em
ordem crescente. Você precisa processar o conteúdo das duas filas de modo que a saída
seja impressa na tela em ordem classificada. Como você escreveria esse programa?

■ Avaliação de proficiência
Cenário 3-3: Usando pilhas
Você está escrevendo um programa que usa duas pilhas. Os dados de cada pilha já estão
em ordem decrescente. Você precisa processar o conteúdo das duas pilhas de modo que
a saída seja impressa na tela em ordem crescente. Como você escreveria esse programa?

Cenário 3-4: Usando listas vinculadas


Você está escrevendo um programa que armazena uma lista de nomes de produto em uma
lista vinculada. O usuário inserirá um nome de produto, e o seu programa precisa verificar
se a lista vinculada contém o produto específico. Como você escreveria esse programa?
Noções básicas sobre LIÇÃO 4
aplicativos Web
M AT R I Z D E H A B I L I D A D E S D A L I Ç Ã O

Habilidades/Conceitos Objetivo do exame MTA Número do objetivo


do exame MTA
Noções básicas sobre o Compreender o desenvolvimento 4.1
desenvolvimento de páginas da Web de páginas da Web.
Noções básicas sobre o Compreender o desenvolvimento 4.2
desenvolvimento de de aplicativos Web do Microsoft
aplicativos ASP.NET ASP.NET.
Noções básicas sobre Compreender a 4.3
a hospedagem Web do IIS hospedagem Web.
Noções básicas sobre desenvolvimento Compreender os serviços Web. 4.4
de serviços Web

P R I N C I PA I S T E R M O S
folhas de estilos em cascata (CSS) JavaScript diretório virtual
programação do lado do cliente SOAP (Simple Object Access Hospedagem Web
gerenciamento de estado do lado Protocol) Serviços Web
do cliente programação do lado do servidor WSDL (Web Service Description
HTML (Hypertext Markup Language) gerenciamento de estado do lado Language)
IIS (Serviços de Informações da Internet) do servidor site
gerenciamento de estado

Você é um desenvolvedor de software de uma organização de grande porte.


Você precisa desenvolver um aplicativo que possa ser usado em uma rede, como
a World Wide Web. O aplicativo será implantado em um servidor Web que executa
o Windows, mas os usuários do aplicativo usarão vários sistemas operacionais
e navegadores da Web.

■ Noções básicas sobre o desenvolvimento de páginas da Web

Uma página da Web é um documento disponibilizado na World Wide Web (WWW)


e pode ser exibido por um navegador da Web. As páginas da Web são desenvolvidas
O RESULTADO usando a linguagem HTML (Hypertext Markup Language) e são armazenadas em um
servidor Web. Os navegadores da Web baixam o HTML solicitado do servidor Web,
renderizando-o na tela do usuário.
85
86 | lição 4

A World Wide Web (também conhecida como WWW ou “a Web”) é um sistema de


documentos de hipertexto interconectados e outros recursos (como imagens e vídeo)
que podem ser acessados pela Internet. Várias tecnologias trabalham em conjunto para
viabilizar a WWW. Nesta seção, discutiremos duas dessas tecnologias:
• HTTP (Hypertext Transfer Protocol)
• HTML (Hypertext Markup Language)
HTTP é o protocolo de comunicação subjacente usado pela World Wide Web. Ele fornece
a linguagem comum usada por navegadores e servidores Web para se comunicar.
O HTTP usa uma URL (Uniform Resource Locator) para identificar e endereçar cada recurso
na Internet de forma exclusiva. Uma URL é essencialmente um endereço Web e é semelhante
a este: http://www.microsoft.com/en/us/default.aspx. Cada URL começa com um protocolo.
Neste exemplo, o protocolo é HTTP. Você também poderá observar o protocolo HTTPS
(HTTP seguro) em uso para aplicações seguras em que os dados precisam ser criptografados
antes de serem transmitidos pela rede. Após o protocolo, a próxima parte de uma URL é
o endereço do servidor Web (aqui, www.microsoft.com), seguido do local do recurso dentro
do servidor Web (/pt-br/) e, finalmente, o próprio recurso solicitado (default. aspx). Todos
os documentos, imagens, vídeos e outros recursos na Web são identificados por uma URL.
Quando um navegador envia uma solicitação HTTP de uma página da Web a um servidor
Web (a página da Web e o servidor são identificados por uma URL), o servidor prepara
uma resposta HTTP para o navegador. Essa resposta especifica o conteúdo e o layout da
página da Web.

Os termos "Internet" e "Web" são usados com frequência de maneira intercambiável,


mas, na verdade, eles são distintos e não devem ser confundidos. A Internet é
*
TOME NOTA um sistema de comunicações de dados global que fornece conectividade entre
computadores. Por outro lado, a Web é um dos vários serviços disponíveis na Internet
que permite que os usuários acessem recursos vinculados por hiperlink.

A linguagem HTML (Hypertext Markup Language) é a usada pelo servidor Web e pelo
navegador da Web para descrever uma página da Web. HTML é uma linguagem baseada
em texto que usa diversas marcas que descrevem como o conteúdo é exibido. O HTML
permite que imagens, vídeos e outros objetos sejam referenciados em um arquivo para
criar páginas da Web multimídia. O HTML também pode inserir scripts (como JavaScript)
que afetam o comportamento das páginas da Web e pode ser usado para incluir folhas de
estilos em cascata (CSS) para definir a formatação e o layout do conteúdo de uma página.
O navegador da Web lê o código HTML e renderiza os resultados na tela.
Uma página da Web pode conter hiperlinks para outros recursos, como imagens e vídeos.
Cada um desses recursos é identificado por sua própria URL. Assim, para renderizar uma
página completamente, o navegador fará solicitações HTTP adicionais para obter esses
recursos e exibi-los como parte da página da Web.
Nas seções a seguir, você aprenderá mais sobre os vários componentes que compõem uma
página da Web, incluindo HTML, CSS e JavaScript.

Noções básicas sobre HTML

Linguagem HTML é a linguagem usada por servidores e navegadores Web para


descrever uma página da Web.

A finalidade do HTML é fornecer uma linguagem padrão para descrever as páginas da


Web, de modo que diferentes navegadores da Web possam compreender essa linguagem e
exibir a página correspondente. HTML é uma linguagem baseada em texto, o que significa
que você pode escrever e editar páginas HTML usando qualquer editor de texto. Quando
Noções básicas sobre aplicativos Web | 87

o HTML é enviado a um navegador da Web, o texto completo da página é enviado.


TOME NOTA
* Na verdade, a maioria dos navegadores permitem que você exiba o código fonte HTML
HTML é baseado em para uma página da Web.
texto quando se trata
de escrever o código. O HTML é composto por um conjunto de marcas (também denominadas elementos
O HTML oferece HTML) que definem a estrutura e o conteúdo de uma página. Por exemplo, a marca
marcas para inserir <html> especifica o início de um documento HTML. As marcas HTML estão sempre
fotos, áudio, vídeo e entre colchetes angulares e são sempre usadas em pares. Em particular, cada marca
vários outros tipos de inicial tem uma marca final correspondente. As marcas finais contêm uma barra “/”
conteúdo multimídia para indicá-las. Por exemplo, a marca final de <html> é </html>.
e interativo em uma Uma página HTML tem duas partes distintas: um cabeçalho e um corpo. O cabeçalho
página da Web. é colocado dentro das marcas <head> e </head>, e é usado para fornecer um título de
documento e links para itens externos que podem ser usados na página, como arquivos
CSS e arquivos JavaScript. O corpo é colocado dentro das marcas <body> e </body>,
e é usado para fornecer a estrutura completa e o conteúdo da página que será exibida
TOME NOTA
* em um navegador da Web.
Neste exemplo, observe Este é um exemplo de uma marca HTML que exibe uma imagem:
que o documento
HTML não contém <img height="400px" width="400px"
a imagem em si. Em alt="Mimas Cassini" src=
vez disso, a marca "http://upload.wikimedia.org/wikipedia/commons/b/bc/Mimas_Cassini.jpg"/>
<img> especifica a Observe que a marca <img> especifica atributos adicionais. Por exemplo, o atributo src
URL da imagem, que especifica o local do arquivo de imagem, e os atributos height e width especificam quais
o navegador baixa dimensões usar ao renderizar a imagem em um navegador.
separadamente e
renderiza como parte Agora, considere um outro exemplo de uma marca HTML:
da página. <a href="http://en.wikipedia.org/wiki/Mimas_(moon)">
Saturn’s moon</a>
Aqui, <a> é a marca de ancoragem usada para criar hiperlinks em uma página da Web.
O atributo href associado a essa marca especifica a URL de destino, e o texto dentro da
marca de ancoragem é a exibida como um link.

Esta lição não abrange todos os elementos HTML. Para saber mais sobre esses
TOME NOTA
* elementos, procure por "Elementos HTML" no MSDN.

O exercício a seguir demonstra as etapas envolvidas na criação de um documento HTML.

TRABALHAR COM HTML

PREPARE-SE. Para criar um documento HTML, execute estas ações:


1. Abra o Visual Studio. Crie um novo projeto com base no modelo Aplicativo Web Vazio
do ASP.NET. Nomeie o projeto como WorkingWithHTML e a solução como Lesson04.
2. Selecione Projeto > Adicionar Novo Item e, em seguida, selecione o modelo Página
HTML. Nomeie o arquivo como default.htm.
3. Substitua o código padrão no arquivo HTML pelo seguinte:
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Lua de Saturno</title>
</head>
88 | lição 4

<body>
<h1>Mimas Cassini</h1>
A marca img é usada para exibir a imagem de uma
<a href="http://en.wikipedia.org/wiki/Mimas_(moon)">
lua de Saturno</a>: <br />
<img height="400px" width="400px"
alt="Mimas Cassini"
src="http://goo.gl/3BeK"/>
</body>
</html>
4. Selecione Depurar > Iniciar Depuração (ou pressione F5). A página default.htm será
aberta em um navegador da Web. A saída deve ser semelhante à figura 4-1, onde você
poderá ver as marcas <img> e <a> em ação.

Figura 4-1
Uma página HTML simples
contendo uma imagem e um
hiperlink

Noções básicas sobre folhas de estilos em cascata

As folhas de estilos em cascata (CSS) permitem que você armazene o estilo e as


informações de formatação de uma página da Web separadas do código HTML.
Esta separação facilita a atualização da aparência do seu site. O Visual Studio inclui
ferramentas para compilar e visualizar suas folhas de estilos.
CSS é uma linguagem que descreve as informações sobre como exibir uma página da Web.
Durante a renderização de páginas da Web em um navegador, o HTML especifica o que
será exibido, e as folhas de estilos em cascata (CSS) determinam como esse material será
exibido. Por exemplo, HTML pode especificar que o documento tenha um título H1 com um
determinado texto, e CSS pode determinar a fonte e a cor que serão aplicadas a esse título.
CSS permite separar o layout de uma página da Web do seu conteúdo. Essa separação
permite que você altere um sem afetar o outro. A mistura de conteúdo e estilo reduz a
Noções básicas sobre aplicativos Web | 89

facilidade de manutenção de um site. Por exemplo, suponha que você queira alterar a cor
e a fonte de todos os títulos H1 em seu site. Uma abordagem pode ser abrir um editor de
HTML e modificar cada arquivo no site que usa a marca H1. Isso poderá ser uma solução
aceitável se o site tiver apenas uma ou duas páginas, mas e se o site tiver um grande
número de páginas, por exemplo, 50 ou 100? Imagine alterar manualmente cada página!
TOME NOTA
* Se essas alterações forem solicitadas com frequência, o processo de desenvolvimento da
Quando usado Web será entediante e propenso a erro. Afinal, como você pode garantir que não perdeu
efetivamente, nenhuma marca H1?
CSS é uma ótima Felizmente, com o CSS, você poderá incluir todas as informações de estilo em um arquivo
ferramenta para separado e conectar esse arquivo a todas as páginas em um site. Em seguida, assim que
aumentar a consistência o arquivo CSS estiver configurado, você poderá modificar qualquer estilo (por exemplo,
e a facilidade de a cor e a fonte dos títulos H1) simplesmente alterando o estilo no arquivo CSS — e essa
manutenção de todo única alteração afetará todas as páginas no site.
o site.
PROJETANDO FOLHAS DE ESTILOS EM CASCATA
A linguagem CSS é baseada em texto e fácil de ler e compreender. O exemplo a seguir
é de uma página HTML que define estilos CSS:
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>Noções básicas sobre CSS</title>
<style type="text/css">
body
{
font-family: Verdana;
font-size: 9pt;
}
div
{
color:Red;
}
.block
{
background-color: Yellow;
border-color: Blue;
border-width: thin;
border-style: outset;
font-family: Arial;
}
</style>
</head>
<body>
Texto de corpo de exemplo <br />
<div>Texto de DIV de exemplo</div>
<div class="block">Texto de DIV de exemplo
com classe block</div>
<span class="block">Texto de SPAN de exemplo
com classe block</span>
</body>
</html>
90 | lição 4

Observe que as definições CSS devem estar dentro do elemento <style> e são definidas
sob o elemento <head>. Esse CSS específico define dois estilos de elemento e um estilo de
classe. O primeiro estilo aplica-se ao elemento body HTML e especifica que todo o texto
no elemento body deve usar a fonte Verdana e 9 pontos de tamanho. O segundo estilo de
elemento especifica que o texto dentro do elemento DIV deve ser escrito em vermelho.
Finalmente, uma classe denominada “block” é definida. As definições de classe CSS são
prefixadas com um ponto (“.”). O conteúdo de qualquer elemento HTML que usa essa
classe será exibido com plano de fundo amarelo e uma borda. Quando você exibir essa
página específica em um navegador, ela deverá aparecer conforme mostra a figura 4-2.

Figura 4-2
Formatando HTML com
folhas de estilos em cascata

Na figura, observe que o texto realçado é exibido como resultado da classe block. No
entanto, a classe CSS block não especifica a cor do texto. Na primeira linha do texto
realçado, a classe block é aplicada ao elemento DIV; na segunda linha do texto realçado,
a classe block é aplicada ao elemento SPAN. No primeiro caso, como a classe block é
aplicada a um texto DIV, o estilo de cor do elemento DIV é transportado na renderização
final.
No exemplo anterior, o arquivo CSS foi escrito dentro do arquivo HTML. Uma
abordagem mais útil consiste em escrever o CSS em seu próprio arquivo separado e, em
seguida, vincular o arquivo HTML a esse arquivo CSS. Você aprenderá como fazer isso
no próximo exercício.

TRABALHAR COM ARQUIVOS CSS

PREPARE-SE. Para escrever um arquivo CSS e vinculá-lo a um arquivo HTML, execute


estas etapas:
1. Adicione um novo projeto com base no modelo Aplicativo Web Vazio do ASP.NET para
a solução Lesson04. Nomeie o projeto como UnderstandingCSS.
2. Selecione Projeto > Adicionar Novo Item. Selecione o modelo Folha de Estilos.
Nomeie o arquivo como styles.css. Substitua o código padrão no arquivo por este:
body
{
font-family: Verdana;
font-size: 9pt;
}
div
{
color:Red;
}
Noções básicas sobre aplicativos Web | 91

.block
{
background-color: Yellow;
border-color: Blue;
border-width: thin;
border-style: outset;
font-family: Arial;
}
3. Selecione Projeto > Adicionar Novo Item e, em seguida, selecione o modelo Página
HTML. Nomeie o arquivo como default.htm. Substitua o código padrão no arquivo por
este:
<!DOCTYPE html PUBLIC
"–//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1–
transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<link rel="STYLESHEET"
type="text/css" href="styles.css" />
<title>Noções básicas sobre CSS</title>
</head>
<body>
Texto do corpo de exemplo <br />
<div>Texto de DIV de exemplo</div>
<div class="block">Texto de DIV de exemplo
com classe bloco</div>
<span class="block">Texto de SPAN de exemplo
com classe bloco</span>
</body>
</html>
TOME NOTA
* 4. Selecione Depurar > Iniciar Depuração (ou pressione F5). A página default.htm
Quando CSS forem será aberta em um navegador da Web, e a saída deverá ser semelhante à figura 4-2
armazenadas em (apresentada anteriormente).
arquivos separados, o
navegador do usuário Conforme mostrado no exercício de exemplo, o elemento HTML <link> é usado para
baixará e armazenará vincular um arquivo CSS a uma página HTML:
esses arquivos <link rel="STYLESHEET"
localmente. Portanto, type="text/css" href="styles.css" />
elas poderão ser usadas
em várias páginas, sem O elemento <link> é sempre colocado dentro do elemento <head>, e o atributo href
qualquer necessidade especifica o endereço do arquivo CSS a ser usado. Para vincular várias páginas ao mesmo
de serem baixadas arquivo CSS, você precisará colocar o elemento <link> dentro de cada página HTML.
novamente. Isso reduz O Visual Studio inclui um designer de estilo interno que pode ajudar você a projetar
a transferência de novos estilos CSS ou modificar os estilos existentes. Ao abrir um arquivo .css, você
dados desnecessária. verá um novo menu denominado Estilos. Nesse menu, você pode criar um novo estilo,
selecionando Estilos > Adicionar Regra de Estilo. Você também pode modificar o estilo
escolhido no momento, selecionando a opção Estilos > Criar Estilo. Essa opção abre caixa
de diálogo Modificar Estilo, como mostra a figura 4-3.
92 | lição 4

Figura 4-3
Caixa de diálogo Modificar
Estilo

Noções básicas sobre JavaScript

JavaScript é uma linguagem de scripts do lado do cliente que é executada dentro de


navegadores da Web para ajudar a criar páginas da Web muito mais interativas do
que é possível apenas com HTML. O JavaScript é usado em milhões de páginas da
Web e é compatível com todos os navegadores da Web modernos.

O JavaScript é usado para tornar os sites mais dinâmicos e as páginas da Web mais
interativas. Com o JavaScript, isso é feito executando o código no lado do cliente (o
navegador da Web) e minimizando as viagens de ida e volta desnecessárias entre o
servidor Web. Vamos usar um exemplo em que um usuário precisa inserir detalhes
pessoais em uma página da Web, como nome, endereço de email e número de telefone.
Um requisito comum consiste em executar a validação dos dados para garantir que os
campos de entrada não estejam vazios e o endereço de email e o número de telefone
do usuário tenham sido fornecidos no formulário obrigatório. Sem o JavaScript, você
precisaria enviar o formulário para o servidor, que executaria a validação do dados
e retornaria os resultados ao cliente. Essa transmissão de informações leva tempo e
prejudica a experiência do usuário. No entanto, uma solução JavaScript pode executar
esse tipo de validação de dados a partir do navegador, proporcionando uma melhor
experiência do usuário.
Como mencionado anteriormente, o código JavaScript é executado localmente dentro
do navegador da Web (o cliente), e não no servidor Web. Portanto, o JavaScript às vezes
também é chamado de linguagem de scripts do lado do cliente, e a programação com
JavaScript é chamada de programação do lado do cliente.
O comportamento em tempo de execução da execução do código do lado do cliente
dependerá do navegador que o executar. No entanto, esse comportamento é independente
da tecnologia de servidor ou da estrutura de programação. Portanto, para o JavaScript
que está sendo executado em um navegador da Web, não importa se a página da Web foi
gerada por ASP.NET ou PHP ou se a página está sendo disponibilizada por um servidor
Web do Windows ou do Linux.
Tanto o JavaScript quanto a linguagem de programação C# usam uma sintaxe influenciada
pela linguagem de programação C. Apesar disso, JavaScript e C# são muito diferentes em
seu modo de execução. Em particular, o JavaScript é executado pelo navegador da Web, e
o código JavaScript é interpretado, em vez de ser compilado, como no caso de C#.
Noções básicas sobre aplicativos Web | 93

Vários sites modernos fornecem uma experiência altamente interativa, rivalizando com
a de aplicativos desktop. Esses sites podem ser desenvolvidos usando a programação
Ajax. Ajax é uma abreviação de "Asynchronous JavaScript and XML". Ajax usa
*
TOME NOTA
JavaScript extensivamente para fornecer aplicativos Web dinâmicos. A estrutura do
AJAX ASP.NET permite que você implemente a funcionalidade Ajax nas páginas da
Web ASP.NET.

Todo o código JavaScript deve ser colocado dentro do elemento <script>. O elemento
<script> geralmente é colocado dentro do elemento <head>, embora isso não seja
necessário. Vários elementos <script> podem existir dentro de uma única página. Para ver
o JavaScript em ação, execute o exercício a seguir.

TRABALHAR COM JAVASCRIPT

PREPARE-SE. Para começar a trabalhar com JavaScript, execute as seguintes tarefas:


1. Adicione um novo projeto com base no modelo Aplicativo Web Vazio do ASP.NET para
a solução Lesson04. Nomeie o projeto como UnderstandingJavaScript.
2. Selecione Projeto > Adicionar Novo Item e, em seguida, selecione o modelo Página HTML.
Nomeie o arquivo como default.htm. Substitua o código padrão no arquivo por este:
<!DOCTYPE html PUBLIC
"–//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1–
transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Noções básicas sobre JavaScript</title>
<script type="text/javascript"
language="javascript">
username = prompt("Insira seu nome");
message = "Olá, " + username +
". Seu nome tem ";
nameLen = username.length;
if (nameLen > 5)
message = message + "mais de ";
else if (nameLen < 5)
message = message + "menos de ";
else
message = message + "exatamente ";
message = message + "5 caracteres.";
alert(message);
</script>
</head>
<body>
</body>
</html>
94 | lição 4

3. Selecione Depurar > Iniciar Depuração (ou pressione F5). A página default.htm será
aberta em um navegador da Web. Observe que o código JavaScript solicita que você
insira seu nome. Em seguida, uma caixa de diálogo exibe uma mensagem com base no
comprimento do seu nome, como mostram as figuras 4-4 e 4-5.

Figura 4-4
Prompt de usuário de
JavaScript

Figura 4-5
Caixa de diálogo JavaScript

Assim como acontece com os arquivos CSS, você também pode colocar seu código
JavaScript em um arquivo separado e vincular esse arquivo a um arquivo HTML, usando
o elemento script, conforme mostrado abaixo:
<script src="SampleScript.js">
</script>
Aqui, o arquivo SampleScript.js contém todo o código JavaScript, e o elemento script
TOME NOTA
* é vinculado a esse arquivo, usando o atributo src. O armazenamento do JavaScript em
Embora todos os arquivos externos oferece várias vantagens:
navegadores modernos
ofereçam suporte a • Maior facilidade de manutenção: se usar o mesmo código JavaScript em cada
JavaScript, eles podem página de um site, você poderá armazenar o código em uma página central, em vez
ser definidos para de repeti-lo em cada página. Dessa forma, quando for o momento de modificar o
que JavaScript seja código JavaScript, você precisará alterá-lo em um único lugar.
desligado. Você pode • Melhor desempenho: o armazenamento do código JavaScript em um arquivo
usar um elemento separado reduz o tamanho de uma página da Web. Além disso, os navegadores
<noscript> para podem baixar e armazenar em cache o arquivo JavaScript externo para que ele não
exibir uma mensagem seja baixado novamente, a menos que seja modificado.
específica aos usuários
O Visual Studio inclui suporte total do IntelliSense para o código JavaScript. Até mesmo
que optarem por não
os controles ASP.NET, como o controle TreeView ou os controles de validação, usam
executar o JavaScript.
JavaScript sempre que possível para renderizar um conteúdo dinamicamente.
Noções básicas sobre programação do lado do cliente versus lado do servidor
Um programa do lado do cliente ou do lado do servidor depende de onde ele é
executado no final.

A programação do lado do cliente refere-se aos programas executados completamente


no computador local de um usuário. O aplicativo Windows Forms e o código JavaScript
executado dentro de um navegador da Web são exemplos de programas do lado do cliente.
Os programas do lado do cliente não consomem recursos do servidor.
Por outro lado, a programação do lado do servidor refere-se aos programas executados
completamente em um servidor e que usam os recursos computacionais do servidor.
Aqui, os únicos recursos do cliente utilizados são os envolvidos na real recuperação dos
Noções básicas sobre aplicativos Web | 95

resultados de processamento do servidor. Os aplicativos e os serviços Web são exemplos


de programação do lado do servidor. Esse tipo de programação usa uma tecnologia do
lado do servidor, como ASP.NET, PHP ou Ruby on Rails.
Recentemente, os aplicativos híbridos que usam tanto programação do lado do cliente
quanto do lado do servidor tornaram-se mais populares. Por exemplo, você pode projetar
PRONTO PARA
CERTIFICAÇÃO aplicativos cliente inteligentes que sejam executados localmente nos computadores cliente,
Você compreende mas usar serviços Web para realizar determinadas tarefas. Na verdade, os aplicativos Ajax
como usar HTML, usam uma mistura de programação do lado do servidor e código do lado do cliente para
JavaScript e CSS para criar aplicativos Web interativos e altamente responsivos.
desenvolvimento de
O ASP.NET permite que você crie aplicativos que sejam executados completamente no
páginas da Web?
4.1
servidor ou nos aplicativos híbridos Ajax que fornecem interfaces rápidas e dinâmicas
durante o armazenamento da maioria de seus dados na Web.

■ Noções básicas sobre o desenvolvimento de aplicativos ASP.NET

ASP.NET é a parte do .NET Framework que permite desenvolver formulários


e serviços Web programáveis. Assim como com qualquer aplicativo .NET Framework,
O RESULTADO você pode desenvolver aplicativos ASP.NET em qualquer linguagem compatível com
o .NET Common Language Runtime, incluindo Visual Basic e C#.

A infraestrutura do ASP.NET tem duas partes principais:


• Um conjunto de classes e interfaces que permite a comunicação entre o navegador
e o servidor Web. Essas classes são organizadas no namespace System.Web.
• Um processo de tempo de execução, também conhecido como o processo de trabalho
ASP.NET (aspnet_wp.exe), que manipula a solicitação da Web para recursos ASP.
NET.
Em um nível mais alto, um aplicativo Web ASP.NET é executado através de uma série
de mensagens de resposta e solicitações HTTP entre o navegador do cliente e o servidor
Web. Esse processo ocorre da seguinte forma:
1. O usuário solicita um recurso de um servidor Web, digitando uma URL no navegador
da Web. O navegador envia uma solicitação HTTP para o servidor Web de destino.
2. O servidor Web analisa a solicitação HTTP e procura um processo capaz de executar
a solicitação.
3. O resultado da solicitação HTTP é retornado ao navegador do cliente sob a forma
de uma resposta HTTP.
4. O navegador lê a resposta HTTP e renderiza-o como uma página da Web para
o usuário.
Este processo é representado na figura 4-6.

Figura 4-6
Comunicação entre um
cliente e um servidor Web
96 | lição 4

Como desenvolvedor, você deve saber de forma oculta quando um servidor Web executa
uma solicitação de uma página ASP.NET. As etapas a seguir descrevem esse processo:
1. Quando o IIS (Serviços de Informações da Internet) recebe uma solicitação HTTP,
ele usa a extensão de nome de arquivo para determinar qual programa ISAPI
(Internet Server Application Programming Interface) deve ser executado para
processar a solicitação. Quando a solicitação for para uma página ASP.NET, ele
passará a solicitação para a DLL ISAPI capaz de lidar com solicitações de páginas
ASP.NET, a aspnet_isapi.dll.
2. O processo aspnet_isapi.dll passa a solicitação para o processo de trabalho ASP.NET
(aspnet_wp.exe), que atende à solicitação.
3. O processo de trabalho ASP.NET compila o arquivo .aspx em um assembly e instrui
o CLR (Common Language Runtime) para executar o assembly.
4. Quando o assembly é executado, ele utiliza os serviços de várias classes na biblioteca
de classes .NET Framework para realizar o seu trabalho e gerar mensagens de
resposta para o cliente solicitante.
5. O processo de trabalho ASP.NET coleta as respostas geradas pela execução da página
da Web, cria um pacote de resposta e passa-o para o processo aspnet_isapi.dll.
6. O aspnet_isapi.dll, encaminha o pacote de resposta para o IIS, que, por sua vez, passa
a resposta para a máquina cliente solicitante.
Antes da execução, cada página ASP.NET é convertida em uma classe. Essa classe deriva
a maior parte de sua funcionalidade da classe System.Web.UI.Page. A classe Page fornece
várias propriedades importantes, como Request, Response, Session e Server.

A classe Page fornece vários métodos e propriedades importantes que controlam como
*
TOME NOTA uma solicitação de página é processada. Para obter uma lista completa de métodos
e propriedades, visite http://msdn.microsoft.com/en-us/library/system.web.ui.page.aspx.

Noções básicas sobre o ciclo de vida da página do ASP.NET


e do modelo de eventos

Durante sua execução, uma página ASP.NET passa por vários estágios distintos
de processamento. Cada um desses estágios passa por etapas de processamento
específicas, como inicialização, carregamento, execução do código de manipulador
de eventos e renderização.

Quando uma página é executada, ela passa por vários estágios de processamento. A
página também dispara alguns eventos aos quais você pode anexar um manipulador de
eventos para executar um código personalizado em diferentes estágios de processamento
da página. Na verdade, os desenvolvedores ASP.NET devem ter uma boa compreensão do
ciclo de vida da página, para poderem escrever o código executado exatamente no estágio
desejado de processamento da página.
A tabela 4.1 lista os diferentes estágios do ciclo de vida e seus eventos associados.

Em um formulário de contato típico, você insere informações e pressiona o botão


Enviar. Quando você envia essa página, a página pode processar os dados enviados
para executar alguma ação, como armazenar as informações em um banco de dados
ou enviar um email. Em vários casos, a página inicial é exibida novamente com uma
*
TOME NOTA
confirmação do envio do formulário. Um postback ocorre quando as informações são
postadas na mesma página da Web para processamento. Um postback é diferente da
carga inicial da página, pois a página recebe informações adicionais (como dados de
formulário) como parte do postback.
Noções básicas sobre aplicativos Web | 97

Tabela 4-1
Estágios importantes no ciclo de vida da página ASP.NET

Estágio Significado Eventos associados


Solicitação de página Quando uma solicitação de página é recebida, começa o ciclo de
vida da página. Neste ponto, o ASP.NET decide se a página pode
ser prontamente disponibilizada do cache ou se precisa ser
analisada e compilada.
Início O estágio inicial envolve determinar se a solicitação é um PreInit
postback ou uma nova solicitação. Várias propriedades de
página, como Request, Response, IsPostBack, and UICulture,
são definidas neste estágio.
Inicialização Durante a fase de inicialização, todos os controles na página são Init
inicializados e disponibilizados. Um manipulador de eventos
para o evento Init é o melhor lugar para o código que você
deseja que seja executado antes do processamento da página.
Carregamento Se a solicitação for um postback, o estágio de carga será usado Load
para restaurar as propriedades de controle com informações de
estado de exibição e estado de controle. Um método que
manipula o evento Load é o melhor lugar para armazenar
o código de inicialização para qualquer controle específico
a essa página.
Tratamento do evento Se a solicitação for um postback, os manipuladores de eventos
postback de controle serão chamados durante este estágio. Em seguida,
os valores de entrada são validados e a propriedade IsValid
para a classe Page é definida.
Pré-renderização Nesta fase sinaliza que a página está prestes a renderizar o seu PreRender
conteúdo. Um manipulador do evento PreRender é a última
chance de modificar a saída da página antes que ela seja
enviada para o cliente.
Renderização Neste estágio, a página chama o método Render para cada
controle e preenche a resposta que será enviada para
o navegador da Web.
Descarregamento Durante o estágio de descarregamento, a resposta é enviada Unload
ao cliente, e a limpeza da página é realizada. Como parte
dessa limpeza, as propriedades de página, como Request
e Response, são descartadas.

Quando quiser manipular um evento, você deve escrever um código que registre um método para
manipular o evento (também chamado de manipulador de eventos) com o evento. Isso geralmente
é feito usando o padrão de registro de evento comum empregado em todo o .NET Framework:
object.event += new EventHandler(eventhandler);
Aqui, substitua object pelo nome do objeto que expõe o evento, event pelo nome do evento
e eventhandler pelo nome do método que manipula o evento.
No entanto, observe que o ASP.NET fornece, por padrão, seis métodos especiais que são
reconhecidos como manipuladores de eventos e não precisam do código de registro acima.
Eles são os métodos especialmente nomeados Page_Load, Page_Init, Page_DataBind,
Page_PreRender e Page_Unload. Esses métodos são tratados como manipuladores de
eventos para os eventos correspondentes expostos pela classe Page. Essa ligação automática
de eventos é controlada pelo atributo AutoEventWireup da diretiva @Page. Por padrão,
o valor desse atributo é true, o que significa que esses métodos especialmente nomeados são
automaticamente conectados aos seus eventos correspondentes.
98 | lição 4

COMPREENDER O CICLO DE VIDA DA PÁGINA ASP.NET

PREPARE-SE. Para ver como diferentes eventos de classe Page são executados, realize
estas ações:
1. Crie um novo projeto com base no modelo Aplicativo Web Vazio do ASP.NET para a
solução Lesson04. Nomeie o projeto como PageEvents.
2. Selecione Projeto > Adicionar Novo Item. Selecione o modelo Formulário da Web.
Nomeie o arquivo como WebForm1.aspx.
3. Na marcação HTML da página (WebForm1.aspx), verifique se o atributo
AutoEventWireup para a diretiva @Page é definido como true:
<%@ Page Language="C#" AutoEventWireup="true"
CodeBehind="WebForm1.aspx.cs"
Inherits="PageEvents.WebForm1" %>
4. Clique com o botão direito do mouse na janela de código e selecione Exibir Código no
menu de atalho para alternar para o modo de exibição de código. Substitua o código
no arquivo code-behind (WebForm1) por este:
using System;
namespace PageEvents
{
public partial class WebForm1
: System.Web.UI.Page
{
protected void Page_Load
(object sender, EventArgs e)
{
Response.Write
("Message from Page_Load. <br/>");
}
protected void Page_Init
(object sender, EventArgs e)
{
Response.Write
("Mensagem de Page_Init. <br/>");
}
protected void Page_PreRender
(object sender, EventArgs e)
{
Response.Write
("Mensagem de Page_PreRender. <br/>");
}
protected void Page_PreInit
(object sender, EventArgs e)
{
Response.Write
("Mensagem de Page_PreInit. <br/>");
}
}
}
Noções básicas sobre aplicativos Web | 99

5. Selecione Depurar > Iniciar Depuração (ou pressione F5). A página default.htm será
aberta em um navegador da Web, como mostra a figura 4-7.

Figura 4-7
Formulário da Web exibindo
a ordem de execução de
eventos para uma página
ASP.NET

No exercício de exemplo, observe que os caracteres <% e %> são usados para inserir
blocos de código na marcação HTML de uma página. O código dentro desses blocos
inseridos é executado durante o estágio de renderização da página. Dentro dos blocos
de código inseridos, a sintaxe <%=expression> é usada para resolver uma expressão
e retornar seu valor ao bloco. Por exemplo, considere o seguinte bloco de código:
<i><% = DateTime.Now.ToShortDateString() %></i>
Quando executado, esse código exibirá a data atual em itálico:
12/01/2010
A diretiva @Page especifica vários atributos que controlam como o ASP.NET renderizará
uma página. Por exemplo, neste exercício, os atributos da diretiva @Page especificam
o seguinte:
• C# é a linguagem de programação desta página da Web (Language="C#")
• Os eventos da página são automaticamente ligados (AutoEventWireup=true)
• O nome do arquivo de código que contém a classe associada à página
(CodeBehind="WebForm1.aspx.cs")
• O nome de classe para a página a ser herdada (Inherits="PageEvents.WebForm1")

Noções básicas sobre o gerenciamento de estado


O gerenciamento de estado é uma questão importante para os aplicativos Web devido
à natureza desconectada de HTTP. Há técnicas do lado do cliente e do lado do
servidor disponíveis para gerenciamento de estado.

O gerenciamento de estado é o processo que mantém o estado de uma página da Web nas
viagens de ida e volta. Os valores das variáveis e dos controles compõem coletivamente o
estado de uma página da Web.
O ASP.NET fornece várias técnicas para preservar as informações de estado nos postbacks
de página. Essas técnicas podem ser amplamente classificadas como do lado do cliente ou
do lado do servidor, dependendo de onde os recursos são consumidos.
100 | lição 4

INTRODUÇÃO AO GERENCIAMENTO DE ESTADO DO LADO DO CLIENTE


O gerenciamento de estado do lado do cliente usa código HTML e os recursos do
navegador da Web para armazenar informações de estado no computador cliente. As
técnicas a seguir são usadas para armazenar informações de estado no lado do cliente:
• Cadeias de caracteres de consulta: aqui, o estado é mantido colocando os dados
como um conjunto de pares de chave-valor na parte de cadeia de caracteres de
consulta de uma URL da página. Por exemplo, a URL a seguir insere um par chave
de cadeia de caracteres de consulta (q) e valor (television): http://www.bing.com/
search?q=television. Para recuperar o valor da chave em uma página ASP.NET, use
a expressão Request.QueryString[“q”]. QueryString é uma propriedade do objeto
Request e obtém a coleção de todas as variáveis de cadeia de caracteres de consulta.
• Cookies: Cookies são pequenos pacotes de informação que são armazenados
localmente por um navegador da Web no computador do usuário. os cookies são
comumente empregados para armazenar as preferências do usuário e o conteúdo
do carrinho de compras e para dar aos usuários uma experiência de navegação
personalizada nas visitas subsequentes a uma página da Web. A classe HttpCookie
representa um cookie em seu código. O código a seguir mostra como definir um
cookie em um computador cliente:
HttpCookie cookie =
new HttpCookie("Name", "Bob");
cookie.Expires = DateTime.Now.AddMinutes(10);
Response.Cookies.Add(cookie);
Da mesma forma, o trecho de código a seguir mostra como ler um cookie:
if (Request.Cookies["Name"] != null)
{
name = Request.Cookies["Name"].Value;
}
• Campos ocultos: Campos ocultos contêm informações que não são exibidas em
uma página da Web, mas ainda assim faz parte do código da página HTML. campos
ocultos podem ser criados usando o elemento HTML <input type="hidden">. O
controle do servidor HTML ASP.NET HtmlInputHidden também mapeia para esse
elemento HTML.
• ViewState: ViewState é o mecanismo usado pelo ASP.NET para manter o estado dos
controles nos postbacks de página. Para facilitar isso, quando o ASP.NET executa
uma página, ele coleta os valores de todos os controles não postbacks que são
modificados no código e formata-os em uma única cadeia de caracteres codificada.
Essa cadeia de caracteres é armazenada em um campo oculto de um controle
denominado __VIEWSTATE. Por padrão, ViewState é habilitado em um aplicativo
ASP.NET. Você pode desabilitar ViewState no nível de um controle, definindo a
propriedade EnableViewState do controle como false:
<asp:GridView ID="GridView1"
runat="server" EnableViewState="false" />
Além disso, você pode desabilitar ViewState no nível da página, definindo o atributo
EnableViewState da diretiva Page como false:
<%@ Page EnableViewState="false" %>
Finalmente, você pode desabilitar ViewState no nível de aplicativo, adicionando a
linha a seguir ao arquivo web.config:
<pages enableViewState="false" />
Noções básicas sobre aplicativos Web | 101

INTRODUÇÃO A GERENCIAMENTO DE ESTADO DO LADO DO SERVIDOR


O gerenciamento de estado do lado do servidor usa recursos do servidor para armazenar
informações de estado. O uso de técnicas do lado do servidor elimina a possibilidade de
um usuário tentar invadir o código do lado do cliente ou ler os dados da sessão. Entretanto,
o armazenamento e o processamento das informações de sessão em um servidor aumenta a
carga do servidor e exige recursos adicionais do servidor para atender às páginas da Web.
ASP.NET oferece suporte ao gerenciamento de estado do lado do servidor em dois níveis:
• Estado de sessão: um aplicativo ASP.NET cria uma sessão exclusiva para
cada usuário que envia uma solicitação para o aplicativo. o ASP.NET identifica
distintamente cada uma dessas sessões, enviando um SessionId exclusivo à URL
de solicitação. Esse SessionId é transmitido como um cookie ou inserido na URL,
dependendo da configuração do aplicativo. A capacidade de identificar e relacionar as
solicitações de forma exclusiva pode ser usada para armazenar dados específicos de
sessão que também são conhecidos como o estado de sessão do aplicativo Web. Um
exemplo comum de estado de sessão consiste em armazenar o conteúdo do carrinho
de compras para os usuários enquanto eles navegam em uma loja baseada na Web.

O estado de sessão pode ser configurado para o armazenamento em outro servidor ou


em um servidor SQL. Isso é útil quando a solicitação do usuário pode ser processada
*
TOME NOTA por um dos vários servidores em um web farm. Um web farm é uma coleção de
servidores Web utilizados coletivamente para servir um site. Os web farms são
necessários para dar suporte ao tráfego em sites populares.

• Estado do aplicativo: o estado do aplicativo é usado para armazenar dados que


são usados ao longo de um aplicativo. o estado do aplicativo pode ser facilmente
acessado por meio de uma propriedade Application da classe Page. Essa propriedade
fornece acesso ao objeto HttpApplicationState que armazena o estado do aplicativo
como uma coleção de pares chave-valor.
O exercício a seguir mostra como usar o estado de sessão. Esse exercício envolve dois
formulários da Web. O WebForm1.aspx obtém um nome de usuário e armazena-o no
estado de sessão. Em seguida, o formulário transfere o usuário para o WebForm2.aspx,
que recupera o nome de usuário da sessão.

USAR O ESTADO DE SESSÃO

PREPARE-SE. Para usar o estado de sessão, execute as etapas a seguir:


1. Adicione um novo projeto com base no modelo Aplicativo Web Vazio do ASP.NET para
a solução Lesson04. Nomeie o projeto como UsingSessionState.
2. Selecione Projeto > Adicionar Novo Item. Selecione o modelo Formulário da Web.
Nomeie o arquivo como WebForm1.aspx.
3. Altere a marcação HTML do WebForm1.aspx para esta:
<%@ Page Language="C#" AutoEventWireup="true"
CodeBehind="WebForm1.aspx.cs"
Inherits="UsingSessionState.WebForm1" %>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
102 | lição 4

<body>
<form id="form1" runat="server">
<div>
<asp:Label ID="Label1" runat="server"
Text="Insira seu nome:" /><br />
<asp:TextBox ID="TextBox1" runat="server" />
<br /><br />
<asp:Button ID="Button1" runat="server"
Text="Submit" onclick="Button1_Click" />
</div>
</form>
</body>
</html>
4. Clique com o botão direito do mouse na janela de código e selecione Exibir Código
no menu de atalho para alternar para o arquivo code-behind (WebForm1.aspx.cs).
Substitua o código desse arquivo pelo seguinte:
using System;
namespace UsingSessionState
{
public partial class WebForm1
: System.Web.UI.Page
{
protected void Page_Load
(object sender, EventArgs e)
{
if (Session["Name"] != null)
Response.Redirect("WebForm2.aspx");
}

protected void Button1_Click


(object sender, EventArgs e)
{
Session.Add("Name", TextBox1.Text);
Response.Redirect("WebForm2.aspx");
}
}
}
5. Adicione um novo formulário da Web (WebForm2.aspx) ao projeto. Altere a marcação
da página para a seguinte:
<%@ Page Language="C#" AutoEventWireup="true"
CodeBehind="WebForm2.aspx.cs"
Inherits="UsingSessionState.WebForm2" %>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
Noções básicas sobre aplicativos Web | 103

</head>
<body>
<form id="form1" runat="server">
<div>
<asp:Label ID="Label1" runat="server" /> <br />
<asp:Button ID="Button1" runat="server"
Text="Limpar sessão"
onclick="Button1_Click" />
</div>
</form>
</body>
</html>
6. Altere o código no arquivo code-behind (WebForm2.aspx.cs) para o formulário, para
que ele seja lido como:
using System;
namespace UsingSessionState
{
public partial class WebForm2
: System.Web.UI.Page
{
protected void Page_Load(
object sender, EventArgs e)
{
if (Session["Nome"] != null)
Label1.Text = String.Format(
"Bem-vindo, {0}", Session["Nome"]);
else
Response.Redirect("WebForm1.aspx");
}
protected void Button1_Click(
object sender, EventArgs e)
{
Session.Remove("Nome");
Response.Redirect("WebForm1.aspx");
}
}
}
7. Selecione Depurar > Iniciar Depuração (ou pressione F5). A página WebForm1.aspx
será aberta em um navegador da Web, conforme mostra a figura 4-8. Digite um nome
e clique no botão Enviar. Esta página armazena o nome digitado no estado de sessão.
104 | lição 4

Figura 4-8
Esta página armazena o
nome digitado no estado de
sessão

PRONTO PARA
CERTIFICAÇÃO
Você compreende 8. Em seguida, você será transferido para WebForm2.aspx, conforme mostra a figura 4-9.
as noções básicas de WebForm2.aspx recupera o nome de usuário do estado de sessão. Na mesma janela
desenvolvimento de do navegador (de modo que você esteja dentro da mesma sessão), tente acessar
aplicativos Web ASP. WebForm1.aspx. Observe que, enquanto a sessão contiver uma entrada para o nome,
NET? você será redirecionado para WebForm2.aspx. Pressione o botão Limpar Sessão. Isso
4.2 limpará a sessão e o transferirá para WebForm1.aspx.

Figura 4-9
Esta página recupera o nome
exibido do estado de sessão

■ Noções básicas sobre a hospedagem Web do IIS

A hospedagem Web envolve a definição de um servidor Web com configurações e


O RESULTADO arquivos de código corretos para que os usuários remotos possam acessar um aplicativo
Web com êxito.

Os aplicativos ASP.NET devem ser implantados em um servidor Web do IIS (Serviços


de Informações da Internet). O IIS é parte integrante dos sistemas operacionais Windows
Server e fornece funcionalidade de hospedagem de sites.
A implantação de um aplicativo ASP.NET é simples, pois o ASP.NET fornece a
implantação de xcopy. Isso significa que tudo o que você precisa fazer para implantar um
site do ASP.NET em um servidor Web é copiar os arquivos para os locais corretos. Você
pode copiar esses arquivos usando o comando xcopy do Windows ou um aplicativo FTP.

Alguns aplicativos Web complexos podem exigir a implantação de arquivos DLL no


TOME NOTA
* GAC (cache de assembly global). Nessas situações, você pode precisar realmente criar
um pacote do Windows Installer para a implantação, em vez de usar xcopy ou FTP.
Noções básicas sobre aplicativos Web | 105

Noções básicas sobre os Serviços de Informações da Internet


Os Serviços de Informações da Internet (IIS) são um servidor Web para hospedar
aplicativos Web no sistema operacional Windows. Um servidor IIS usa os conceitos
de sites, aplicativos e diretórios virtuais.

Você pode usar o IIS para hospedar vários sites e compartilhar informações com
usuários pela Internet ou por uma intranet. O IIS usa uma relação hierárquica entre sites,
aplicativos e diretórios virtuais como um bloco de construção básico para a hospedagem
de conteúdo online.
O IIS pode ser administrado usando a ferramenta Gerenciador do IIS, que faz parte
do sistema operacional Windows. A ferramenta Gerenciador do IIS, como mostra a
figura 4-10, fornece uma interface gráfica do usuário para configurar sites, aplicativos e
diretórios virtuais. A captura de tela na figura 4-10 é de um computador que executa o
Windows 7. A interface do usuário do Gerenciador do IIS é diferente no Windows XP.

Figura 4-10
Interface do Gerenciador
de Serviços de Informações
da Internet (IIS) em um
computador que executa
o Windows 7

Criando diretórios virtuais e sites


Um site é um contêiner de aplicativos e diretórios virtuais. Um diretório virtual é um
alias mapeado para um diretório físico no servidor Web.

Um site é um contêiner de aplicativos e diretórios virtuais que podem ser acessados


usando um endereço da Web. Por exemplo, a URL www.northwind.com pode apontar
para um site com vários diretórios virtuais, como ordens e contas, cada um dos quais pode
ser acessado em combinação com o endereço do site — por exemplo, através de www.
northwind.com/orders e www.northwind.com/account.
Um servidor Web nunca expõe o real endereço físico e o local dos arquivos para o mundo
externo. Em vez disso, ele usa um sistema de aliases que mapeiam para os diretórios
106 | lição 4

físicos. Esses aliases também são chamados de diretórios virtuais. Os diretórios virtuais
tornam-se parte da URL, como demonstrado no exemplo anterior. Quando o IIS recebe
uma solicitação para uma URL desse tipo, ele mapeia o diretório virtual para o local físico
dos arquivos. O exercício a seguir mostra como criar um diretório virtual.

CRIAR UM DIRETÓRIO VIRTUAL

PREPARE-SE. Para criar um diretório virtual usando o gerenciador do IIS, execute as


etapas a seguir:
1. Abra o Gerenciador do IIS. Para abrir o Gerenciador do IIS no Windows 7, digite IIS no
menu Iniciar e clique no atalho Gerenciador de Serviços de Informações da Internet
(IIS). Para acessar o Gerenciador do IIS no Windows XP, vá para Iniciar > Executar,
digite “inetmgr” e clique no botão OK.
2. Expanda os nós no painel esquerdo (consulte a figura 4-10) e selecione o nó Site Padrão.
3. Clique com o botão direito do mouse no nó Site Padrão e selecione a opção Adicionar
Diretório Virtual no menu de atalho. No Windows XP, o comando será Novo >
Diretório Virtual. Neste ponto, um Assistente para Criação de Diretório Virtual será
exibido na tela.
4. Na caixa de diálogo Adicionar Diretório Virtual, forneça um alias e o caminho físico,
como mostra a figura 4-11 e, em seguida, clique em OK.
Figura 4-11
Caixa de diálogo Adicionar
Diretório Virtual

Implantação de aplicativos Web


A implantação de sites simples é feita copiando os arquivos para o local correto. Para
instalar um site complexo, você talvez precise usar o Windows Installer.

Há duas maneiras principais de implantar arquivos em um site:


• Usando xcopy ou FTP: vários aplicativos Web e serviços Web simplesmente exigem
que os arquivos sejam copiados para o servidor Web. Esses sites e serviços não
PRONTO PARA
exigem quaisquer ações especiais, como reiniciar os serviços do IIS, registrar os
CERTIFICAÇÃO componentes no Registro do Windows e assim por diante. A implantação com xcopy
Você compreende ou FTP é ideal nesses cenários.
as noções básicas de • Usando o Windows Installer: o Windows Installer pode executar uma série de
hospedagem Web com ações personalizadas durante o processo de implantação. Portanto, ele pode ser usado
o servidor Web do IIS? para implantar sites complexos que necessitam da criação automática de diretórios
4.3
virtuais, reinício de serviços, registro de componentes etc.
Noções básicas sobre aplicativos Web | 107

■ Noções básicas sobre o desenvolvimento de serviços Web

Um serviço Web é um componente de software que pode ser acessado em uma rede
O RESULTADO
usando protocolos de rede padrão, por exemplo, HTTP. Os serviços Web são descritos
usando WSDL (Web Services Description Language).

Os serviços Web permitem interagir com objetos de programação localizados em


computadores remotos. Os serviços Web são especiais, pois toda a comunicação entre os
servidores de serviços Web e seus clientes ocorre através de mensagens XML transmitidas
pelo protocolo HTTP.
Com o uso dessas tecnologias padrão, os objetos remotos podem ser publicados e
consumidos por sistemas incompatíveis. Por exemplo, um objeto remoto escrito em C# e
publicado como um serviço Web em um servidor Web do Windows pode ser processado
pelo código Java executado em uma máquina Linux.
Antes de discutirmos em detalhes como criar e consumir serviços Web, vamos nos
familiarizarmos com duas tecnologias importantes que tornam possíveis os serviços Web:
• SOAP (Simple Object Access Protocol)
• Linguagem WSDL

Introdução ao SOAP
O SOAP é o protocolo para a troca de informações estruturadas em uma
comunicação de serviço Web entre dois computadores remotos.

SOAP é o protocolo que define como computadores remotos trocam mensagens como
parte de uma comunicação de serviço Web. SOAP depende de XML como seu formato
de mensagem e usa HTTP para transmissão de mensagens. O uso do SOAP para a
comunicação traz dois benefícios importantes. Primeiro, como as mensagens de serviços
Web são formatadas como XML, elas são mais fáceis de serem compreendidas por
sistemas incompatíveis. Em segundo lugar, como essas mensagens são transmitidas pelo
HTTP penetrante, elas normalmente podem atingir qualquer máquina na Internet sem
serem bloqueadas por firewalls.
Este é um pacote SOAP típico enviado de um cliente para um serviço Web:
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope
xmlns:xsi=http://www.w3.org/2001/XMLSchema–instance
xmlns:xsd=http://www.w3.org/2001/XMLSchema
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<ToLower xmlns="http://northwindtraders.com">
<inputString>SEQUÊNCIA DE AMOSTRA</inputString>
</ToLower>
</soap:Body>
</soap:Envelope>
108 | lição 4

Observe, no exemplo, alguns elementos óbvios desse pacote SOAP:


• O pacote consiste em um envelope que contém um corpo e, cada um deles
é identificado com uma marca XML específica.
• O corpo consiste no nome do método a ser invocado. Nesse pacote SOAP, o nome
do método é ToLower e usa um único parâmetro denominado inputString e um valor
específico.
Veja a seguir o pacote de resposta do servidor:
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<ToLowerResponse
xmlns="http://northwindtraders.com">
<ToLowerResult>sequência de amostra</ToLowerResult>
</ToLowerResponse>
</soap:Body>
</soap:Envelope>
No pacote de resposta, o elemento XML ToLowerResponse é o resultado da invocação do
método no servidor.

Introdução ao WSDL
WSDL é uma linguagem baseada em XML para descrever serviços Web.

*
TOME NOTA WSDL significa Web Services Description Language e fornece um padrão pelo qual um
Um serviço Web pode serviço Web pode informar ao seu cliente qual tipo de mensagens ele aceitará e quais
existir sem um arquivo resultados serão retornados. Um arquivo WSDL funciona como a interface pública de um
WSDL, mas você deve serviço Web e inclui as seguintes informações:
conhecer a mensagem • Os tipos de dados que ele pode processar
SOAP exata de entrada
• Os métodos que ele expõe
esperada pelo serviço
Web antes de usar esse • As URLs através das quais esses métodos podem ser acessados
serviço.
Criando serviços Web
Nesta seção, você aprenderá a criar e publicar um serviço Web.

Nesta seção, você aprenderá a criar um serviço Web simples denominado TextWebService
que expõe dois métodos, ToLower e ToUpper. Esses métodos converter uma determinada
cadeia de caracteres em letras minúsculas e maiúsculas, respectivamente. Embora este
exemplo seja simples, ele abrange todos os aspectos de criação de um serviço Web que
pode envolver uma lógica de processamento mais complexa.
Noções básicas sobre aplicativos Web | 109

CRIAR UM SERVIÇO WEB

PREPARE-SE. Para criar um serviço Web, execute as seguintes ações:


1. Adicione um novo projeto com base no modelo Aplicativo Web Vazio do ASP.NET para
a solução Lesson04. Nomeie o projeto como TextWebService, conforme mostra a
figura 4-12.
Figura 4-12
Selecione o modelo
Aplicativo Web Vazio
do ASP.NET

2. Selecione Projeto > Adicionar Novo Item no menu de atalho. Selecione o modelo
Serviço Web, conforme mostra a figura 4-13. Nomeie o serviço Web como
TextWebService.asmx.
Figura 4-13
Selecione o modelo Serviço
Web

3. Altere o código padrão para a classe TextWebService no arquivo TextWebService.asmx.


cs, conforme mostrado abaixo:
[WebService(Namespace = "http://northwindtraders.com/")]
[WebServiceBinding(ConformsTo
= WsiProfiles.BasicProfile1_1)]
public class TextWebService:
System.Web.Services.WebService
110 | lição 4

{
[WebMethod]
public string ToUpper(string inputString)
{
return inputString.ToUpper();
}
[WebMethod]
public string ToLower(string inputString)
{
return inputString.ToLower();
}
}
4. Selecione Depurar > Compilar TextWebService para compilar o projeto e garantir que
TOME NOTA
* não há erros. O serviço Web agora está pronto para uso.
Você pode usar o nome No código acima, há alguns itens importantes a serem observados. Primeiro, observe que
de domínio da sua cada classe exposta como um serviço Web XML precisa ter um atributo WebService. O
empresa como parte atributo WebService tem uma propriedade Namespace que assume como padrão https://
do namespace para tempuri.org/. Embora não haja problemas ter esse valor no momento do desenvolvimento,
distinguir seus serviços o valor do namespace deverá ser alterado antes que o serviço Web seja publicado. Na
Web dos serviços verdade, cada serviço Web individual deve ter um namespace exclusivo para que os
publicados por outras aplicativos cliente o diferencie dos outros serviços Web.
empresas.
Cada método exposto do serviço Web também precisa ter um atributo WebMethod. Os
métodos marcados com atributos WebMethod também são conhecidos como métodos
Web. Os dois métodos utilizados neste exercício convertem uma determinada cadeia de
caracteres em letras maiúsculas e minúsculas, respectivamente.
Para testar um serviço Web simples, como o TextWebService criado acima, você precisa
apenas de um navegador da Web. Você poderá selecionar os métodos a serem invocados,
passar parâmetros e examinar os valores de retorno dentro do navegador, conforme
mostrado no exercício a seguir.
TESTAR UM SERVIÇO WEB

PREPARE-SE. Para testar um serviço Web, execute estas tarefas:


1. Abra o projeto TextWebService criado no exercício anterior. Selecione Depurar >
Iniciar Depuração. Um navegador será iniciado exibindo a página de teste do serviço
Web, como mostra a figura 4-14.
Figura 4-14
Página de teste de serviço
Web
Noções básicas sobre aplicativos Web | 111

2. Na página de teste, clique no link Descrição do Serviço. Dessa forma, você será capaz
de exibir a linguagem WSDL para esse serviço Web. Clique no botão Voltar para
retornar à página de teste.
3. Observe que todos os métodos Web aparecem como links na página de teste. Para
invocar um método Web específico, clique no respectivo link. Depois isso, você verá
uma página para testar o método Web selecionado, como mostra a figura 4-15.

Figura 4-15
Página de teste de
método Web

4. Cada página de teste do método Web mostra SOAP e outras mensagens


compreendidos pelo serviço Web. Ela também contém um formulário que permite
que você insira parâmetros de método e teste o método Web. Digite uma cadeia
de caracteres de entrada de teste e clique no botão Invocar. Você deverá ver um
resultado na página seguinte, como mostra a figura 4-16.
Figura 4-16
Valor de retorno do teste
de serviço Web

5. Teste os dois métodos. Quando terminar, feche o navegador da Web.


112 | lição 4

Conforme demonstrado no exercício, quando você clicar no botão Invocar, a página de


teste construirá os pacotes SOAP apropriados do serviço Web para o processo e, em
seguida, exibirá os resultados retornados do serviço Web.

Consumindo serviços Web


Nesta seção, você aprenderá como acessar serviços Web de um aplicativo cliente.

Anteriormente na lição, você aprendeu a invocar um serviço Web da página de teste


de serviço Web. Nesta seção, você aprenderá a chamar um serviço Web de forma
programática de dentro de um aplicativo cliente ASP.NET.

ACESSAR UM SERVIÇO WEB DE UM APLICATIVO CLIENTE

PREPARE-SE. Para acessar um serviço Web de um aplicativo cliente, execute as seguintes


etapas:
1. Adicione um novo projeto à solução Lesson04 com base no modelo Aplicativo Web do
ASP.NET. Nomeie o projeto como TextWebServiceClient.
2. Clique com o botão direito do mouse no nome do projeto na janela do Gerenciador
de Soluções e, em seguida, selecione a opção Adicionar Referência da Web do menu
de atalho. Na caixa de diálogo Adicionar Referência da Web, digite a URL do serviço
criado no exercício anterior e pressione Enter. (Você também pode copiar a URL da
barra de endereços do navegador.) Essa ação carrega a lista de operações disponíveis
no serviço Web, como mostra a figura 4-17.

Figura 4-17
Caixa de diálogo Adicionar
Referência da Web

3. Na caixa de diálogo Adicionar Referência da Web, altere o nome da referência da Web


para textWebService e clique no botão Adicionar Referência. Isso adicionará uma
Referência da Web ao projeto, como mostra a figura 4-18.
Noções básicas sobre aplicativos Web | 113

Figura 4-18
Nó Web References para
o projeto

4. Altere o código de Default.aspx para este:


<%@ Page Title="Home Page" Language="C#"
AutoEventWireup="true"
CodeBehind="Default.aspx.cs"
Inherits="TextWebServiceClient._Default" %>
<html>
<head><title>Cliente TextWebService
</title></head>
<body>
<form runat="server">
<h2>Formulário de teste de TextWebService</h2>
<p>
<asp:TextBox ID="TextBox1"
runat="server"
Text="enter text" />
<br />
<asp:Button ID="Button1"
runat="server"
Text="Invocar métodos de serviço"
onclick="Button1_Click" />
</p>
<p>
<strong>Resultados:</strong><br />
Método ToLower:
<asp:Label ID="toLowerLabel"
runat="server"
Text="Label" ForeColor="Green" />
<br />
114 | lição 4

Método ToUpper:
<asp:Label ID="toUpperLabel"
runat="server"
Text="Label" ForeColor="Green" />
</p>
</form>
</body>
</html>
5. Abra o modo de exibição de Design para default. aspx e clique duas vezes no controle
Button. Isso adicionará o código para o manipulador de eventos Click. Modifique o
TOME NOTA
* código como mostrado abaixo:
Ao invocar um método protected void Button1_Click(
de serviço Web, você object sender, EventArgs e)
pode optar por usar
um método síncrono {
ou assíncrono. Você var webService =
pode querer usar o new textWebService.TextWebService();
método assíncrono para toLowerLabel.Text =
aumentar a capacidade
de resposta do webService.ToLower(TextBox1.Text);
aplicativo cliente. toUpperLabel.Text =
webService.ToUpper(TextBox1.Text);
}
6. Selecione Depurar > Iniciar Depuração para executar o aplicativo Web. Digite um texto
de exemplo e, em seguida, clique no botão Invocar Métodos de Serviço. Você verá os
resultados em TextWebService, como mostra a figura 4-19.

Figura 4-19
Valor de retorno do serviço
Web

No exercício acima, quando você adicionar uma referência da Web, o Visual Studio criará
um proxy local que representa o serviço remoto. O proxy simplifica a comunicação com o
serviço Web, aceitando mensagens, encaminhando-as para o serviço Web e retornando os
resultados do serviço Web.
Você pode usar esse proxy facilmente para criar objetos do serviço Web e invocar
métodos. Como resultado, o trabalho com objetos remotos é semelhante ao trabalho com
objetos locais.
Noções básicas sobre aplicativos Web | 115

Quando você cria uma referência da Web, o Visual Studio lê o arquivo WSDL apropriado
PRONTO PARA
CERTIFICAÇÃO para determinar quais classes e métodos estão disponíveis no servidor remoto. Quando
Você compreende você chama um método em um objeto remoto, o .NET Framework converte sua chamada
as noções básicas de em mensagens SOAP e transmite-as sem qualquer intervenção da sua parte.
desenvolvimento de
serviços Web?
4.4
RESUMO DE HABILIDADES

Nesta lição, você aprendeu que:


• Uma página da Web é um documento disponibilizado na World Wide Web (WWW)
e pode ser exibido por um navegador da Web.
• Linguagem HTML é a linguagem usada por servidores e navegadores Web para
descrever uma página da Web.
• As folhas de estilos em cascata (CSS) permitem que você armazene o estilo e as
informações de formatação separadas do código HTML. Essa separação facilita
a atualização de um site. O Visual Studio inclui ferramentas para compilar e visualizar
suas folhas de estilos.
• JavaScript é uma linguagem de scripts do lado do cliente executada dentro de um
navegador da Web para ajudar a criar páginas da Web muito mais interativas do que
é possível apenas com HTML.
• As técnicas de gerenciamento de estado do lado do cliente, como cadeias de
caracteres de consulta, cookies, campos ocultos e ViewState, usam HTML e os
recursos dos navegadores da Web para armazenar informações de estado em
computadores cliente.
• As técnicas de gerenciamento de estado do lado do servidor, como estado de sessão
e estado do aplicativo, usam recursos do servidor para gerenciamento de estado.
• Os Serviços de Informações da Internet (IIS) são um servidor Web para hospedar
aplicativos Web no sistema operacional Windows. Um servidor IIS usa os conceitos
de sites, aplicativos e diretórios virtuais.
• Os serviços Web permitem invocar objetos remotos usando tecnologias padrão,
como XML e HTTP.
• SOAP é o protocolo que define como os computadores remotos trocam mensagens
como parte de uma comunicação de serviços Web. O SOAP depende de XML para
seu formato de mensagem e usa HTTP para a transmissão de mensagens.
• A linguagem WSDL fornece um padrão através do qual um serviço Web pode
informar ao seu cliente quais tipos de mensagens serão aceitos e quais resultados
serão retornados.

■ Avaliação de conhecimento
Preencha as lacunas
Complete as frases a seguir com a(s) palavra(s) correta(s) nas lacunas fornecidas.
1. Na marca de ancoragem HTML (<a>), o atributo _________ especifica a URL
de destino.
2. Você pode colocar o código CSS em um arquivo separado e vinculá-lo a uma página
da Web por meio do uso do elemento HTML _________.
3. O código JavaScript em uma página da Web é executado no _________.
116 | lição 4

4. Você pode usar um elemento _________ para exibir uma mensagem específica para
os usuários quando seu navegador não está executando JavaScript.
5. Você pode desabilitar ViewState no nível de página, definindo o atributo _________
da diretiva Page para false na página ASP.NET.
6. O estado _________ é usado para armazenar dados que são usados globalmente por
meio de um aplicativo, em oposição ao estado _________, que armazena dados para
uma sessão de usuário.
7. Um aplicativo Web é acessado usando um nome _________ em vez de um nome de
pasta física.
8. Você deve marcar as classes com o atributo _________ para expô-las como um
serviço Web.
9. De todos os métodos em uma classe de serviço Web, somente as marcadas com os
atributos _________ são expostas como métodos de serviço Web.
10. SOAP depende de _________ como seu formato de mensagem e usa _________ para
a transmissão de mensagens.

Múltipla escolha
Assinale a letra que corresponde à melhor resposta.
1. Escreva o código a seguir para a sua página da Web:
<html>
<head>
<title>Página de exemplo</title>
<style type="text/css">
div
{
font-family: Verdana;
font-size: 9pt;
}
</style>
</head>
<body>
<div style=
"font-weight: bold; font-size: 12pt;">
Página de texto</div>
</body>
</html>
Qual seria o estilo do texto exibido como parte do elemento <div>?
a. Font family: Verdana; font weight: bold; font size: 12pt
b. Font family: Verdana; font weight: bold; font size: 9pt
c. Font family: Verdana; font size: 12pt
d. Font family: Verdana; font size: 9pt
Noções básicas sobre aplicativos Web | 117

2. Você está desenvolvendo um site de mapeamento que permite aos usuários


explorarem interativamente mapas usando ações como, por exemplo, panorâmica
e zoom. Você quer que o site seja ágil e acessível nos navegadores da Web mais
modernos. No entanto, você não quer que os usuários tenham que instalar plug-ins
adicionais para usar seu site. Qual das seguintes tecnologias você deve usar para
exibir mapas?
a. HTML
b. Tecnologia de programação do lado do servidor, como ASP.NET
c. Adobe Flash
d. JavaScript
3. Sua página ASP.NET contém uma variável de nível de página do tipo Cliente. Você
quer preservar o valor dessa variável entre postbacks de página, mas você não precisa
desta variável em nenhuma outra página no aplicativo. Qual das seguintes técnicas de
gerenciamento de estado é a melhor maneira de conseguir isso?
a. Cadeias de caracteres de consulta
b. Cookies
c. ViewState
d. Sessão
4. Você está desenvolvendo um aplicativo Web para um banco online. Sua aplicação
permite que os usuários acessem suas informações de conta e transações de dentro de
um navegador da Web. Quando um usuário fizer logon no aplicativo Web, você quer
mostrar o saldo de conta e o nome de usuário em todas as páginas do aplicativo até
que o usuário faça logoff. Você também quer que este aplicativo esteja protegido de
usuários mal-intencionados. Qual das seguintes técnicas de gerenciamento de estado
você deve usar?
a. Cookies
b. ViewState
c. ViewState com criptografia
d. Sessão
5. Você está desenvolvendo um formulário da Web para exibir informações sobre
o tempo. Quando um usuário solicita o formulário da Web, o formulário precisa
executar uma inicialização para alterar sua aparência e atribuir valores para alguns
controles. Onde você deve colocar o código?
a. No manipulador de evento PreInit da classe Page
b. No manipulador de evento Init da classe Page
c. No manipulador de evento Load da classe Page
d. No manipulador de evento PreRender da classe Page
6. Você quer exibir valores das expressões C# em uma página ASP.NET. Qual dos
seguintes tipos de blocos de código você deve usar para delimitar a expressão?
a. <script runat=“server”>…</script>
b. <script>…</script>
c. <%= … %>
d. <form>…</form>
7. Você desenvolveu um aplicativo de quadro de horários que será usado por todos os
funcionários na sua empresa. Você usou o ASP.NET para desenvolver este aplicativo
e o implantou no servidor Web da empresa. O que todos os funcionários da empresa
devem instalar em seus computadores antes de poderem acessar o aplicativo de
quadro de horários?
a. .NET Framework redistribuível
b. Software Development Kit do .NET Framework
c. Visual Studio
d. Um navegador da Web
118 | lição 4

8. Seu aplicativo cliente chama um serviço Web que realiza cálculos complexos
e demorados. Um usuário reclama que, enquanto os resultados estão sendo
retornados, a interface de usuário congela momentaneamente. Qual abordagem você
deve tomar para resolver este problema?
a. Você deve instalar um processador melhor no servidor Web.
b. Você deve instalar um processador melhor no computador cliente.
c. Você deve atualizar para uma conexão de Internet mais rápida.
d. Você deve usar chamadas assíncronas para chamar o serviço Web.
9. Você criou um serviço Web ASP.NET que converte uma moeda em outra. Um dos
métodos no seu serviço Web é definido com o código a seguir:
public double Convert(double amount,
string from, string to)
{
// código para fazer conversão de moeda
}
Os usuários do serviço Web reportam que podem definir uma referência para o
serviço Web, mas o método Convert não está disponível para eles. Qual poderia ser o
problema?
a. O arquivo .asmx para o serviço Web não está disponível no servidor Web.
b. A classe de serviço Web não está marcada com o atributo WebService.
c. O método Convert não está marcado com o atributo WebMethod.
d. Os serviços Web somente podem expor métodos que retornam valores de texto.
10. Você está trabalhando em dois projetos do Visual Studio. O primeiro projeto é um
serviço Web que retorna um objeto DataSet que pertence ao namespace System.Data.
O segundo projeto acessa o serviço Web criado pelo primeiro projeto. Qual projeto
neste cenário requer uma referência ao namespace System.Data?
a. O projeto de serviço Web
b. O projeto de cliente que acessa o serviço Web
c. O projeto de cliente e o projeto de serviço Web
d. Nem o projeto de cliente nem o projeto de serviço Web

■ Avaliação da competência
Cenário 4-1: Usando JavaScript e HTML
Você está desenvolvendo uma página da Web que fornece uma interface de usuário
responsiva. Você decide exibir uma imagem na página. Quando o usuário move o mouse
sobre a imagem, a imagem original é substituída por uma nova. Em seguida, quando
o mouse é movido fora da área de imagem, a imagem original é exibida novamente. Você
espera conseguir isso usando código JavaScript e HTML do lado do cliente. Como você
criaria uma página da Web que funciona como descrito aqui?

Cenário 4-2: Usando cadeias de caracteres de consulta


Você está desenvolvendo uma parte de um site que permite que os usuários insiram seus
nomes e endereços de email para assinar um boletim informativo por email. Sua solução
consiste em duas páginas da Web. A primeira página coleta o nome de usuário e o endereço
de email e, em seguida, transfere o controle para uma segunda página. A segunda página
aceita o nome e o endereço de email como parâmetros de cadeia de caracteres de consulta e
exibe uma mensagem de confirmação para o usuário. Você precisa escrever um código para
essas duas páginas. Qual código você escreverá para atender a esse requisito?
Noções básicas sobre aplicativos Web | 119

■ Avaliação de proficiência
Cenário 4-3: Chamando um serviço Web de maneira assíncrona
A classe proxy gerada pelo Visual Studio para um serviço Web inclui métodos para
chamar o serviço Web de maneira síncrona e assíncrona. Por padrão, o aplicativo usa
o método síncrono. Se você preferir a invocação assíncrona, precisará chamar a versão
assíncrona do método. As versões assíncronas não esperam o serviço Web retornar
uma resposta e usam um mecanismo de retorno de chamada para obter uma resposta
quando ela estiver pronta. A invocação assíncrona de um serviço Web pode ajudar os
aplicativos cliente a serem mais dinâmicos. Se você quiser chamar o método ToLower
do TextWebService criado anteriormente de uma maneira assíncrona. Qual código você
escreveria para invocar de maneira assíncrona um serviço Web?

Cenário 4-4: Usar o estado de sessão


Você está desenvolvendo uma parte de um site que permite que os usuários insiram seus
nomes e endereços de email para assinar um boletim informativo por email. Sua solução
consiste em duas páginas da Web. A primeira página coleta o nome de usuário e endereço
de email, adiciona-os ao estado de sessão e transfere o controle para uma segunda página.
A segunda página recupera o nome e o endereço de email do estado de sessão e exibe
uma mensagem de confirmação. Você precisa escrever um código para essas duas páginas.
Qual código você escreverá para atender a esse requisito?
120 | lição 5

5 LIÇÃO
Noções básicas
sobre aplicativos da
área de trabalho
M AT R I Z D E H A B I L I D A D E S D A L I Ç Ã O

Habilidades/Conceitos Objetivo do exame MTA Número do objetivo


do exame MTA
Noções básicas sobre objetos Entender os aplicativos de 5,1
formulários do Windows.
Noções básicas sobre Entender aplicativos de console. 5,2
valores e referências
Noções básicas sobre Entender os serviços Windows. 5,3
encapsulamento

P R I N C I PA I S T E R M O S
parâmetros de linha de comando instalador Aplicativos do Windows Forms
aplicativo de console Aplicativos MDI (interface de serviço Windows
delegados vários documentos)
eventos herança visual

Você é um desenvolvedor de software de uma organização de grande porte. Você


precisa desenvolver um aplicativo que seja bem integrado com a área de trabalho
Windows do usuário e forneça uma interface do usuário semelhante à dos aplicativos
da área de trabalho populares na plataforma Windows. O aplicativo precisa ser
funcional esteja ele conectado ou desconectado da rede. O aplicativo também deve
ser capaz de se comunicar com dispositivos, como impressoras e scanners portáteis.

■ Noções básicas sobre os aplicativos do Windows Forms

Os aplicativos do Windows Forms são aplicativos cliente inteligentes compostos de um


ou mais formulários que exibem uma interface visual para o usuário. Esses aplicativos
O RESULTADO se integram bem com o sistema operacional, usam dispositivos conectados e podem
funcionar conectados ou não com a Internet.

120
Noções básicas sobre aplicativos da área de trabalho | 121

Como projetar um Windows Form

Um Windows Form é uma superfície visual capaz de exibir vários controles, inclusive
caixas de texto, botões e menus. O Visual Studio fornece o Windows Forms Designer
do tipo “arrastar e soltar” que você pode usar para criar facilmente seus aplicativos.

TOME NOTA
* Para projetar Windows Forms, você deve primeiro decidir quais controles deseja colocar no
Um controle é um formulário. O Windows Forms fornece uma grande coleção de controles comuns que você
elemento distinto de pode usar prontamente para criar uma excelente interface de usuário. Se a funcionalidade
interface do usuário que você está procurando ainda não estiver disponível como um controle comum, você
que aceita a entrada do poderá criar um controle personalizado ou adquirir um controle de outro fornecedor.
usuário ou exibe uma
saída para o usuário. Você pode usar a funcionalidade fornecida pelo Windows Forms Designer do Visual
Studio para inserir e organizar rapidamente os controles de acordo com os seus requisitos.
O Visual Studio fornece acesso fácil aos controles disponíveis através de sua caixa de
ferramentas, como mostra a figura 5-1.

Figura 5-1
Caixa de ferramentas do
Visual Studio

Um formulário e seus componentes geralmente respondem às ações do usuário, como


pressionamentos de teclas ou movimento do mouse. Essas ações são chamadas de eventos.
Grande parte do código que você escreve como desenvolvedor do Windows Forms
é direcionada para capturar esses eventos e manipulá-los criando uma resposta adequada.
Por exemplo, no exercício a seguir, você criará um Windows Form que exibe o valor de
data selecionado pelo usuário.

CRIAR UM WINDOWS FORM


PREPARE-SE. Inicie o Microsoft Visual Studio. Em seguida, execute as seguintes ações:
1. Crie um novo projeto com base no modelo Aplicativo Windows Forms, como mostra
a figura 5-2. Nomeie o projeto como WindowsFormsDesign.
122 | lição 5

Figura 5-2
Caixa de diálogo Novo Projeto do Visual Studio

2. O projeto de aplicativo Windows Form será carregado com um formulário padrão


(Form1.cs) aberto no modo de exibição de Designer. O modo de exibição de Designer
permite que você trabalhe visualmente com o formulário. Por exemplo, você pode
organizar os controles na superfície do formulário e definir suas propriedades.
Os controles disponíveis podem ser acessados a partir da janela Caixa de Ferramentas.
Se ainda não conseguir ver essa janela, selecione Exibir > Caixa de Ferramentas
para exibi-la. Em seguida, na Caixa de Ferramentas, arraste e solte um controle
DateTimePicker e um controle Label na superfície do Designer e organize os controles
como mostra a figura 5-3.

Figura 5-3
Windows Form com um
controle DateTimePicker
e um controle Label

3. No modo de exibição de Designer, selecione o controle Label e, usando a janela


Propriedades, defina a propriedade Text para uma cadeia de caracteres vazia.
4. Além disso, no modo de exibição de Designer, clique duas vezes no controle
DateTimePicker. Essa ação anexa o manipulador de eventos padrão para o evento
ValueChanged do controle DateTimePicker e alterna o modo de exibição de Designer
para Código. Em seguida, altere o código padrão do manipulador de eventos desta
forma:
private void dateTimePicker1_ValueChanged
(object sender, EventArgs e)
{
label1.Text =
dateTimePicker1.Value.ToLongDateString();
}
Noções básicas sobre aplicativos da área de trabalho | 123

5. Selecione Depurar > Iniciar Depuração (ou pressione F5) para executar o projeto.
TOME NOTA
* Na interface de usuário, selecione uma nova data e verifique se a data selecionada
Neste exercício,
é exibida no controle Label.
usamos os nomes de
controle padrão. Em Neste exercício, observe que, quando o formulário é exibido inicialmente, o controle
formulários complexos Label é definido como uma cadeia de caracteres vazia. Depois disso, quando você alterar
com mais controles, a seleção de data, manipulando o controle DateTimePicker, o valor de data selecionada
é recomendável será definido como o texto do controle Label.
atribuir nomes mais
significativos aos
Noções básicas sobre o modelo de evento do Windows Form
controles.
A manipulação de eventos desempenha um papel fundamental na programação
baseada em interface do usuário; através da manipulação de eventos, você pode
responder a vários eventos disparados como resultado de ações do usuário e,
portanto, criar programas interativos. O modelo de evento do Windows Forms
usa delegados do .NET Framework para vincular os eventos aos seus respectivos
manipuladores de eventos.
Nos aplicativos do Windows Forms, cada formulário e controle expõe um conjunto
predefinido de eventos. Quando um evento ocorre, o código no manipulador de evento
associado é invocado. Por exemplo, no exercício anterior, quando você clicou duas vezes
no controle DateTimePicker para adicionar código ao manipulador de eventos, o Visual
Studio gerou o código a seguir para anexar o manipulador de eventos ao evento:
this.dateTimePicker1.ValueChanged +=
new System.EventHandler(
TOME NOTA
* this.dateTimePicker1_ValueChanged);
Um delegado pode ser
Aqui, ValueChanged é o evento do controle DateTimePicker que queremos capturar.
vinculado a qualquer
Portanto, uma nova instância do delegado do tipo EventHandler foi criada, e o método
método cuja assinatura
dateTimePicker1_ValueChanged foi passado para o manipulador de eventos. O método
corresponda à do
dateTimePicker1_ValueChanged é o método no qual você escreve realmente o código de
manipulador de
manipulação de eventos.
eventos.
Esse código é gerado automaticamente pelo Visual Studio Designer. Você encontrará esse
código no arquivo code-behind do designer (Form1.Designer.cs), dentro de uma região de
código intitulada código gerado pelo Windows Form Designer.
Uma outra observação é que a sintaxe para adicionar um delegado usa o operador +=. Isso
porque o .NET Framework oferece suporte a delegados multicast em que um delegado
pode ser vinculado a mais de um método, permitindo, assim, notificações um-para-muitos
quando um evento é disparado.

Usando a herança visual

A herança visual permite que você reutilize funcionalidades e layouts existentes para
Windows Forms.

Um dos princípios fundamentais da programação orientada a objeto é a herança. Quando


uma classe é herdada de uma classe base, ela deriva sua funcionalidade base da classe
base. Naturalmente, você poderá estender a classe derivada a qualquer momento para
fornecer funcionalidade adicional e torná-la mais útil.
124 | lição 5

Um Windows Form, na sua essência, é apenas uma outra classe; portanto, a herança
também se aplica a ele. Entretanto, quando a herança é aplicada a um Windows Form,
ele herda todas as características visuais de um formulário, como tamanho, cor e qualquer
controle localizado no formulário. Você também pode manipular visualmente qualquer
uma das propriedades herdadas da classe base. Portanto, a herança do Windows Forms
é muitas vezes chamada de herança visual. No exercício a seguir, você criará um
Windows Form através da herança visual de um formulário existente.

CRIAR UM WINDOWS FORM USANDO A HERANÇA VISUAL


PREPARE-SE. Inicie o Microsoft Visual Studio e abra o projeto de aplicativo Windows
existente denominado WindowsFormsDesign. Em seguida, execute estas etapas:
1. Abra Form1.designer.cs e altere os modificadores de acesso para os controles de
label1 e dateTimePicker1 de private para protected, como mostrado:
protected System.Windows.Forms.Label label1;
protected System.Windows.Forms.DateTimePicker
dateTimePicker1;

2. Selecione Projeto > Adicionar formulário do Windows... para adicionar um novo


Windows Form com base no modelo Formulário Herdado. Você pode procurar esse
modelo rapidamente digitando seu nome na caixa de pesquisa, conforme mostra
a figura 5-4. Nomeie o formulário herdado como InheritedForm.cs. (Observe que o
modelo Formulário Herdado não está disponível nas edições do Visual Studio Express.
Se você estiver usando uma edição Express, basta criar um Windows Form normal
denominado InheritedForm.cs e prosseguir na etapa 4.)

Figura 5-4
Modelo Formulário Herdado
Noções básicas sobre aplicativos da área de trabalho | 125

3. Clique no botão Adicionar. Em seguida, na caixa de diálogo Selecionador de Herança,


selecione Form1 no namespace WindowsFormsDesign, conforme mostra a figura 5-5,
e clique no botão OK.

Figura 5-5
Caixa de diálogo
Selecionador de Herança

4. Selecione o Modo de Exibição de Código para o InheritedForm; você verá que a


classe InheritedForm é herdada de Form1, como mostrado abaixo. Se não tiver usado
o modelo Formulário Herdado na etapa 2, você precisará modificar manualmente
o código para adicionar o código para a herança (mostrado em negrito):
public partial class InheritedForm
: WindowsFormsDesign.Form1
{
public InheritedForm()
{
InitializeComponent();
}
}

5. No modo de exibição de Designer de InheritedForm, defina a propriedade Text para


Inherited Form.
6. Além disso, no modo de exibição de Designer, clique duas vezes em InheritedForm.
Essa ação anexa um manipulador de eventos para o evento Load do formulário e
alterna o modo exibição de Designer para Código. No modo de exibição de Código,
altere o código padrão para o manipulador de eventos desta forma:
private void InheritedForm_Load(
object sender, EventArgs e)
{
label1.Text =
dateTimePicker1.Value.ToLongDateString();
}
126 | lição 5

7. Abra Program.cs e modifique o método Main, conforme mostrado a seguir, para


garantir que InheritedForm seja iniciado quando você executar o aplicativo:
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application
.SetCompatibleTextRenderingDefault(false);
Application.Run(new InheritedForm());
}

8. Selecione Depurar > Iniciar Depuração (ou pressione F5) para executar o projeto.
Quando InheritedForm for carregado, a data selecionada no momento será exibida no
controle Label. Isso, ao contrário, não ocorre no Form1 criado anteriormente, em que
o controle Label estava inicialmente vazio.
O formulário InheritedForm demonstra que você pode obter toda a funcionalidade de
Form1 simplesmente herdando o formulário. Ao alterar o modificador de acesso dos
controles de membro, label1 e dateTimePicker1, do Form1 de private para protected,
você será capaz de acessá-lo de dentro do formulário herdado. Este exercício também
demonstra como você pode estender a funcionalidade do formulário base em um
formulário herdado.

Noções básicas sobre aplicativos de interface MDI

Os aplicativos MDI (interface de vários documentos) são aqueles em que várias


janelas filho residem sob uma única janela pai.

Os aplicativos MDI permitem que várias janelas compartilhem o mesmo menu


e a mesma barra de ferramentas do aplicativo. Os aplicativos MDI geralmente têm
um menu denominado Janela que permite aos usuários gerenciar várias janelas filho,
oferecendo recursos, como alternância entre janelas filho e organização de janelas filho.
Por exemplo, a figura 5-6 mostra o Microsoft Excel 2010 no modo MDI.

Figura 5-6
Microsoft Excel 2010 como
um aplicativo MDI
Noções básicas sobre aplicativos da área de trabalho | 127

Os aplicativos MDI contrastam com os aplicativos SDI (single-document interface) em


que cada janela contém seu próprio menu e sua barra de ferramentas. Os aplicativos SDI
dependem do sistema operacional para fornecer a funcionalidade de gerenciamento de
TOME NOTA
* janelas. Por exemplo, no Windows, você pode alternar entre várias janelas usando a barra
Talvez seja complicado de tarefas do Windows.
implementar o suporte
para vários monitores Há muito debate entre os designers de interface de usuário em relação a qual interface
nos aplicativos MDI, de aplicativo funciona melhor. De um modo geral, o SDI é considerado mais adequado
pois a janela pai precisa para usuários novatos, ao passo que o MDI é considerado mais conveniente para usuários
abranger todos os avançados. Muitos aplicativos populares, como o Microsoft Word e o Microsoft Excel,
monitores do usuário. dão suporte a SDI e MDI. O Word e o Excel são instalados, por padrão, como aplicativos
SDI, mas eles oferecem aos usuários uma opção que permite alternar entre MDI e SDI.
Por exemplo, no Word 2010 e no Excel 2010, você pode alternar para o modo MDI,
desmarcando a opção “Mostrar todas as janelas na Barra de Tarefas” no menu Opções.

CRIAR UM APLICATIVO MDI


PREPARE-SE. Inicie o Microsoft Visual Studio e crie um novo projeto de aplicativo
Windows Forms denominado MDIApplication. Em seguida, execute estas etapas:
1. Selecione a janela Propriedades para Form1 e defina a propriedade Text para MDI
Application e a propriedade IsMdiContainer para True.
2. Selecione o controle MenuStrip da Caixa de Ferramentas e adicione-o ao formulário.
Adicione um item de menu de nível superior &Janela e em seguida, adicione &Nova
Janela e &Organizar no próximo nível. No menu Organizar, adicione três opções —
&Em Cascata, &Horizontal e &Vertical — conforme mostra a figura 5-7.

Figura 5-7
Adicionando opções
de menu
128 | lição 5

O sinal & na frente de um caractere no texto de um menu não é exibido como está;
nesse caso, ele define o caractere como a tecla de atalho do menu. Por exemplo,
*
TOME NOTA o menu &Janela pode ser invocado pressionando Alt+W. As teclas de acesso não
estarão evidentes até que o usuário pressione a tecla Alt. Uma configuração no sistema
operacional Windows controla se as teclas de acesso estarão sempre visíveis.

3. Para o controle MenuStrip, defina sua propriedade MdiWindowListItem para o nome


do menu Janela (windowToolStripMenuItem, por padrão).
4. No Gerenciador de soluções, clique com o botão direito do mouse no projeto e selecione
Adicionar > Windows Form. Adicione um novo Windows Form com o nome ChildForm.
5. Clique duas vezes no formulário filho e adicione o código a seguir para manipular o
evento Load:
private void ChildForm_Load(
object sender, EventArgs e)
{
Text = DateTime.Now.ToString();
}

6. No formulário pai, clique duas vezes no item de menu Janela > Nova Janela e adicione
o seguinte manipulador de eventos para o evento Click:
private void newWindowToolStripMenuItem_Click(
object sender, EventArgs e)
{
ChildForm child = new ChildForm();
child.MdiParent = this;
child.Show();
}

7. No formulário pai, clique duas vezes em Janela > Organizar, Janela > Em Cascata,
Janela > Organizar, Janela > Horizontal e Janela > Organizar, Janela > Vertical,
respectivamente, e adicione os seguintes manipuladores de eventos para seus eventos
Click:
private void cascadeToolStripMenuItem_Click(
object sender, EventArgs e)
{
LayoutMdi(MdiLayout.Cascade);
}
private void horizontalToolStripMenuItem_Click(
object sender, EventArgs e)
{
LayoutMdi(MdiLayout.TileHorizontal);
}
private void verticalToolStripMenuItem_Click(
object sender, EventArgs e)
{
LayoutMdi(MdiLayout.TileVertical);
}
Noções básicas sobre aplicativos da área de trabalho | 129

8. Selecione Depurar > Iniciar Depuração (ou pressione F5) para executar o projeto.
Selecione Janela > Nova Janela para criar várias novas janelas filho. Alterne entre as
janelas filho. Observe que há apenas uma única instância do aplicativo na barra de
tarefas do Windows. Agora, use as opções no menu Janela > Organizar para organizar
as janelas filho. Por exemplo, um aplicativo com três janelas filho pode ser semelhante
à imagem na figura 5-8 quando as janelas filho são organizadas horizontalmente.
Figura 5-8
Um aplicativo MDI com três
janelas filho organizadas
horizontalmente

Vamos rever alguns dos métodos e propriedades importantes usados nesse exercício.
Primeiro, para o formulário pai, a propriedade IsMdiContainer é definida para true.
Essa propriedade indica que a forma é um contêiner de vários formulários filho MDI.
Correspondentemente, para cada formulário filho, você define a propriedade MdiParent
para especificar o formulário do contêiner pai.
Em seguida, a propriedade MdiWindowListItem de MenuStrip é usada para indicar
qual item de menu será usado para exibir a lista de janelas filho MDI. Quando essa
propriedade for definida, o item de menu listará todas as janelas filho e também permitirá
que você alterne entre as janelas filho. Como resultado do código no método ChildForm_
PRONTO PARA
CERTIFICAÇÃO
Load, a barra de título de cada formulário exibirá a data e a hora do instante em que
Você compreende o formulário foi carregado.
como desenvolver Finalmente, o método LayoutMdi é usado pelos itens do menu Janela para organizar as
aplicativos do Windows janelas filho. O método aceita um parâmetro do tipo enumeração MdiLayout. O valor da
Forms?
enumeração determina se as janelas filho precisam estar lado a lado horizontalmente ou
5,1
verticalmente, em cascata ou exibidas como ícones.

■ Noções básicas sobre aplicativos de console

Os aplicativos de console não têm uma interface gráfica de usuário e usam uma janela de
O RESULTADO
console no modo texto para interagir com o usuário. Esses aplicativos são mais adequados
a tarefas que não exigem interface do usuário ou exigem uma interface mínima.

TOME NOTA
* Como o nome sugere, um aplicativo de console é executado a partir da janela de console.
Para habilitar a A entrada para esse aplicativo pode ser fornecida usando os parâmetros de linha de
leitura ou a gravação comando, ou o aplicativo pode ler os caracteres da janela de console interativamente.
no console a partir Da mesma forma, a saída de um aplicativo de console também é gravada na janela de
de um aplicativo comando. Você pode habilitar a leitura ou a gravação no console, criando um aplicativo
Windows Forms, por meio do modelo Aplicativo de Console no Visual Studio.
defina o Tipo de Saída
Você também pode usar aplicativos de console para criar comandos que possam ser
do projeto como
executados na linha de comando. Por exemplo, você pode aproveitar os pipes e os filtros
Aplicativo de Console
fornecidos pelo sistema operacional para passar a saída de um comando como entrada
nas Propriedades do
para outro comando, criando, assim, comandos mais avançados através da combinação
projeto.
de comandos simples.
130 | lição 5

Trabalhando com parâmetros de linha de comando

Nesta seção, você aprenderá a aceitar os parâmetros de linha de comando de um


aplicativo de console.

O exercício a seguir cria um aplicativo de console simples que aceita o nome de um arquivo
de texto como um argumento de linha de comando e exibe o conteúdo desse arquivo.

CRIAR UM APLICATIVO DE CONSOLE


PREPARE-SE. Inicie o Microsoft Visual Studio. Em seguida, execute estas etapas:
1. Crie um novo projeto com base no modelo Aplicativo de Console, como mostra a
­figura 5-9. Nomeie o projeto como DisplayFile.

Figura 5-9
Modelo Aplicativo
de Console

2. No Program.cs, modifique o código dentro do método Main como mostrado abaixo:


static void Main(string[] args)
{
if (args.Length < 1)
return;
string[] lines = File.ReadAllLines(args[0]);
foreach (string item in lines)
{
Console.WriteLine(item);
}
}

3. Adicione a diretiva using a seguir ao arquivo:


using System.IO;
Noções básicas sobre aplicativos da área de trabalho | 131

4. Selecione Compilar > Compilar Solução (ou pressione F6) para compilar o projeto.
5. Crie um arquivo de texto usando o Visual Studio ou o Bloco de Notas, digite um texto
de exemplo e salve o arquivo como Sample.txt na mesma pasta do arquivo executável.
(Por padrão, o arquivo executável é criado na pasta bin\debug sob a pasta do projeto.)
6. Abra um prompt de comando e navegue até o caminho do arquivo EXE do projeto.
Execute o seguinte comando:
DisplayFile sample.txt
PRONTO PARA
CERTIFICAÇÃO Esse comando deve exibir o conteúdo do arquivo de texto na janela de comando.
Você compreende 7. Se preferir, você também poderá passar o argumento de linha de comando do Visual
como desenvolver
Studio usando a janela Propriedades do projeto, como mostra a figura 5-10. Para exibir
aplicativos de console?
a janela Propriedades do projeto, selecione a opção de menu Projeto > Propriedades
5,2
de DisplayFile.
Figura 5-10
Definindo opções de início
na janela Propriedades
do projeto

■ Noções básicas sobre os serviços Windows

Um serviço Windows é um aplicativo executado em segundo plano e que não tem uma
O RESULTADO interface de usuário.

A natureza dos serviços Windows torna-os ideais para criar programas de execução
longa que funcionam em segundo plano e não permitem qualquer interação direta do
usuário. Um serviço Windows pode ser iniciado, pausado, reiniciado e parado. Um
serviço Windows também pode ser configurado para começar automaticamente quando
o computador é iniciado.
Alguns exemplos de serviços Windows incluem um servidor Web que escuta as
solicitações de entrada e envia uma resposta ou o spooler de impressão de um sistema
operacional que fornece serviços de impressão para os programas aplicativos.
132 | lição 5

Os serviços desempenham um papel importante na arquitetura de aplicativos empresariais.


Por exemplo, você pode ter um serviço que escuta ordens recebidas e inicia um fluxo de
trabalho de processamento de ordens sempre que uma ordem é recebida.

Como um serviço Windows é capaz de ser executado em segundo plano, ele não
precisa que um usuário esteja conectado para funcionar. Os serviços Windows serão
TOME NOTA
* executados em sua própria sessão do Windows no contexto de segurança especificado.
Ainda assim, dependendo das permissões necessárias, você poderá especificar uma
conta de usuário na qual o serviço será executado.

Como criar um serviço Windows

Para criar um serviço Windows no Visual Studio, use o modelo Aplicativo de Serviço
Windows. Observe que um serviço Windows deve ser instalado antes de poder
TOME NOTA
* ser utilizado.
O Visual Studio
Todos os serviços Windows devem derivar da classe ServiceBase. Essa classe base
Express Edition não
fornece a estrutura básica e funcionalidade para criar um serviço Windows. Você pode
fornece modelos
substituir os métodos de classe base OnStart, OnStop, OnPause e OnContinue para
para a criação de
adicionar sua própria lógica personalizada que é executada em resposta às alterações nos
projetos de serviço
estados de serviço.
Windows. Portanto,
você precisará de uma O exercício a seguir demonstra como criar um serviço Windows simples que grava
versão não express mensagens no log de eventos do aplicativo. Os logs de eventos fazem parte do Windows
do Visual Studio para usado por tarefas do sistema operacional e aplicativos em execução em segundo plano
realizar os exercícios para registro de erro ou outras mensagens informativas. Por padrão, o Windows define
que usam projetos de três logs de eventos: Sistema, Aplicativo e Segurança. Os aplicativos geralmente usam
serviço Windows. o log de eventos Aplicativo para registrar sua mensagem. O utilitário Visualizador de
Eventos do Windows pode ser usado para exibir as mensagens em logs de eventos.

CRIAR UM SERVIÇO WINDOWS


PREPARE-SE. Inicie o Microsoft Visual Studio. Em seguida, execute estas etapas:
1. Crie um novo projeto com base no modelo Serviço Windows. Nomeie o projeto como
FirstService, conforme mostra a figura 5-11.
Figura 5-11
Selecionando o modelo de
projeto Serviço Windows
Noções básicas sobre aplicativos da área de trabalho | 133

2. Selecione a janela Propriedades para Service1 e defina as propriedades (Name)


e ServiceName para “FirstService”.
3. No Gerenciador de Soluções, renomeie o arquivo Service1.cs como FirstService.
cs. Abra Program.cs e verifique se as referências a Service1 foram alteradas para
FirstService.
4. Selecione a janela Propriedades para o serviço e defina as propriedades
CanPauseAndContinue e CanShutdown para True.
5. Abra o designer para FirstService e adicione um componente EventLog a ele a partir da
Caixa de Ferramentas. O componente EventLog permite que você se conecte aos logs
de eventos.
6. Exiba o código para FirstService e modifique o construtor, como mostrado abaixo.
Nesse código, crie primeiro uma origem de evento com o nome FirstService. Essa
origem de evento é usada para distinguir as mensagens geradas por um aplicativo
específico de todas as outras mensagens de um log de eventos. Em seguida, defina
a propriedade Source do componente de log de eventos para o nome da origem do
evento. A propriedade Log do componente de log de eventos, eventLog1, é usada para
especificar o log de eventos usado para registrar as mensagens:
public FirstService()
{
InitializeComponent();
if (!EventLog.SourceExists(“FirstService”))
{
EventLog.CreateEventSource(
“FirstService”, “Application”);
}
eventLog1.Source = “FirstService”;
eventLog1.Log = “Application”;
}

7. Adicione o código a seguir aos métodos de alteração de estado de serviço para


definir seu comportamento. O método WriteEntry do componente de log de eventos,
eventLog1, é usado para gravar uma mensagem em um log de eventos. Como
parte do método, você pode especificar o tipo de mensagem. Por exemplo, sua
mensagem pode ser uma mensagem de erro, uma mensagem de aviso ou apenas uma
informação:
protected override void OnStart(string[] args)
{
eventLog1.WriteEntry(
“Iniciando o serviço”,
EventLogEntryType.Information, 1001);
}

protected override void OnStop()


{
eventLog1.WriteEntry(
“Parando o serviço”,
EventLogEntryType.Information, 1001);
}
134 | lição 5

protected override void OnPause()


{
eventLog1.WriteEntry(
“Pausando o serviço”,
EventLogEntryType.Information, 1001);
}

protected override void OnContinue()


{
eventLog1.WriteEntry(
“Continuando o serviço”,
EventLogEntryType.Information, 1001);
}

protected override void OnShutdown()


{
eventLog1.WriteEntry(
“Desligando o serviço”,
EventLogEntryType.Information, 1001);
}

8. Selecione Compilar > Compilar Solução (ou pressione F6) para compilar o projeto.
Aqui, o código de FirstService substitui os métodos OnStart, OnStop, OnPause,
OnContinue e OnShutdown para gravar mensagens no log de eventos. No entanto, nem
todos os serviços precisarão substituir esses métodos. A substituição desses métodos por
um serviço dependerá do valor das propriedades CanPauseAndContinue e CanShutdown
de serviço Windows.
O método WriteEntry do log de eventos conduz a mensagem para ser gravada no log,
o tipo de entrada de log de eventos (informações, erro, aviso etc.) e um eventId, que é
uma id específica do aplicativo usada para identificar o evento.
O serviço Windows FirstService agora está pronto, mas antes de ele ser usado, ele deve ser
instalado no banco de dados do serviço Windows. Isso é feito adicionando um instalador
de serviço ao projeto de serviço Windows. O exercício a seguir mostra como fazer isso.

ADICIONAR UM INSTALADOR A UM SERVIÇO WINDOWS


PREPARE-SE. Inicie o Microsoft Visual Studio. Em seguida, execute estas etapas:
1. Abra o projeto FirstService criado no exercício anterior. Clique com o botão direito
do mouse na superfície do Designer de FirstService.cs e selecione a opção Adicionar
Instalador no menu de contexto.
2. Essa ação adiciona um novo arquivo ProjectInstaller.cs ao projeto. Abra o Designer
para ProjectInstaller.cs. Você verá que os dois componentes foram adicionados ao
Designer, como mostra a figura 5-12.

Figura 5-12
Modo de exibição
de Designer para
ProjectInstaller.cs
Noções básicas sobre aplicativos da área de trabalho | 135

3. Acesse as propriedades para o serviceProcessInstaller1component e altere a


propriedade Account para LocalService.
4. Em seguida, acesse as propriedades de serviceInstaller1component. Altere a
propriedade DisplayName para FirstService e a propriedade Description para
“A simple test service”. Observe que, por padrão, o valor da propriedade StartType
é definido como Manual.
5. Selecione Compilar > Compilar Solução (ou pressione F6) para compilar o projeto.
O serviço Windows agora está pronto para ser instalado.

A propriedade StartType da classe ServiceInstaller indica como e quando um serviço


é iniciado. A propriedade StartType pode ter um de três valores possíveis. O valor Manual,
*
TOME NOTA que também é o valor padrão, indica que você precisa iniciar o serviço manualmente.
O valor Automatic indica que o serviço será iniciado automaticamente quando o Windows
for iniciado. O valor Disabled indica que o serviço não pode ser iniciado.

Quando você adiciona um instalador a um projeto de serviço Windows, as classes


TOME NOTA
* ServiceProcessInstaller e ServiceInstaller são adicionadas ao projeto. A classe
Para minimizar os ServiceProcessInstaller executa tarefas de instalação que são comuns a todos os serviços
riscos de segurança, Windows de um aplicativo. Isso inclui a definição da conta de logon para o serviço
evite usar a conta Windows. A classe ServiceInstaller, por outro lado, executa as tarefas de instalação
LocalSystem para que são específicas de um único serviço Windows, como a definição de ServiceName
executar um serviço e StartType.
Windows, a menos
que o serviço exija A propriedade Account da classe ServiceProcessInstaller especifica o tipo de conta em que
privilégios de os serviços são executados. A propriedade Account é do tipo enumeração ServiceAccount
segurança mais altos onde os valores possíveis são LocalService, LocalSystem, NetworkService e User.
para funcionar. O valor LocalSystem especifica uma conta altamente privilegiada, ao passo que a conta
LocalService atua como um usuário sem privilégios.
Um arquivo executável que tem o código das classes do instalador do serviço pode ser
instalado por meio da ferramenta do Instalador da linha de comando (installutil.exe).
O exercício a seguir mostra como instalar um aplicativo de serviço Windows no banco de
dados de serviço Windows.

INSTALAR UM SERVIÇO WINDOWS


PREPARE-SE. Para instalar um serviço Windows, execute as seguintes etapas:
1. Execute o prompt de comando do Visual Studio como administrador. Para acessar
o prompt de comando, vá para Iniciar > Todos os Programas > Visual Studio >
Ferramentas do Visual Studio e escolha Prompt de Comando Visual Studio. Para
executar um programa como administrador no Windows, clique com o botão direito
do mouse no atalho do programa e selecione a opção Executar como administrador
no menu de atalho.
2. Altere o diretório para o diretório de saída do projeto FirstService. Nesse diretório está
localizado o arquivo executável.
136 | lição 5

3. Emita o seguinte comando; os resultados devem ser semelhantes aos mostrados na


figura 5-13:
installutil FirstService.exe

Figura 5-13
Usando installutil.exe

TOME NOTA
*
A instalação de um
serviço Windows 4. O serviço Windows FirstService agora está instalado.
requer acesso ao O aplicativo de serviço Windows agora é armazenado no banco de dados de serviço
Registro do Windows. Windows. Anteriormente, quando você adicionou um ServiceInstaller para FirstService,
Portanto, certifique- você definiu a propriedade StartType do componente serviceInstaller1 para Manual. Como
se de instalar resultado, você precisará iniciar o serviço manualmente quando necessário. O exercício
installUtil.exe como a seguir demonstra como iniciar, pausar, continuar e parar um serviço Windows.
administrador.

TRABALHAR COM UM SERVIÇO WINDOWS


PREPARE-SE. Inicie a janela Gerenciamento do Computador clicando com o botão
TOME NOTA
* direito do mouse em Meu Computador e selecionando Gerenciar no menu de atalho.
Para desinstalar um Em seguida, execute estas etapas:
serviço Windows, use
1. Na janela Gerenciamento do Computador, expanda a seção Serviços e Aplicativos
InstallUtil.exe com a
e selecione Serviços. Uma lista de todos os serviços instalados no computador deve
opção -u.
ser exibida, como mostra a figura 5-14.
Figura 5-14
A seção Serviços permite
que você trabalhe com os
serviços instalados
Noções básicas sobre aplicativos da área de trabalho | 137

2. Selecione o serviço FirstService e clique no hiperlink Iniciar hiperlink, como mostra


a figura 5-14. Você deverá ver uma caixa de diálogo indicando o andamento, como
mostra a figura 5-15. Quando o serviço for iniciado, seu status mudará para Iniciado.

Figura 5-15
Mensagem de controle de
serviço no início de um
serviço

3. Expanda o nó Visualizador de Eventos e selecione o log Aplicativo Windows. Você


deverá ver a mensagem “Starting the Service” de FirstService, como mostra a
figura 5-16.

Figura 5-16
O log Aplicativo Windows

4. Retorne à lista de serviços e tente pausar, continuar ou parar FirstService. Examine


PRONTO PARA
CERTIFICAÇÃO o log de eventos de Aplicativo para verificar se as mensagens adequadas estão sendo
Você compreende exibidas.
como desenvolver Nos últimos exercícios, você viu como criar, instalar e usar um serviço Windows. Você
serviços Windows?
também aprendeu como adicionar mensagens ao log de eventos do aplicativo Windows
5,3
programaticamente.

RESUMO DE HABILIDADES

Nesta lição, você aprendeu que:


• U
 m Windows Form é uma superfície visual que pode exibir uma variedade de
controles, como caixas de texto, botões e menus. O Visual Studio fornece o Windows
Forms Designer do tipo “arrastar e soltar” que você pode usar para criar aplicativos.
• N
 o Windows Forms, cada formulário e controle expõe um conjunto predefinido de
eventos. Quando um evento ocorre, o código no manipulador de evento associado
é invocado. O modelo de evento do Windows Forms usa delegados do .NET
Framework para vincular os eventos aos seus respectivos manipuladores de eventos.
138 | lição 5

• A
 herança visual permite que você reutilize funcionalidades e layouts existentes para
Windows Forms.
• O
 s aplicativos MDI (interface de vários documentos) são aqueles em que residem
várias janelas filho sob uma única janela pai.
• O
 s aplicativos de console não têm uma interface gráfica de usuário e usam uma
janela de console no modo texto para interagir com o usuário. Esses aplicativos
são mais adequados a tarefas que não exigem interface do usuário ou exigem uma
interface mínima.
• O
 s serviços Windows são ideais para criar aplicativos de longa execução que operam
em segundo plano e não têm interface de usuário.
• Você pode criar serviços Windows usando o modelo Serviços Windows do Visual Studio.
• A
 ntes de um serviço Windows ser usado, ele deve ser instalado no Registro do
Windows. Para isso, adicione o componente Installer ao aplicativo de serviço
Windows. Isso permitirá que você instale o serviço Windows usando uma ferramenta
de instalação, como InstallUtil.exe.

■ Avaliação de conhecimento
Preencha as lacunas
Complete as sentenças a seguir com a(s) palavra(s) correta(s) nas lacunas fornecidas.
1. Use a propriedade _________ da classe ServiceInstaller para especificar um breve
comentário que explique a finalidade do serviço.
2. A propriedade _________ da classe _________ indica o tipo de conta em que um
serviço Windows será executado.
3. A propriedade _________ da classe EventLog é usada para especificar o nome do
aplicativo a ser usado para gravar em um log de eventos.
4. _________ permite que você reutilize a funcionalidade e o layout existente para o
Windows Forms.
5. Os aplicativos _________ são aqueles em que várias janelas filho residem sob uma
única janela pai.
6. Um(a) _________ é ideal para criar aplicativos de longa execução que operam em
segundo plano e não têm interface de usuário.
7. _________ não tem interface gráfica do usuário e usam uma janela de console em
modo de texto para interagir com o usuário.
8. Os aplicativos _________ fornecem sua própria funcionalidade de gerenciamento de
janela, ao passo que os aplicativos _________ dependem do sistema operacional para
o gerenciamento de janela.
9. Um delegado pode ser vinculado a qualquer método cuja assinatura corresponda à
do(a) _________.
10. O(A) _________ pode ser vinculado(a) a mais de um método, permitindo
notificações um-para-muitos quando um evento é disparado
Noções básicas sobre aplicativos da área de trabalho | 139

Múltipla escolha
Assinale a letra que corresponde à melhor resposta.
1. Você precisa projetar um serviço Windows que não pode ser pausado. Qual das
opções a seguir o ajudará a realizar essa tarefa?
a. Defina a propriedade CanPauseAndContinue do serviço Windows como False.
b. Defina a propriedade CanPauseAndContinue do serviço Windows como True.
c. Defina a propriedade CanStart do serviço Windows como True, mas defina
a propriedade CanShutdown como False.
d. Não substitua os métodos OnPause e OnContinue no serviço Windows.
2. Você desenvolveu um serviço Windows. Você precisa instalar esse serviço para
instalar sua funcionalidade. Qual das opções a seguir você deve escolher para realizar
essa tarefa?
a. Usar o Gerenciador de Servidores do Visual Studio.
b. Usar o nó Serviços na janela Gerenciamento do Computador.
c. Usar o InstallUtil.exe.
d. Usar o gacutil.exe.
3. Você desenvolveu um serviço Windows. Esse serviço precisa ser executado como um
usuário sem privilégios para minimizar qualquer possível risco de segurança. Qual
das seguintes contas você deve usar para executar este serviço Windows?
a. LocalSystem
b. NetworkService
c. LocalService
d. User (em que a propriedade UserName é definida para um membro da função
administrador)
4. Você está projetando um aplicativo de serviço Windows que contém apenas um
serviço Windows. Você deseja que esse serviço seja iniciado automaticamente quando
o computador for reiniciado. Qual das classes a seguir você deve usar para especificar
essa configuração?
a. ServiceBase
b. ServiceInstaller
c. ServiceProcessInstaller
d. ServiceController
5. Você precisa alterar a exibição e o comportamento de um Windows Form para que
ele possa conter várias janelas filho. O que você deve fazer?
a. Definir a propriedade IsMdiContainer do formulário como True.
b. Definir a propriedade MdiParent para todas as janelas filho.
c. Definir a propriedade MdiChild do formulário.
d. Definir a propriedade IsMdiChild do formulário.
6. Você está desenvolvendo um Windows Form que responde aos eventos do mouse.
Quando o mouse se move, você precisa invocar o método Form1_HandleMouse.
Qualquer código escrito não deve afetar nenhum código de manipulação de eventos
existente. Qual instrução você deve usar para anexar o manipulador de eventos ao
evento?
a.
this.MouseDown = new MouseEventHandler
(Form1_HandleMouse);
b.
this.MouseMove = new MouseEventHandler
(Form1_HandleMouse);
140 | lição 5

c.
this.MouseDown += new MouseEventHandler
(Form1_HandleMouse);
d.
this.MouseMove += new MouseEventHandler
(Form1_HandleMouse);
7. Você está desenvolvendo um Windows Form com uma interface MDI. Você precisa
escrever um código que organize as janelas filho verticalmente dentro da região do
cliente do formulário pai MDI. Qual das seguintes instruções você deve usar?
a.
LayoutMdi(MdiLayout.TileVertical);
b.
LayoutMdi(MdiLayout.Cascade);
c.
MdiLayout(LayoutMdi.TileVertical);
d.
MdiLayout(LayoutMdi.Cascade);
8. Você está desenvolvendo um aplicativo que será executado na linha de comando. Qual
dos métodos a seguir você deve usar para gerar a saída para a linha de comando?
a. Console.Read
b. Console.Write
c. File.Read
d. File.Write
9. Você deseja desenvolver um aplicativo que exiba uma superfície visual capaz de
mostrar uma variedade de controles, como caixas de texto, botões e menus. O
aplicativo também deve permitir várias janelas filho sob uma única janela pai. Quais
dos seguintes tipos de aplicativo você deve desenvolver?
a. Aplicativo de console
b. Aplicativo de serviço Windows
c. Aplicativo SDI (Single document interface)
d. Aplicativo MDI (interface de vários documentos)
10. Você está estendendo um aplicativo Windows existente. Você deseja criar um novo
formulário que derive suas características visuais (incluindo tamanho, cor e alguns
controles) de um formulário criado anteriormente. Qual técnica você deve usar para
criar o novo formulário?
a. Herança visual
b. Encapsulamento visual
c. Abstração visual
d. Polimorfismo visual

■ Avaliação da competência
Cenário 5-1: Usando a herança visual
Você precisa criar um Windows Form semelhante ao criado no exercício VisualInheritance.
No entanto, desta vez, o requisito é que a cor de fundo desse formulário coincida com
a cor selecionada no momento na área de trabalho do usuário. Como você desenvolveria
esse formulário?

Cenário 5-2: manipulando o evento MouseDown


Você está desenvolvendo um jogo no qual os usuários podem acertar um alvo em um
Windows Form com o mouse. Você precisa desenvolver um formulário experimental que
exiba as coordenadas X e Y do local clicado pelo usuário na barra de título do formulário.
Como você deve fazer isso?
Noções básicas sobre aplicativos da área de trabalho | 141

■ Avaliação de proficiência
Cenário 5-3: trabalhando com a entrada do console
Você está desenvolvendo um programa que manipula texto. Você precisa escrever um
aplicativo de console que aceite texto do usuário e converta-o em letras maiúsculas.
Qual código você precisa escrever para atender a esse requisito?

Cenário 5-4: usando o utilitário Net (net.exe)


O utilitário de linha de comando net.exe vem instalado com o Windows. Ele permite
que você execute vários comandos de rede, inclusive o controle de serviços Windows.
Você deseja usar net.exe para trabalhar com o serviço Windows FirstService criado
anteriormente. Quais etapas você deve executar para pausar, parar e iniciar um serviço
Windows usando o utilitário net.exe?
6 LIÇÃO
Noções básicas sobre
bancos de dados
M AT R I Z D E H A B I L I D A D E S D A L I Ç Ã O

Habilidades/Conceitos Objetivo do exame MTA Número do objetivo


do exame MTA
Noções básicas sobre objetos Compreender os sistemas de 6,1
gerenciamento de banco de
dados relacional

Noções básicas sobre valores Compreender os métodos de consulta 6,2


e referências de banco de dados.
Noções básicas sobre Compreender os métodos de conexão 6,3
encapsulamento de banco de dados.

P R I N C I PA I S T E R M O S
atributo primeira forma normal (1NF) design de banco de dados
DataSet arquivos simples relacional

banco de dados dependência funcional segunda forma normal (2NF)

integridade do banco de dados normalização procedimento armazenado

sistema de gerenciamento de procedimentos armazenados linguagem SQL


banco de dados (DBMs) parametrizados terceira forma normal (3NF)
aplicativos desconectados chave primária linguagem XML
elemento instruções de processamento
diagramas de relacionamento banco de dados relacional
entre entidades (ERDs)

Você é um desenvolvedor de software da Northwind Corporation. Como parte do seu


trabalho, você interage com e processa dados sobre clientes, produtos, fornecedores e
pedidos. Seu trabalho envolve a interação com bancos de dados relacionais, como o
Microsoft SQL Server. No entanto, você também trabalha com dados armazenados em
outros formatos, como arquivos simples, arquivos XML e dados na memória. Para ser
eficaz no trabalho, você precisa saber como se conectar a várias fontes de dados e como
recuperar e atualizar dados nessas fontes.

■ Noções básicas sobre conceitos de banco de dados relacional


Um banco de dados relacional é uma coleção de dados inter-relacionados baseados no
O RESULTADO
modelo relacional desenvolvido por E. F. Codd. Esse modelo define entidades de dados
distintas, seus atributos e relações entre as entidades.
142
Noções básicas sobre bancos de dados | 143

Noções básicas sobre bancos de dados

Um banco de dados é uma coleção organizada de dados inter-relacionados que são


gerenciados como uma única unidade.

Um banco de dados permite que você armazene, mantenha e recupere dados importantes.
Se um banco de dados for projetado corretamente, ele poderá ser usado por vários
aplicativos e usuários. Um sistema de gerenciamento de banco de dados (DBMS),
por outro lado, é um software que organiza bancos de dados e fornece recursos, como
armazenamento, acesso a dados, segurança, backup etc. Microsoft SQL Server, Microsoft
Access, Oracle e MySql são exemplos de DBMSs populares.
Os sistemas de gerenciamento de banco de dados podem ser implementados com base
em modelos diferentes. Dentre esses modelos, o modelo relacional é o mais popular. No
modelo relacional, os dados são organizados em tabelas, que podem ter várias linhas.
Os DBMSs com base em modelos relacionais são chamados de DBMSs relacionais
(RDBMSs). SQL Server, Access, Oracle e MySql são todos RDBMSs.
Outros sistemas de gerenciamento de banco de dados são baseados em modelos diferentes.
Por exemplo, os DBMSs (ODBMSs) de objeto baseiam-se no modelo de objeto, em que
os dados são armazenados como uma coleção de objetos. Nesta lição, no entanto, vamos
nos concentrar exclusivamente nos bancos de dados relacionais mais populares.
Os DBMSs relacionais usam a linguagem SQL para recuperar e manipular dados.
Os sistemas de gerenciamento de banco de dados relacional mais populares fornecem
algum suporte para a versão padronizada do SQL, permitindo, assim, que você use suas
habilidades através de diferentes sistemas de banco de dados relacional.

Noções básicas sobre conceitos de banco de dados relacional

Um banco de dados relacional organiza dados em tabelas bidimensionais, que


consistem em colunas e linhas.

Um banco de dados relacional organiza as informações em tabelas. Uma tabela


é uma lista de linhas e colunas que é conceitualmente semelhante a uma planilha do
Microsoft Excel. Uma linha também é chamada de registro ou tupla, e uma coluna às
vezes é chamada de campo. A coluna ou o campo especifica o tipo de dados que serão
armazenados para cada registro da tabela. Por exemplo, os pedidos dos clientes podem
ser armazenados em uma tabela Pedidos em que cada linha representa um único pedido.
Nesta tabela, as colunas, como OrderDate, podem ser usadas para especificar que um
valor válido é do tipo de dados correto. Uma tabela Pedidos de exemplo é mostrada
na figura 6-1.

Figura 6-1
Uma tabela Orders em um
banco de dados relacional
144 | lição 6

Noções básicas sobre design de banco de dados relacional

Um design de banco de dados relacional é o processo que determina a estrutura de


banco de dados relacional adequada para atender aos requisitos comerciais.

Os dados de uma organização são um dos seus ativos mais importantes. Assim, quando
você projetar um banco de dados, um dos princípios orientadores será assegurar a
integridade do banco de dados. Integridade significa que os dados no banco de dados são
sempre exatos e consistentes.
O processo de design de um banco de dados consiste nas seguintes etapas:
1. Desenvolver uma declaração de missão para o banco de dados: identifica a
finalidade do banco de dados, como ele será usado e quem o usará. Esta etapa define
o tom do resto do processo de design.
2. Determinar os dados que precisam ser armazenados: identifica todos os tipos
diferentes de dados que precisam ser armazenados no banco de dados. Geralmente,
essas informações são coletadas como parte da tarefa de análise de requisitos, através
de diagramas de relacionamento entre entidades.
3. Dividir os dados em tabelas e colunas: identifica as tabelas e as informações que
você deseja armazenar nessas tabelas.
4. Escolher chaves primárias: uma chave primária é uma coluna ou um conjunto de
colunas que identifica exclusivamente cada linha de dados de uma tabela.
5. Identificar relações: identifica como os dados de uma tabela estão relacionados
com os dados de outra tabela. Por exemplo, para cada cliente de uma tabela Clientes,
você pode ter vários pedidos na tabela Pedidos; essa relação é chamada de relação
um-para-muitos.
6. Aplicar o processo de normalização: aplica regras de normalização de dados para
garantir que qualquer problema que possa afetar a integridade dos dados seja resolvido.
Você aprenderá mais sobre o processo de normalização posteriormente nesta lição.
Após estabelecer a finalidade de um banco de dados, o próximo conjunto de etapas (etapas
2 a 5) poderá ser executado como parte da modelagem de relacionamento entre entidades.
A etapa final de normalização poderá, então, ser aplicada à saída dessa modelagem.

Noções básicas sobre diagramas de relacionamento entre entidades

Os diagramas de relacionamento (ERDs) entre entidades são usados para modelar


entidades, seus atributos e os relacionamentos entre as entidades. Esses diagramas podem
ajudá-lo a determinar quais dados precisam ser armazenados em um banco de dados.

A modelagem de relacionamento entre entidades é um processo usado para criar o modelo


de dados conceitual de um sistema, e diagramas de relacionamento entre entidades são as
ferramentas de modelagem gráfica para realizar essa modelagem. Os blocos de construção
básicos de um ERD são entidade, atributo e relacionamento:
• Entidade: uma entidade é um constructo de um objeto físico ou um conceito. Um
pedido, um cliente, um funcionário e assim por diante são alguns exemplos. Em
geral, uma entidade é denominada pelo nome que representa.
• Atributo: atributos são as propriedades distintas de uma entidade. Por exemplo,
para uma entidade Order, alguns atributos úteis podem ser OrderNumber, OrderDate,
ShipDate e ShipVia. Da mesma forma, para uma entidade Employee, alguns atributos
úteis podem ser EmployeeId, LastName, FirstName, Title e HireDate. Cada entidade
deve ter um conjunto de atributos de identificação exclusiva que é conhecido como a
chave primária da entidade. Por exemplo, um OrderNumber é um atributo que identifica
com exclusividade um pedido, portanto, ele é uma chave primária da entidade Order.
Noções básicas sobre bancos de dados | 145

• Relação: uma relação é uma associação entre entidades. Por exemplo, Takes é
um relacionamento entre uma entidade Employee e uma entidade Order (ou seja,
Employee Takes Order).
Observe que os ERDs não mostram entidades únicas ou relações únicas. Por exemplo,
é possível haver milhares de entidades Order e centenas de entidades Customer. Nesse
caso, esses diagramas mostram conjuntos de entidades e conjuntos de relacionamentos —
por exemplo, todas as milhares de entidades Order podem formar um único conjunto de
entidades. Na verdade, quando Order ou Customer aparece em um ERD, ele geralmente
se refere a um conjunto de entidades, e não a uma entidade individual.
Os ERDs usam convenções de design específicas. Em especial:
• Um retângulo representa um conjunto de entidades.
• Uma elipse representa um atributo.
• Um losango representa um conjunto de relacionamentos.
• As linhas sólidas vinculam conjuntos de entidades a conjuntos de relacionamentos e
conjuntos de entidades a atributos.
A figura 6-2 mostra um ERD de exemplo. Neste diagrama, os dois conjuntos de entidades
são Customer e Order. Os atributos associados a Customer são ID, Name e City. Os
atributos associados a Order são OrderID, OrderDate e ShipDate. Esses atributos que
formam uma chave primária são sublinhados. Além disso, conforme mostrado na figura, o
relacionamento entre Customer e Order é Places.
Figura 6-2
Um diagrama de
relacionamento entre
entidades

Dentro de um ERD, um relacionamento pode ser classificado como um-para-um, um-para-


muitos ou muitos-para-muitos. Na figura 6-2, a linha que conecta o relacionamento Places
ao conjunto de entidades Customer é rotulado como “1”, ao passo que a linha entre
Places e o conjunto de entidades Order é rotulado como “N”. Esse é um exemplo de um
relacionamento um-para-muitos. Nesse relacionamento, um cliente pode colocar vários
pedidos, mas um pedido pode ter apenas um cliente associado a ele.

MAPEANDO ERDs PARA UM BANCO DE DADOS RELACIONAL


Para converter um ERD em um banco de dados relacional, você deve executar as
seguintes etapas:
1. Mapear as entidades: comece criando uma tabela para cada conjunto de entidades
no diagrama. Os atributos se tornarão colunas. Certifique-se de definir o(s) atributo(s)
de chave primária para a(s) coluna(s) de chave primária da tabela.
2. Mapear o relacionamento: em seguida, mapeie o relacionamento um-para-muitos,
garantindo que a tabela no lado N do relacionamento contenha a coluna de chave
primária da tabela no lado 1 do relacionamento. Para a figura 6-2, isso pode ser feito
adicionando uma coluna CustomerID da tabela Order que é mapeada para a coluna
ID da tabela Customer. No contexto da tabela Order, CustomerID também é chamado
de chave estrangeira. A adição dessa coluna na tabela Order permite responder a
perguntas como “Quais são todos os pedidos feitos por um cliente específico?”
e “Quem é o cliente de um pedido específico?”
146 | lição 6

Quando mapeado para um banco de dados relacional, o ERD da figura 6-2 gera as tabelas
a seguir:
Customers

ID Name City
1001 Jane Doe Berlin
1002 John Doe Tokyo
1003 Howard Steel Sydney

Orders

OrderID CustomerId OrderDate ShipDate


101 1001 10/1/2010 10/7/2010
102 1002 10/5/2010 10/10/2010
103 1001 10/4/2010 10/10/2010

Noções básicas sobre normalização de dados

O processo de normalização de dados garante que um design de banco de dados não


tenha problemas que possam levar à perda da integridade dos dados.

A análise do relacionamento entre entidades ajuda a garantir sua identificação dos itens de
dados corretos para seu banco de dados. Em seguida, através do processo de normalização
de dados, você aplica um conjunto de regras de normalização para se certificar de que
tenha estabelecido o design de banco de dados correto — ou seja, você verifica se as
colunas pertencem às tabelas certas para garantir que seu banco de dados esteja livre de
problemas indesejáveis.
Por exemplo, como parte da análise do relacionamento entre entidades, você pode
encontrar uma tabela Livros com as seguintes colunas:
Books

BookId BookName CategoryId CategoryName


1 Cooking Light 1001 Cooking
2 Prophecy 1002 Mystery & Thriller
3 Shift 1003 Business
4 The Confession 1002 Mystery & Thriller

No entanto, esse design para a tabela Livros sofre de três problemas:


• Anomalia de inserção: uma anomalia de inserção é uma situação em que não
é possível inserir novos dados em um banco de dados por causa de uma dependência
não relacionada. Por exemplo, se você quiser que seu banco de dados tenha novos
CategoryId e CategoryName para os livros de história, o design atual não permitirá
isso, a menos que você primeiro tenha um livro de história para colocar nessa categoria.
Noções básicas sobre bancos de dados | 147

• Anomalia de exclusão: uma anomalia de exclusão é uma situação em que a exclusão


de uma parte dos dados provoca a perda involuntária de outros dados. Por exemplo,
se você excluir BookId 3 da tabela Livros, o fato de já ter havido um CategoryName
Business seria perdido.
• Anomalia de atualização: uma anomalia de atualização é uma situação em que
a atualização de um único valor de dados requer a atualização de várias linhas. Por
TOME NOTA
* exemplo, suponha que você decida alterar o nome de categoria Mystery & Thriller
A normalização pode para simplesmente Mystery. Com o design de tabela atual, você deverá alterar
ajudá-lo a garantir um o nome de categoria para cada livro nessa categoria. Se você atualizar o nome de
design de banco de ­categoria em uma linha, mas não nas outras, você também corre o risco de acabar
dados correto, mas não tendo dados inconsistentes no banco de dados.
pode assegurar que
você tenha os itens de Cada um desses problemas pode ser corrigido seguindo o processo de normalização. Há
cinco formas normais utilizadas como parte desse processo; no entanto, esta lição discute
dados corretos para
apenas os três primeiros, pois eles representam tudo o que é necessário na maioria dos casos.
começar.
NOÇÕES BÁSICAS SOBRE A PRIMEIRA FORMA NORMAL
Para uma tabela estar na primeira forma normal (1NF), nenhuma das colunas na tabela
deverá ter valores múltiplos na mesma linha de dados. Por exemplo, se uma tabela
Customers armazenar dados, como mostrado abaixo, essa tabela não estará na 1NF, pois
a coluna PhoneNumber estará armazenando mais de um valor em cada linha.
Customer

TOME NOTA
* Id FirstName LastName PhoneNumber
Uma convenção geral
consiste em sublinhar 1 Jane Doe (503) 555-6874
os nomes das colunas 2 John Doe (509) 555-7969,
em uma tabela que (509) 555-7970
fazem parte da chave
primária. 3 Howard Steel (604) 555-3392,
(604) 555-3393

Para essa tabela estar em 1NF, você precisará dividi-la em duas:


Customer

Id FirstName LastName
1 Jane Doe
2 John Doe
3 Howard Steel

CustomerPhones

Id PhoneNumber
1 (503) 555-6874
2 (509) 555-7969
2 (509) 555-7970
3 (604) 555-3392
3 (604) 555-3393
148 | lição 6

Aqui, a tabela Customers e a tabela CustomerPhones estão ambas em 1NF. Ambas


as tabelas têm uma chave primária (Id na primeira tabela e a combinação de Id e
PhoneNumber na segunda tabela) que estabelece um relacionamento entre elas. Com base
em qualquer Id de um cliente, você poderá encontrar todos os números de telefone para
esse cliente sem qualquer confusão. Por outro lado, LastName não é uma chave primária,
pois um sobrenome pode ter entradas duplicadas.

A criação de colunas de repetição, como PhoneNumber1 e PhoneNumber2, para


*
TOME NOTA normalizar a tabela Customer não seria uma solução aceitável, pois o primeiro
formulário de normalização não permite esse tipo de coluna.

NOÇÕES BÁSICAS SOBRE A SEGUNDA FORMA NORMAL


Para uma tabela estar na segunda forma normal (2NF), primeiro deverá cumprir os
requisitos para 1NF. Além disso, 2NF exige que todas as colunas que não são de chave
sejam funcionalmente dependentes de toda a chave primária.
Para compreender 2NF, você deve primeiro compreender o significado de dependência
funcional. Vamos usar o exemplo da tabela Customers acima. Na tabela Customers, a
coluna Id é a chave primária, pois ela identifica exclusivamente cada linha. As colunas
FirstName e LastName são colunas que não são de chave, pois elas não fazem parte da
chave primária. Tanto FirstName quanto LastName são funcionalmente dependentes de
Id, pois, com base em um valor de Id, você poderá sempre encontrar um valor para o
FirstName e o LastName correspondente sem qualquer ambiguidade. Não há nenhuma
coluna que não seja de chave na tabela Customers que não dependa funcionalmente da
chave primária. As tabelas Customers e CustomerPhones já estão, portanto, em 2NF.

2NF aplica-se somente a tabelas com chaves primárias compostas (ou seja, várias
colunas juntas compõem a chave primária). Os valores combinados de todos os campos
*
TOME NOTA em uma chave primária composta devem ser exclusivos. Se uma tabela atender à
1NF e tiver apenas uma única coluna em sua chave primária, ela também estará em
conformidade com a 2NF.
Por outro lado, considere a tabela a seguir:

Orders

OrderId CustomerId OrderDate CustomerName


101 1 10/1/2010 Jane Doe
102 2 10/5/2010 John Doe
103 1 10/4/2010 Jane Doe

Aqui, as colunas OrderId e CustomerId juntas identificam uma linha exclusiva e, portanto,
formam uma chave primária composta. No entanto, a coluna OrderDate é funcionalmente
dependente apenas de OrderId, e a coluna CustomerName é dependente apenas de
CustomerId. Isso viola 2NF, pois as colunas que não são de chave são funcionalmente
dependentes apenas de parte da chave primária.
Uma maneira possível de modificar a tabela Orders para que ela fique em conformidade
com 2NF é retirar CustomerName da tabela e ter apenas três colunas — OrderId,
CustomerId e OrderDate — com apenas OrderId funcionando como chave primária. Nessa
solução, tanto CustomerId quanto OrderDate são funcionalmente dependentes de OrderId
e, portanto, estão em conformidade com 2NF.
Noções básicas sobre bancos de dados | 149

NOÇÕES BÁSICAS SOBRE A TERCEIRA FORMA NORMAL


A terceira forma normal (3NF) exige que 2NF seja atendida e que não haja nenhuma
dependência funcional entre os atributos que não são de chave. Em outras palavras, cada
atributo que não seja de chave deve ser dependente apenas da chave primária e de nada
mais. Por exemplo, considere a tabela a seguir:
Items

ItemId SupplierId ReorderFax


101 100 (514) 555-2955
102 11 (514) 555-9022
103 525 (313) 555-5735

Aqui, ItemId é a chave primária. No entanto, ReorderFax é um número de fax do


fornecedor e, portanto, dependente funcionalmente de SupplierId. Para atender ao requisito
de 3NF, essa tabela deve ser decomposta em duas tabelas: Items (ItemId, SupplierId) e
Supplier (SupplierId, ReorderFax).
Items

ItemId SupplierId
101 100
102 11
103 525

Supplier
PRONTO PARA
CERTIFICAÇÃO
Você compreende SupplierId ReorderFax
as noções básicas
dos sistemas de 100 (514) 555-2955
gerenciamento de
banco de dados 11 (514) 555-9022
relacional? 525 (313) 555-5735
6,1

■ Noções básicas sobre métodos de consulta de banco de dados

Os dados estão no cerne de vários aplicativos de negócios, e, como desenvolvedor,


você provavelmente perderá muito tempo trabalhando em tarefas relacionadas a dados.
O RESULTADO Nesta seção, você aprenderá a usar a linguagem SQL e os procedimentos armazenados
do SQL Server para selecionar, inserir, atualizar e excluir dados.

SQL é a linguagem usada pela maioria dos sistemas de banco de dados para gerenciar as
informações em seus bancos de dados. Os comandos SQL permitem que você recupere e
atualize dados. Os comandos SQL também permitem que você crie e gerencie objetos de
banco de dados, como tabelas. A linguagem SQL pode ser considerada uma linguagem de
programação para bancos de dados relacionais. No entanto, ela é declarativa, por natureza,
em oposição à natureza imperativa das linguagens de programação mais comuns.
150 | lição 6

Em SQL, você informa ao banco de dados o que precisa ser feito, e é função do banco
de dados descobrir como fazer isso — por exemplo, você pode dizer ao banco de dados
para selecionar as 10 primeiras linhas de uma tabela. Compare isso com uma linguagem
de programação imperativa, como C#, em que você precisa especificar em detalhes como
o trabalho deve ser realizado. Por exemplo, você pode precisar criar um loop que seja
executado dez vezes, configurar e inicializar variáveis, mover ponteiros de registro etc.
SQL é um padrão ANSI (American National Standards Institute), mas diferentes
fornecedores de banco de dados implementaram suas próprias extensões ao SQL padrão.
A implementação do Microsoft SQL Server é denominada T-SQL (Transact-SQL).
Há duas maneiras principais de enviar T-SQL para o SQL Server. Você pode usar
instruções SQL ad hoc executadas diretamente ou usar procedimentos armazenados. Os
procedimentos armazenados são coleções de instruções SQL e lógica de programação
armazenadas no servidor de banco de dados como objetos nomeados.
Trabalhando com consultas SQL

As instruções SELECT, INSERT, UPDATE e DELETE são os quatro tipos principais


de instruções SQL usados para manipular dados do SQL Server.

O uso de consultas SQL ad hoc é uma maneira flexível de trabalhar com um banco de
dados SQL Server. Nesta parte da lição, você aprenderá as noções básicas sobre os quatro
tipos principais de instruções SQL que o ajudarão a manipular dados do SQL Server:
• As instruções SELECT permitem que você recupere dados armazenados em um
banco de dados.
• As instruções INSERT permitem que você adicione novos dados a um banco de dados.
• As instruções UPDATE permitem que você modifique os dados existentes em um
banco de dados.
• As instruções DELETE permitem que você exclua dados de um banco de dados.

CONECTANDO-SE A UM BANCO DE DADOS DO SQL SERVER

Você precisará se conectar a um banco de dados SQL Server antes de manipular


qualquer informação nesse banco de dados.

Neste exercício, você aprenderá a trabalhar com um banco de dados Microsoft SQL
Server. Se não tiver acesso a uma versão recente do SQL Server, você poderá baixar o
SQL Server 2008 Express gratuitamente de http://www.microsoft.com/pt-br/server-cloud/
products/sql-server-editions/sql-server-standard.aspx. Este exercício usa o banco de dados
SQL Server de exemplo Northwind. Esse banco de dados não é instalado, por padrão, com
o SQL Server, mas você pode baixar o arquivo de banco de dados seguindo as instruções
em http://msdn.microsoft.com/pt-br/library/ms143221.aspx.
Execute o exercício a seguir para se conectar ao banco de dados Northwind e usá-lo com
o Visual Studio.

CONECTAR AO BANCO DE DADOS NORTHWIND


PREPARE-SE. Antes de iniciar estas etapas, certifique-se de iniciar o Microsoft Visual Studio.
1. Abra a janela Gerenciador de Servidores. Selecione o nó Conexões de Dados, clique no
botão Conectar ao Banco de Dados na barra de ferramentas Gerenciador de Servidores.

No Visual Studio Express Edition, a janela Gerenciador de Servidores é chamada de


*
TOME NOTA Gerenciador de Banco de Dados e pode ser aberta selecionando Exibir > Outras Janelas
> Gerenciador de Banco de Dados.
Noções básicas sobre bancos de dados | 151

2. Na caixa de diálogo Adicionar Conexão, navegue até o arquivo do banco de dados


Northwind (northwnd.mdf), como mostra a figura 6-3.

Figura 6-3
Conectando ao banco de
dados Northwind

3. Use a Autenticação do Windows como o modo de autenticação e clique no botão


Testar Conexão para verificar se você consegue se conectar ao banco de dados.
Finalmente, clique no botão OK para adicionar a conexão ao banco de dados.
4. Assim que a conexão estiver estabelecida, o banco de dados estará disponível como
uma conexão sob o nó Conexões de Dados no Gerenciador de Servidores. Expanda
o banco de dados para ver as tabelas, os procedimentos armazenados e outros
objetos de banco de dados, conforme mostra a figura 6-4.

Figura 6-4
Acessando o banco de
dados Northwind através do
Gerenciador de Servidores
152 | lição 6

5. Clique com o botão direito do mouse no nó NORTHWND.MDF e selecione


Propriedades. Você deverá ver a janela Propriedades, mostrada na figura 6-5.
Nessa janela, observe a propriedade Connection String. Você usará o valor dessa
­propriedade para se conectar ao banco de dados Northwind de um aplicativo C#.

Figura 6-5
Janela Propriedades do
banco de dados Northwind

PAUSE. Você acessará os dados do banco de dados Northwind no próximo exercício.

EXECUTANDO CONSULTAS SQL

Há várias maneiras de se comunicar com o SQL Server para executar consultas de

bancos de dados.
Há várias maneiras de enviar consultas para um SQL Server. Por exemplo, você pode usar
qualquer um destes:
• IDE (ambiente de desenvolvimento integrado) do Visual Studio
• Aplicativo C#
• SQL Query Analyzer
• utilitário de prompt de comando osql
Observe que os utilitários de prompt de comando SQL Query Analyzer e osql são
ferramentas instaladas com o SQL Server.

EXECUTAR CONSULTAS DO VISUAL STUDIO

PREPARE-SE. Para usar os aplicativos C# e IDE do Visual Studio para executar consultas
SQL, siga estas etapas:
1. Selecione o banco de dados Northwind no Gerenciador de Servidores. Clique com o botão
direito do mouse no banco de dados e selecione Nova Consulta. Essa ação abre um
Designer de Consultas e mostra uma caixa de diálogo Adicionar Tabela. Selecione a tabela
Clientes e clique em Adicionar. Clique em Fechar na caixa de diálogo Adicionar Tabela.
2. No painel SQL do Designer de Consultas (que é a área que exibe o texto da consulta),
modifique a instrução SQL para:
SELECT * FROM Customers
3. No menu do Visual Studio, selecione a opção Designer de Consultas > Executar
SQL ou clique no botão Executar SQL na barra de ferramentas. A instrução SQL será
enviada para o servidor SQL para execução, e é possível que resultados como os da
figura 6-6 sejam exibidos.
Noções básicas sobre bancos de dados | 153

Figura 6-6
Designer de Consultas do
Visual Studio

O Designer de Consultas no Visual Studio exibe até quatro painéis. Os painéis são os
seguintes, de cima para baixo:
• Painel Diagrama: esse painel exibe as tabelas envolvidas na consulta e os
relacionamentos entre essas tabelas, bem como todas as colunas contidas nas tabelas.
• Painel Critérios: esse painel mostra as colunas que foram selecionadas como parte
da consulta, bem como informações adicionais de classificação e filtragem.
• Painel SQL: esse painel mostra a real instrução SQL que será executada.
• Painel Resultados: esse painel mostra os resultados (se houver) depois que
a consulta tiver sido executada.
A barra de ferramentas Designer de Consultas inclui botões que você pode usar para
ocultar ou mostrar qualquer um desses quatro painéis. Para o exercício a seguir, você
precisará apenas do painel SQL e do painel Resultados.

EXECUTAR CONSULTAS DO APLICATIVO C#

PREPARE-SE. Para executar consultas de aplicativos C#, faça o seguinte:


1. Crie um novo projeto de aplicativo do Windows denominado QueryCS.
2. Para o Windows Form, adicione um controle TextBox, um controle Button e um
controle DataGridView. Defina a propriedade MultiLine de TextBox para True. Defina
a propriedade Text do controle Button para Execute SQL.
3. Clique duas vezes no controle Button para gerar um manipulador de eventos para
o evento Click. Modifique o manipulador de eventos, como mostrado abaixo:
private void button1_Click(
object sender, EventArgs e)
{
if (textBox1.TextLength > 0)
{
SelectData(textBox1.Text);
}
}
154 | lição 6

4. Adicione o método a seguir à classe. Certifique-se de alterar a cadeia de caracteres de


conexão para corresponder ao caminho local do arquivo de banco de dados no seu
computador:
private void SelectData(string selectCommandText)
{
try
{
// Altere a cadeia de conexão
// de acordo com seu sistema.
string selectConnection =
@"Data Source=.\SQLEXPRESS;" +
@"AttachDbFilename=" +
@"c:\SqlSampleDB\NORTHWND.MDF;" +
@"Integrated Security=True;" +
@"Connect Timeout=30;User Instance=True";
SqlDataAdapter dataAdapter =
new SqlDataAdapter(
selectCommandText, selectConnection);
DataTable table = new DataTable();
dataAdapter.Fill(table);
dataGridView1.DataSource = table;
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
5. Adicione as diretivas using a seguir ao código:
using System.Data;
using System.Data.SqlClient;
Selecione Depurar > Iniciar Depuração para executar o projeto. Digite uma consulta
SQL válida e clique no controle Button. Você deverá ver a saída mostrada na figura 6-7.

Figura 6-7
Consultas em execução de
um aplicativo C#
Noções básicas sobre bancos de dados | 155

O código nesse exercício implementa um método SelectData que inicializa um objeto


SqlDataAdapter e usa-o para preencher um DataTable. Depois disso, DataTable
é vinculado como uma fonte de dados para o componente DataGridView. O objeto
SqlDataAdapter atua como um pipeline entre o SQL Server e o DataTable para
a recuperação de dados. O método Fill altera os dados em DataTable para corresponder
aos dados na fonte de dados. O selectCommandText é usado para identificar os dados na
fonte de dados.
SELECIONANDO DADOS

A instrução SELECT é usada para recuperar dados de uma ou mais tabelas de banco
de dados.
A instrução SELECT geralmente tem a seguinte forma:
SELECT list_of_fields
FROM list_of_tables
WHERE where_clause
GROUP BY group_by_clause
HAVING having_clause
ORDER BY order_by_clause
Cada uma dessas linhas de código na instrução SELECT é chamada de cláusula. As
cláusulas SELECT e FROM são necessárias, mas o restante é opcional. Por exemplo, esta
é uma instrução SQL que contém apenas as cláusulas necessárias:
SELECT OrderId, CustomerId
FROM Orders
Se quiser listar todos os campos de uma tabela, você também poderá usar o atalho a
seguir, em vez de listar explicitamente todos os campos:
SELECT *
FROM Orders
Além disso, você pode selecionar informações de várias tabelas; por exemplo:
Select OrderId, Customers.CustomerId, ContactName
From Orders, Customers
Customers.CustomerId é conhecido como um nome totalmente qualificado por especificar
o nome da tabela e o nome do campo. Isso é necessário porque as tabelas Orders e
Customers incluem esse campo, portanto, você deve informar ao SQL Server à qual tabela
específica você deseja se referir.
Se executar essa consulta, você terá muito mais registros do que o esperado. Isso acontece
porque, embora tenha informado ao SQL Server quais tabelas incluir, você não inseriu
qualquer informação sobre como relacionar essas tabelas. Como resultado, o SQL Server
constrói o conjunto de resultados para incluir todas as linhas da tabela Customer para cada
linha da tabela Orders. Este tipo de junção é chamado de junção cruzada e, nesse caso,
não é muito útil.
Uma consulta mais útil, é claro, faria a correspondência de cada pedido com o respectivo
cliente. A palavra-chave INNER JOIN pode ajudá-lo a fazer isso, como mostrado na
consulta a seguir:
SELECT OrderID, Customers.CustomerId, ContactName
FROM Orders INNER JOIN Customers
ON Orders.CustomerId = Customers.CustomerId
156 | lição 6

Essa consulta informa ao SQL Server para fazer a correspondência de cada linha da
tabela Orders com todas as linhas da tabela Customers em que o CustomerId do pedido é
igual ao CustomerId do cliente. Como CustomerId é exclusivo na tabela Customers, isso
equivale a incluir apenas uma única linha para cada pedido no conjunto de resultados.
Neste caso, o conjunto de resultados terá o mesmo número de linhas que o número de
linhas existentes na tabela Orders.
Mas, e se você quiser ver apenas algumas linhas da tabela? Nessa situação, você poderá
TOME NOTA
* usar a cláusula WHERE. A cláusula WHERE avalia cada linha para uma condição e
O delimitador padrão
decide se a incluirá no conjunto de resultados. Por exemplo:
para texto e datas no
SQL Server é a aspa SELECT *
simples. FROM Orders
WHERE ShipCountry = 'Canada'
Aqui, a cláusula WHERE examina todas as linhas da tabela Orders para ver se
ShipCountry tem o valor exato “Canada”. Se isso acontecer, a linha será incluída no
conjunto de resultados; caso contrário, a linha não será incluída no conjunto de resultados.
Você também pode combinar várias condições em uma única cláusula WHERE. Por
exemplo:
SELECT *
FROM Orders
WHERE (ShipCountry = 'Canada')
AND (OrderDate >= '01/01/97')
AND (OrderDate <= '01/31/97')
Aqui, as condições WHERE filtram os pedidos em que ShipCountry é “Canada” e a data
do pedido é janeiro de 1997.
Por padrão, o SQL não garante que os resultados estejam em uma ordem específica. No
entanto, você pode usar a cláusula ORDER BY para garantir que os dados desejados
sejam retornados em uma ordem específica. Por exemplo, para listar os pedidos com base
na data do pedido, você pode usar a seguinte consulta:
SELECT *
FROM Orders
WHERE (ShipCountry = 'Canada')
AND (OrderDate >= '01/01/97')
AND (OrderDate <= '01/31/97')
ORDER BY OrderDate
Você pode modificar a ordem de classificação, usando a palavra-chave ASC (para
ordem crescente) ou DESC (para ordem decrescente). A ordem de classificação padrão
é crescente. Portanto, a consulta a seguir lista os pedidos mais recentes na parte superior:
SELECT *
FROM Orders
WHERE (ShipCountry = 'Canada')
AND (OrderDate >= '01/01/97')
AND (OrderDate <= '01/31/97')
ORDER BY OrderDate DESC
Noções básicas sobre bancos de dados | 157

É bastante comum os aplicativos de negócios solicitarem dados agregados ou resumidos.


Esses requisitos podem ser abordados usando a cláusula GROUP BY e funções de
agregação. Por exemplo, você pode usar a consulta a seguir a fim de saber para quais
países despacha a maioria de seus pedidos:
SELECT ShipCountry, COUNT(ShipCountry) AS OrderCount
FROM Orders
GROUP BY ShipCountry
ORDER BY OrderCount DESC
Isso exibirá o nome de cada país seguido do número total de pedidos despachados para
esse país. A cláusula ORDER BY classifica o resultado e coloca os países com a maioria
dos pedidos no topo da lista.
Você pode pensar na cláusula GROUP BY como uma criação de “buckets” — nesse caso,
um para cada país. À medida que o mecanismo de banco de dados examina cada registro,
ele o lança no bucket apropriado. Após a conclusão desse processo, o mecanismo de
banco de dados conta o número de registros final em cada bucket e produz uma linha para
cada um deles. A figura 6-8 mostra o início do conjunto de resultados dessa consulta.
Figura 6-8
Resumindo informações
usando a cláusula GROUP BY

Na instrução SQL anterior, Count é uma função de agregação, ou seja, ele retorna um
resultado com base em um grupo de linhas. T-SQL oferece suporte várias funções de
agregação diferentes. Algumas das mais comuns são:
• Count: retorna o número de registros
• Sum: retorna o valor total em uma determinada coluna
• Avg: retorna o valor médio em uma determinada coluna
• Min: retorna o menor valor em uma determinada coluna
• Max: retorna o maior valor em uma determinada coluna

ATUALIZAÇÃO DE DADOS

A instrução UPDATE é usada para atualizar informações nas tabelas de banco de dados.

Outra instrução SQL útil é a UPDATE. A finalidade de uma instrução UPDATE é


atualizar ou modificar dados. Por exemplo, você pode atualizar um campo em um registro
na tabela Customers usando a seguinte consulta:
UPDATE Customers
SET ContactName = 'Maria Anderson'
WHERE CustomerId = 'ALFKI'
158 | lição 6

Nessa consulta, a palavra-chave SET informa ao SQL Server quais colunas atualizar,
TOME NOTA
* e a palavra-chave WHERE informa a ele quais linhas atualizar. Na tabela Customers,
Em uma instrução CustomerId é uma chave primária e é identificada exclusivamente por uma única linha.
UPDATE, a cláusula Portanto, essa instrução UPDATE pode atualizar, no máximo, uma linha.
SET é necessária
e pode ser especificada Observe, no entanto, que você não está limitado a atualizar apenas um único registro.
apenas uma vez. Pelo contrário, se a cláusula WHERE selecionar vários registros, todos esses registros
serão atualizados:
UPDATE Customers
TOME NOTA
* SET Country = 'United States'
É altamente WHERE Country = 'USA'
recomendável
que você examine Você também pode atualizar mais de um campo por vez com uma instrução UPDATE,
cuidadosamente como no exemplo a seguir:
a cláusula WHERE UPDATE Customers
para cada instrução
SET ContactName = 'Maria Anderson',
UPDATE. Se não tiver
cuidado, você poderá CITY = 'Tokyo'
atualizar dados para WHERE CustomerId = 'ALFKI'
mais linhas do que
o desejado.
INSERÇÃO DE DADOS

A instrução INSERT é usada para adicionar uma ou mais linhas a uma tabela de
banco de dados.

A instrução INSERT lista os campos para a tabela de destino, seguidos por um conjunto
de valores para inserir nesses campos. Por exemplo, a instrução INSERT a seguir insere
uma linha na tabela Order Details:
INSERT INTO [Order Details]
(OrderId, ProductId, UnitPrice, Quantity, Discount)
VALUES (10248, 2, 19.00, 2, 0)
Colchetes são necessários quando os nomes de tabelas ou campos contêm espaços. Aqui,
o primeiro conjunto de parênteses contém uma lista de colunas, e o segundo conjunto
contém os valores a serem inseridos. Se um campo tiver um valor padrão, puder ser nulo
ou for um campo de identidade, você poderá deixá-lo fora da lista de campos, como no
exemplo a seguir:
INSERT INTO [Order Details]
(OrderId, ProductId, UnitPrice, Quantity)
VALUES (10249, 2, 19.00, 2)
Essa instrução funcionará mesmo que nenhum valor tenha sido especificado para o campo
Discount. Além disso, com essa instrução, você poderá reorganizar uma lista de campos
desde que reorganize a lista de valores para correspondência:
INSERT INTO [Order Details]
(ProductId, OrderId, UnitPrice, Quantity)
VALUES (2, 10250, 19.00, 2)
A instrução INSERT não se limita à inserção de um único registro. Na verdade, há um
segundo formato que insere os resultados de uma instrução SELECT na tabela de destino.
Por exemplo, esta consulta insere um produto de cada fornecedor na tabela Products:
INSERT INTO Products
(SupplierId, ProductName, CategoryId)
SELECT SupplierId, 'Almond', 7
FROM Suppliers
Noções básicas sobre bancos de dados | 159

Essa consulta funciona compilando os resultados da instrução SELECT e, em seguida,


inserindo cada linha retornada pelas instruções SELECT na tabela de destino. É evidente
que as colunas ainda precisarão coincidir adequadamente.

EXCLUSÃO DE DADOS

A instrução DELETE é usada para remover informações das tabelas de banco de dados.

A instrução DELETE remove dados de uma tabela. Para fins de prática e para evitar a
exclusão de dados do mesmo banco de dados, você poderá copiar uma tabela usando uma
instrução SELECT, como no exemplo a seguir:
SELECT * INTO CustomersCopy
FROM Customers
Essa instrução seleciona todos os registros da tabela Customers e copia-os para uma nova
tabela denominada CustomersCopy.
Para excluir uma única linha de dados da tabela CustomersCopy, você usaria a seguinte
instrução DELETE:
DELETE FROM CustomersCopy
WHERE CustomerId = 'ALFKI'
Tenha cuidado, pois se omitir a cláusula WHERE, você excluirá todos os dados da tabela:
DELETE FROM CustomersCopy

Trabalhando com procedimentos armazenados

Um procedimento armazenado é um conjunto de instruções SQL que são


armazenadas em um banco de dados. Os procedimentos armazenados podem ser
usados por vários aplicativos.

Em contraste com as consultas ad hoc, os procedimentos armazenados são consultas


armazenadas permanentemente em um SQL Server. Você pode considerar os
procedimentos armazenados como o equivalente SQL dos métodos C#.
Os procedimentos armazenados têm dois benefícios principais. Primeiro, você pode
usá-los para salvar instruções SQL complexas para execução futura. Segundo, o SQL
Server compila os procedimentos armazenados para que eles possam ser executados mais
rápido do que as consultas ad hoc. Nesta seção da lição, você aprenderá a criar e executar
procedimentos armazenados.

CRIANDO E EXECUTANDO UM PROCEDIMENTO ARMAZENADO


O comando CREATE PROCEDURE pode ser usado para criar um novo procedimento
armazenado.
Você pode usar a palavra-chave CREATE PROCEDURE do T-SQL para criar um
procedimento armazenado. Você pode executar a instrução CREATE PROCEDURE
de qualquer interface que permite que você insira e execute o T-SQL.
160 | lição 6

CRIAR UM PROCEDIMENTO ARMAZENADO DO VISUAL STUDIO

PREPARE-SE. Para criar um procedimento armazenado do Visual Studio, execute as


seguintes ações:
1. Abra o Gerenciador de Servidores e selecione o banco de dados Northwind.
Clique com o botão direito do mouse no nó Procedimento Armazenado e selecione
a opção Adicionar Novo Procedimento Armazenado Procedimento.
2. No designer de procedimento armazenado, substitua o texto clichê pelo seguinte
código:
CREATE PROCEDURE GetCustomersFromFrance
AS
SELECT * FROM Customers
Where Country = 'France'
RETURN
3. Salve o procedimento armazenado. O procedimento armazenado é agora adicionado
ao banco de dados.
TOME NOTA
* 4. Para executar o procedimento armazenado, clique com o botão direito do mouse
Você pode usar a
no procedimento armazenado no Gerenciador de Servidores e selecione Executar.
instrução ALTER
O resultado do procedimento armazenado deve ser exibido na janela Saída.
PROCEDURE para
modificar a definição 5. Você também poderá executar esse procedimento armazenado do projeto QueryCS
de um procedimento criado anteriormente. Aqui, em vez de uma instrução SQL, digitar simplesmente
armazenado existente. o nome do procedimento armazenado e clique no botão Executar SQL. O resultado
do procedimento armazenado será exibido no Windows Form.

TRABALHANDO COM PROCEDIMENTOS ARMAZENADOS PARAMETRIZADOS

Os procedimentos armazenados parametrizados permitem que você passe


argumentos de tempo de execução para o SQL Server.

A capacidade de passar parâmetros aumenta significativamente a eficiência dos


procedimentos armazenados. Os valores dos parâmetros podem ser fornecidos em tempo
de execução para os procedimentos armazenados.
Suponha que você queira descobrir o total de vendas de um determinado cliente no banco
de dados Northwind. Nessa situação, você deve ser capaz de especificar CustomerId em
tempo de execução.

CRIAR UM PROCEDIMENTO ARMAZENADO PARAMETRIZADO

PREPARE-SE. Para criar um procedimento armazenado parametrizado, execute estas ações:


1. Abra o Gerenciador de Servidores e selecione o banco de dados Northwind.
Clique com o botão direito do mouse no nó Procedimento Armazenado e selecione
a opção Adicionar Novo Procedimento Armazenado Procedimento.
2. No designer de procedimento armazenado, substitua o texto clichê pelo seguinte
código:
CREATE PROCEDURE dbo.GetCustomerSales
(
@CustomerId char(5),
@TotalSales money OUTPUT
)
Noções básicas sobre bancos de dados | 161

AS
SELECT @TotalSales = SUM(Quantity * UnitPrice)
FROM (Customers INNER JOIN Orders
ON Customers.CustomerId = Orders.CustomerId)
INNER JOIN [Order Details]
ON Orders.OrderId = [Order Details].OrderId
WHERE Customers.CustomerId = @CustomerId
RETURN
3. Salve o procedimento armazenado. O procedimento armazenado é agora adicionado
ao banco de dados.
Nesse procedimento armazenado, @CustomerId e @TotalSales são parâmetros.
@CustomerId é um parâmetro de entrada; você deverá fornecer um valor para esse
parâmetro ao executar o procedimento armazenado. @TotalSales é um parâmetro de
saída; ele retorna um valor do procedimento armazenado. Ao executar esse procedimento
armazenado do Visual Studio, você recebe uma caixa de diálogo solicitando a inserção do
valor para todos os parâmetros, conforme mostra a figura 6-9.

Figura 6-9
A caixa de diálogo Executar
Procedimento Armazenado
solicita os valores de
parâmetro

Para executar esse procedimento armazenado, digite ALFKI como o valor de @


CustomerId e NULL como o valor de @TotalSales. Quando você pressionar o botão OK,
o valor calculado do parâmetro de saída, @TotalSales, será exibido na janela Saída.
Entretanto, você não pode executar um procedimento armazenado parametrizado do
projeto QueryCS, pois o código desse local não aceita parâmetros.

EXECUTAR PROCEDIMENTOS ARMAZENADOS PARAMETRIZADOS DE C#

PREPARE-SE. Para executar procedimentos armazenados parametrizados de C#, realize as


seguintes tarefas:
1. Crie um novo projeto de aplicativo do Windows denominado ParameterizedSP.
2. Coloque um controle Label no formulário e defina sua propriedade Text para
“Customer Id:”. Coloque um controle TextBox ao lado dela e denomine o controle
como CustomerIdTextBox. Em seguida, coloque um controle Button e defina sua
propriedade Name como GetTotalSalesButton e a propriedade Text para “Get Total
Sales”. Finalmente, coloque um controle Label no formulário e denomine-o como
TotalSalesLabel. Organize os controles para que eles fiquem semelhantes à figura 6-10.
162 | lição 6

3. Clique duas vezes no controle Button para gerar um manipulador de eventos para
o evento Click. Modifique o manipulador de eventos, como mostrado abaixo:
private void GetTotalSalesButton_Click(
object sender, EventArgs e)
{
TotalSalesLabel.Text = String.Format(
"Total Sales: {0}",
GetTotalSales(CustomerIdTextBox.Text));
}
4. Adicione o método a seguir à classe. Certifique-se de alterar a cadeia de caracteres
de conexão para corresponder ao caminho local do arquivo de banco de dados no
seu computador:
private double GetTotalSales(string customerId)
{
double totalSales = −1;
try
{
// Altere a cadeia de conexão
// de acordo com seu sistema.
string connectionString =
@"Data Source=.\SQLEXPRESS;" +
@"AttachDbFilename=" +
@"c:\SqlSampleDB\NORTHWND.MDF;" +
@"Integrated Security=True;" +
@"Connect Timeout=30;User Instance=True";
SqlConnection connection =
new SqlConnection(connectionString);
SqlCommand command =
connection.CreateCommand();
command.CommandType =
CommandType.StoredProcedure;
command.CommandText = "GetCustomerSales";
command.Parameters.AddWithValue(
"@CustomerId", customerId);
command.Parameters.AddWithValue(
"@TotalSales", null);
command.Parameters["@TotalSales"].DbType
= DbType.Currency;
command.Parameters["@TotalSales"].Direction
= ParameterDirection.Output;
connection.Open();
command.ExecuteNonQuery();
Noções básicas sobre bancos de dados | 163

totalSales = Double.Parse(
command.Parameters["@TotalSales"]
.Value.ToString());
connection.Close();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
return totalSales;
}
5. Adicione as diretivas using a seguir ao código:
using System.Data;
using System.Data.SqlClient;
Selecione Depurar > Iniciar Depuração para executar o projeto. Insira um CustomerId
válido. Você deverá ver a saída mostrada na figura 6-10.

Figura 6-10
Executando procedimentos
armazenados parametrizados
de um aplicativo C#

No código, os parâmetros são representados por objetos SqlParameter. O código funciona


definindo o valor do parâmetro @CustomerId, executando o objeto SqlCommand
correspondente ao procedimento armazenado e, em seguida, recuperando a propriedade
Value do parâmetro @TotalSales.

Se adicionar uma nova linha a uma tabela com uma coluna de identidade, você poderá
*
TOME NOTA usar a variável @@IDENTITY do SQL Server para recuperar o valor da coluna de
identidade para a linha recém-criada.

O código anterior tem estas linhas:


connection.Open();
command.ExecuteNonQuery();
totalSales = Double.Parse(
command.Parameters["@TotalSales"]
.Value.ToString());
connection.Close();
Aqui, você primeiro abre a conexão de banco de dados, executa o procedimento
necessário com a conexão e, em seguida, fecha a conexão. O objeto que contém
referências à conexão de banco de dados usa uma grande quantidade de recursos do
sistema e, portanto, é dispendioso para execução. Portanto, é recomendável que você
feche esse objeto assim que terminar de usá-lo. Se você não fechar a conexão, haverá
perda de memória no programa que poderá afetar o desempenho.
164 | lição 6

C# também fornece uma instrução using que pode ajudar a assegurar que objetos dispendiosos,
TOME NOTA
* como conexões de banco de dados, sejam fechados automaticamente quando você terminar de
O objeto usado com a usá-los. Aqui está uma versão alternativa do código acima que utiliza a instrução using para
instrução using deve fechar automaticamente a conexão de banco de dados:
implementar a interface
IDisposable. // descartando objetos com a instrução using
using (connection)
PRONTO PARA {
CERTIFICAÇÃO connection.Open();
Você compreende os
vários métodos de command.ExecuteNonQuery();
consulta de banco de totalSales = Double.Parse(
dados?
command.Parameters["@TotalSales"]
.Value.ToString());
PRONTO PARA }
CERTIFICAÇÃO
Você compreende Observe que a instrução using define um escopo para o objeto de conexão. Quando o código
o que são métodos de atinge o final desse escopo, o objeto de conexão é automaticamente fechado, e todos os
conexão de banco de recursos são liberados.
dados?
6,3

■ Noções básicas sobre métodos de conexão de banco de dados

Os aplicativos de negócios podem necessitar de dados em vários formatos. Por exemplo,


O RESULTADO você talvez precise trabalhar com arquivos simples, arquivos XML e objetos na memória.

O .NET Framework fornece classes que são otimizadas para trabalhar com arquivos simples,
arquivos XML e objetos na memória. Os dados armazenados dentro de arquivos simples podem
ser manipulados usando as classes do namespace System.IO. Para trabalhar com dados XML,
as classes do namespace System. XML podem ser usadas. Finalmente, para trabalhar com
objetos na memória, como um DataSet, são usadas as classes do namespace System.Data. Você
aprenderá mais sobre como trabalhar com cada um desses formatos de dados nas seções a seguir.
Trabalhando com arquivos simples

Um arquivos simples é uma tabela de banco de dados armazenada dentro de um


arquivo de disco autônomo.

Um arquivo simples geralmente contém uma linha de dados por linha, e as colunas são separadas
por delimitadores, como vírgulas ou têm um comprimento fixo. Os dados em um arquivo simples
podem ser texto ou binário. Esses arquivos são chamados de “arquivos simples” para distingui-
los das formas mais estruturadas de armazenamento, tais como bancos de dados relacionais e
arquivos XML.
Historicamente, antes do advento dos bancos de dados modernos, os arquivos simples eram uma
maneira popular para armazenar e organizar informações. Eles ainda são úteis atualmente, embora
somente em cenários limitados, ao contrário dos bancos de dados para uso geral. Os arquivos
simples são utilizados no sistema operacional ou nos arquivos de configuração de aplicativo,
ao transferir dados para sistemas remotos e na migração de dados entre sistemas incompatíveis.
A entrada e a saída baseadas em arquivo no .NET Framework giram em torno do conceito de
streams e repositório de backup. Um stream é um fluxo de dados brutos, e um repositório de
backup é a origem ou o destino do stream. Um repositório de backup pode ser um arquivo de
disco, memória, conexão de rede etc. Você poderá encontrar classes para trabalhar com streams
e repositórios de backup no namespace System.IO.
Noções básicas sobre bancos de dados | 165

Como mencionado anteriormente, os arquivos simples podem estar em formato de texto


sem formatação ou binário. Os arquivos de texto são organizados com frequência como
linhas de texto separadas por caracteres de fim-de-linha. As classes StreamReader e
StreamWriter permitem manipular facilmente esses arquivos de texto.
Os arquivos binários armazenam seu conteúdo como uma sequência de bytes. Embora os
arquivos binários não possam ser compreendidos pelo usuário como os arquivos de texto,
eles são capazes de armazenar uma variedade de dados, como imagens, sons, vídeo etc.
Um programa de computador será sempre necessário para interpretar o conteúdo de um
arquivo binário. As classes BinaryReader e BinaryWriter permitem manipular facilmente
os arquivos binários.
No exercício a seguir, você selecionará colunas da tabela Customers e gravará essas
colunas em um arquivo de texto. Posteriormente, você abrirá esse arquivo de texto e
exibirá seu conteúdo na janela de console.

LER E GRAVAR EM UM ARQUIVO DE TEXTO

PREPARE-SE. Para ler e gravar em um arquivo de texto, faça o seguinte:


1. Crie um novo projeto de aplicativo de console denominado WorkingWithTextFiles.
2. Adicione o código a seguir à classe Program. Você precisará corrigir o caminho do seu
banco de dados Northwind no código:
static void Main(string[] args)
{
string myDocumentsPath =
Environment.GetFolderPath(
Environment.SpecialFolder.MyDocuments);
CopyDataToTextFile(myDocumentsPath
+ @"\CustomerList.txt");
DisplayTextFile(myDocumentsPath
+ @"\CustomerList.txt");
}
static private void CopyDataToTextFile(
string fileName)
{
try
{
// Altere a cadeia de conexão
// e acordo com seu sistema.
string connectionString =
@"Data Source=.\SQLEXPRESS;" +
@"AttachDbFilename=" +
@"c:\SqlSampleDB\NORTHWND.MDF;" +
@"Integrated Security=True;" +
@"Connect Timeout=30;User Instance=True";
SqlConnection connection =
new SqlConnection(connectionString);
SqlCommand command =
connection.CreateCommand();
166 | lição 6

command.CommandText =
"SELECT CustomerId, CompanyName,"
+ "ContactName, Phone FROM Customers";
using (connection)
{
connection.Open();
SqlDataReader reader =
command.ExecuteReader();
using (StreamWriter sw =
new StreamWriter(fileName))
{
while (reader.Read())
{
string customerRow =
String.Format("{0}, {1}, {2}, {3}",
reader.GetValue(0),
reader.GetValue(1),
reader.GetValue(2),
reader.GetValue(3));
sw.WriteLine(customerRow);
}
}
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
static void DisplayTextFile(string fileName)
{
try
{
using (StreamReader sr =
new StreamReader(fileName))
{
string line;
while ((line = sr.ReadLine()) != null)
{
Console.WriteLine(line);
}
}
}
Noções básicas sobre bancos de dados | 167

catch (Exception ex)


{
Console.WriteLine(ex.Message);
}
}
3. Adicione as diretivas using a seguir ao código:
using System.Data.SqlClient;
using System.IO;
4. Compile e execute o programa. Examine a pasta Meus Documentos para o nome de
arquivo CustomerList.txt e verifique se os dados do cliente foram gravados. Verifique
também a saída na janela de console em relação ao conteúdo do arquivo.
O código deste exercício primeiro abre um novo objeto StreamWriter e chama seu método
WriteLine várias vezes para gravar texto em um arquivo de texto. Em seguida, ele cria um
objeto StreamReader para ler o texto do arquivo recém-criado usando o método ReadLine.
Quando não há nenhum dado para ler, o objeto ReadLine retorna um valor nulo. O código
usa esse valor para determinar quando será concluída a leitura do arquivo de texto.

Trabalhando com XML

A linguagem XML é um formato baseado em texto para representar dados


estruturados.

Em XML, você pode armazenar dados e metadados (informações sobre os dados que
estão sendo armazenados). Por exemplo, a linguagem XML a seguir representa os dados
de dois clientes:
<?xml version="1.0" encoding="utf-8"?>
<!--Customer List-->
<Customers>
<Customer Id="ALFKI">
<CompanyName>Alfreds Futterkiste</CompanyName>
<Phone>030-0074321</Phone>
</Customer>
<Customer Id="EASTC">
<CompanyName>Eastern Connection</CompanyName>
<Phone>(171) 555-0297</Phone>
</Customer>
</Customers>
Mesmo sem saber nada sobre XML, você conseguirá compreender o conteúdo desse arquivo
apenas olhando para ele. A linguagem XML é composta por marcas (contidas dentro de
colchetes angulares) e dados. As marcas sempre aparecem em pares, com cada marca de
abertura acompanhada por uma marca de fechamento. Por exemplo, <Customers> é uma
marca de abertura e </Customers> é a marca de fechamento correspondente.
A primeira linha de um documento XML é a declaração XML:
<?xml version="1.0" encoding="utf-8"?>
As marcas XML que começam com <? são chamadas de instruções de processamento.
Essa instrução de processamento nos diz que o documento é um XML em conformidade
com as especificações da linguagem XML versão 1.0 e usa o conjunto de caracteres
UTF-8 para seus elementos de dados.
168 | lição 6

Uma marca de abertura e uma marca fechamento junto com seu conteúdo são chamados
de elemento. Por exemplo, a seguir é apresentado um único elemento XML do documento
acima:
<Phone>030-0074321</Phone>
Esse bit de código define um elemento com o nome Phone cujo valor é 030-0074321. Os
elementos podem ser aninhados, mas não podem se sobrepor. Por exemplo, a linguagem
XML a seguir é inválida devido à sobreposição entre os elementos CompanyName e
Phone:
<Customer Id="EASTC">
<CompanyName>Eastern Connection<Phone>
</Phone>(171) 555-0297</CompanyName>
</Customer>
</Customers>
Os documentos XML são hierárquicos por natureza. Cada documento XML contém um
único elemento raiz com todos os outros nós. Portanto, um documento XML pode ser
visualizado como uma árvore de nós.
Os elementos podem conter atributos. Um atributo é um determinado dado que descreve
um elemento em mais detalhes. Por exemplo:
<Customer Id="ALFKI">
Aqui, o elemento Customer inclui um atributo cujo nome é Id e cujo valor é ALFKI.
Finalmente, um documento XML pode conter comentários. Os comentários começam com
os caracteres <!-- e terminam com os caracteres -->.
A linguagem XML muitas vezes é mais complexa do que o que é discutido nesta seção.
No entanto, essas noções básicas são suficientes para você compreender a maioria dos
documentos XML que provavelmente desejará executar até começar a trabalhar com XML
de forma aprofundada.
Há várias maneiras de trabalhar com dados XML. As classes que trabalham com dados
XML são organizadas no namespace System.Xml. Esta parte da lição concentra-se nas
seguintes classes comumente usadas:
• XmlReader e XmlWriter: essas classes fornecem uma maneira rápida, sem
armazenamento em cache e somente de encaminhamento para ler ou gravar dados XML.
• XmlDocument: essa classe é uma representação na memória de dados XML e
permite a navegação e a edição do documento XML.
No exercício a seguir, você poderá usar a classe XmlReader para ler o nome de arquivo
XML Customers.xml de maneira sequencial e somente de encaminhamento.

LER DE UM ARQUIVO XML

PREPARE-SE. Para ler de um arquivo XML, faça o seguinte:


1. Crie um novo projeto de aplicativo de console denominado WorkingWithXmlReader.
2. Adicione o código a seguir ao método Main da classe Program:
using (XmlReader reader =
XmlReader.Create("Customers.xml"))
{
while (reader.Read())
{
Noções básicas sobre bancos de dados | 169

if (reader.IsStartElement())
{
switch (reader.Name)
{
case "CompanyName":
if (reader.Read())
{
Console.Write(
"Company Name: {0}, ",
reader.Value);
}
break;
case "Phone":
if (reader.Read())
{
Console.WriteLine(
"Phone: {0}", reader.Value);
}
break;
}
}
}
}
3. Em seguida, adicione a diretiva using a seguir ao programa:
using System.Xml;
4. Agora, adicione um novo arquivo XML denominado Customers.xml ao projeto.
Verifique se o arquivo xml contém estes dados:
<?xml version="1.0" encoding="utf-8"?>
<!--Customer List-->
<Customers>
<Customer Id="ALFKI">
<CompanyName>Alfreds Futterkiste</CompanyName>
<Phone>030-0074321</Phone>
</Customer>
<Customer Id="EASTC">
<CompanyName>Eastern Connection</CompanyName>
<Phone>(171) 555-0297</Phone>
</Customer>
</Customers>
Compile o programa. Copie o arquivo Customers.xml para a pasta do programa
executável. Execute o programa. Você deverá ver uma lista de todos os nomes de
empresa e números de telefone.
170 | lição 6

O código neste exercício primeiro cria uma nova instância de XmlReader usando o método
XmlReader.Create. Isso gerará uma exceção se o arquivo não for encontrado. O programa
será encerrado quando o método XmlReader.Read não tiver nada para ler. Você pode usar
propriedades, como Name e Value, para acessar várias partes da linguagem XML.

Trabalhando com DataSet

Um DataSet é uma representação na memória de dados relacionais.

Um DataSet é uma representação na memória de dados relacionais. Da mesma forma


que um banco de dados, um DataSet pode ter tabelas, relações e restrições de integridade
dos dados, como restrições exclusivas ou restrições de chave estrangeira. Um DataSet é
geralmente criado recuperando dados de uma fonte de dados, como um banco de dados.
Após criar um DataSet, você poderá trabalhar com todos os dados no DataSet, mesmo
quando o link para a fonte de dados de origem estiver temporariamente indisponível.
Quando houver alterações nos dados, apenas a cópia dos dados na memória será atualizada.
A conexão com a fonte de dados somente será necessária no momento de atualizar a fonte
de dados com as alterações do DataSet. O DataSet é muito útil para criar aplicativos
desconectados. Os aplicativos desconectados são aqueles que podem continuar funcionando
sem uma conexão constante com os recursos de rede, como os bancos de dados.
Todas as classes relacionadas ao DataSet fazem parte do namespace System.Data. Um
objeto DataSet é criado usando a classe DataSet. O DataSet consiste em uma coleção
de objetos DataTable. Um DataTable é exatamente como uma tabela de banco de dados
relacional. Um objeto DataTable tem uma coleção de objetos DataColumn que representam
as colunas da tabela. As linhas no DataTable são representadas pela coleção DataRow.
O DataAdapter atua como uma ponte entre a fonte de dados e o DataSet. O DataAdapter
armazena a conexão de dados e os comandos de dados necessários para se conectar à
fonte de dados. O DataAdapter também fornece comandos para recuperar dados da fonte
de dados e comandos para atualizar a fonte de dados com alterações.
O .NET Framework fornece três classes DataAdapter para funcionarem com diferentes
tipos de fontes de dados:
• A classe OdbcDataAdapter é usada para funcionar com fontes de dados ODBC. A
classe OdbcDataAdapter faz parte do namespace System.Data.Odbc.
• A classe OleDbDataAdapter é usada para funcionar com fontes de dados OLEDB. A
classe OleDbDataAdapter faz parte do namespace System.Data.OleDb.
• A classe SqlDataAdapter é usada para funcionar com bancos de dados do SQL
Server. A classe SQLDataAdapter faz parte do namespace System.Data.SqlClient.

Você também pode se conectar a um banco de dados do SQL Server usando as classes
OdbcAdapter e OleDbAdapter. No entanto, a classe SQLDataAdapter é otimizada
*
TOME NOTA
para o SQL Server. Portanto, quando se trabalha com o SQL Server, é preferível usar a
classe SQLDataAdapter.

Em um aplicativo típico que cria e atualiza um DataSet, você precisará executar as


seguintes etapas:
1. Compile e preencha cada DataTable no DataSet com dados da fonte de dados usando
um DataAdapter.
Noções básicas sobre bancos de dados | 171

2. Altere os dados nos objetos DataTable individuais, adicionando, atualizando ou


excluindo objetos DataRow.
3. Invoque o método AcceptChanges no dataset. Esse método é conectado às fontes de
dados originais e atualiza-as com todas as alterações feitas no DataSet desde que ele
foi carregado ou desde a última vez que AcceptChanges foi chamado. Se preferir,
você poderá chamar o método RejectChanges para cancelar todas as alterações feitas
no DataSet desde que ele foi carregado ou desde a última vez que AcceptChanges foi
chamado.
No exercício a seguir, você usará as classes discutidas até agora para ler dados do banco
de dados Northwind do SQL Server em um DataSet e, em seguida, iterar na tabela
Customer para exibir os números de pedido de cada cliente.

LER DE UM OBJETO DATASET NA MEMÓRIA

PREPARE-SE. Para ler de um objeto DataSet na memória, faça o seguinte:


1. Crie um novo projeto de aplicativo de console denominado WorkingWithDataSet.
2. Substitua o código na classe Program pelo código a seguir. Certifique-se de alterar a
cadeia de caracteres de conexão para corresponder ao caminho local do arquivo de
banco de dados no seu computador:
static void Main(string[] args)
{
WorkingWithDataSet();
}
static void WorkingWithDataSet()
{
string cString = @"Data Source=.\SQLEXPRESS;"
+ @"AttachDbFilename=B:\SqlSampleDB\NORTHWND.MDF;"
+ "Integrated Security=True;"
+ "Connect Timeout=30;User Instance=True";
SqlConnection northwindConnection =
new SqlConnection(cString);
string customerCommandText =
"SELECT * FROM Customers";
SqlDataAdapter customerAdapter =
new SqlDataAdapter(
customerCommandText, northwindConnection);
string ordersCommandText =
"SELECT * FROM Orders";
SqlDataAdapter ordersAdapter =
new SqlDataAdapter(
ordersCommandText, northwindConnection);
172 | lição 6

DataSet customerOrders = new DataSet();


customerAdapter.Fill(
customerOrders, "Customers");
ordersAdapter.Fill(
customerOrders, "Orders");
DataRelation relation =
customerOrders.Relations.Add("CustomerOrders",
customerOrders.Tables["Customers"]
.Columns["CustomerID"],
customerOrders.Tables["Orders"]
.Columns["CustomerID"]);
foreach (DataRow customerRow in
customerOrders.Tables["Customers"].Rows)
{
Console.WriteLine(customerRow["CustomerID"]);
foreach (DataRow orderRow in
customerRow.GetChildRows(relation))
Console.WriteLine("\t" +
orderRow["OrderID"]);
}
Console.WriteLine(
“Pressione qualquer tecla para continuar. . .");
Console.ReadKey();
}
3. Adicione a diretiva using a seguir ao programa:
using System.Data;
using System.Data.SqlClient;
4. Selecione Projeto > Definir como Projeto de Inicialização para definir o projeto como
o projeto de inicialização da solução.
5. Selecione Depurar > Iniciar Depuração (ou pressione F5) para executar o programa.
Observe que a janela de console lista todos os clientes da tabela Customers. Cada
PRONTO PARA CustomerID é seguido pelo OrderID correspondente a esse cliente.
CERTIFICAÇÃO
Você compreende os O código nesse exercício primeiro cria um DataSet com dois objetos DataTable,
vários métodos de Customers e Orders. O DataSet também cria um objeto DataRelation que estabelece
conexão de banco de o relacionamento entre as tabelas Customers e Orders na coluna CustomerID. Esse
dados? relacionamento permite que você chame o método GetChildRow em uma linha customer
6,3 para recuperar as linhas order correspondentes a cada cliente.

Um DataSet pode ler e gravar dados como documentos XML. Para gravar dados como
*
TOME NOTA XML, use o método WriteXml da classe DataSet. Para ler dados do documento XML,
use o método ReadXml da classe DataSet.
Noções básicas sobre bancos de dados | 173

RESUMO DE HABILIDADES

Nesta lição, você aprendeu que:


• Um banco de dados relacional organiza as informações em tabelas. Uma tabela
é uma lista de linhas e colunas.
• Um design de banco de dados relacional é o processo que determina a estrutura de
banco de dados relacional adequada para atender aos requisitos comerciais.
• Os diagramas de relacionamento entre entidades são usados para modelar as
entidades, seus atributos e os relacionamentos entre as entidades. Esses diagramas
de relacionamento entre entidades podem ajudá-lo a determinar quais dados
precisam ser armazenados em um banco de dados.
• O processo de normalização de dados garante que um design de banco de dados não
tenha problemas que possam levar à perda da integridade dos dados. A maioria dos
problemas de design podem ser resolvidos, garantindo que as tabelas atendam aos
requisitos da terceira forma normal.
• A linguagem SQL linguagem fornece instruções, como SELECT, INSERT, UPDATE
e DELETE, para trabalharem com dados relacionais.
• Um procedimento armazenado é um conjunto de instruções SQL que são
armazenadas em um banco de dados. Os procedimentos armazenados podem ser
usados por vários aplicativos.
• As classes XmlReader e XmlWriter fornecem uma maneira rápida, sem
armazenamento em cache e somente de encaminhamento para ler ou gravar dados
XML. A classe XmlDocument é uma representação na memória de dados XML
e permite a navegação e a edição do documento XML.
• A classe DataSet é uma representação na memória de dados relacionais.
A classe DataAdapter funciona como ponte entre a fonte de dados e o DataSet.
O DataAdapter armazena a conexão de dados e os comandos de dados necessários
para se conectar à fonte de dados.

■ Avaliação de conhecimento
Preencha as lacunas
Complete as sentenças a seguir com a(s) palavra(s) correta(s) nas lacunas fornecidas.
1. Para que uma tabela esteja na _______________, nenhuma das colunas deve ter
vários valores na mesma linha de dados.
2. A _______________ exige que todas as colunas que não são de chave sejam
funcionalmente dependentes de toda a chave primária.
3. A _______________ exige que não haja dependência funcional entre os atributos que
não são de chave.
4. Os blocos de construção básicos para um diagrama de relacionamento entre entidades
são _______________, _______________ e _______________.
5. A cláusula _______________ em uma instrução SELECT avalia cada linha para uma
condição e decide se deve incluí-la no conjunto de resultados.
6. O objeto usado com a instrução using deve implementar a interface
_______________.
7. A instrução _______________ de T-SQL pode ser usada para criar um procedimento
armazenado.
174 | lição 6

8. No processo de _______________, você aplica um conjunto de regras para garantir


que seu design de banco de dados ajude na integridade dos dados e para facilitar a
manutenção no futuro.
9. Você encontra classes para trabalhar com streams e repositórios de backup no namespace
_______________.
10. O formato _______________ é um formato hierárquico de representação de dados.

Múltipla escolha
Assinale a letra que corresponde à melhor resposta.
1. Seu aplicativo precisa armazenar a imagem do produto em um arquivo de disco. Você
gostaria de minimizar o tamanho deste arquivo de disco. Qual dos seguintes objetos você
deve usar para escrever o arquivo?
a. FileStream
b. StreamWriter
c. BinaryWriter
d. XmlWriter
2. Seu programa em C# precisa retornar o número total de clientes em um banco de dados.
O programa será usado várias vezes ao dia. Qual é o caminho mais rápido para retornar
essas informações de seu programa?
a. Escrever uma consulta SQL e use o método SqlCommand.ExecuteScalar para executar
a consulta.
b. Criar um procedimento armazenado para retornar o número total de clientes e, em
seguida, usar o método SqlCommand.ExecuteScalar para executar o procedimento
armazenado.
c. Escrever uma consulta SQL e use o método SqlDataAdapter.Fill para executar a con-
sulta.
d. Criar um procedimento armazenado para retornar o número total de clientes e, em
seguida, usar o método SqlDataAdapter.Fill para executar o procedimento armazenado.
3. Você precisa modificar os registros em uma tabela de produtos, marcando determinados
produtos como descontinuados. No entanto, você precisa fazer isso somente quando
UnitsInStock e UnitsOnOrder estiverem ambos zero. Qual das seguintes instruções SQL
você deve usar?
a. INSERT
b. SELECT
c. UPDATE
d. DELETE
4. Você precisa atualizar os campos da região para clientes no Japão. Você escreve a
seguinte instrução SQL UPDATE:
UPDATE Customers
SET Region = 'EastAsia'
Você testa a consulta em um banco de dados de teste e descobre que mais registros foram
afetados do que você esperava. Você precisa corrigir a instrução SQL. O que você deve fazer?
a. Adicione uma cláusula WHERE à instrução UPDATE.
b. Adicione uma cláusula SET adicional à instrução UPDATE.
c. Adicione uma cláusula GROUP BY à instrução UPDATE.
d. Adicione uma cláusula HAVING à instrução UPDATE.
5. Você está desenvolvendo um aplicativo que precisa recuperar uma lista de clientes de um
banco de dados do SQL Server. O aplicativo deve percorrer a lista sequencialmente uma
vez, processando o registro de cada cliente. Qual das seguintes classes você deve usar para
manter a lista de clientes a fim de alcançar o desempenho máximo?
a. DataSet
b. DataTable
c. DataView
d. SqlDataReader
Noções básicas sobre bancos de dados | 175

6. O aplicativo que você está desenvolvendo precisa ler dados de um arquivo simples
que inclua itens como, por exemplo, uma chave de inteiros de cinco dígitos, seguido
por um nome de cliente de 20 caracteres e dois campos de data e hora. Qual das
seguintes classes você deve usar?
a. FileStream
b. StreamReader
c. BinaryReader
d. DataReader
7. Você está desenvolvendo um aplicativo que precisará copiar dados de uma exibição
do SQL Server para um DataSet. Você dá ao objeto DataSet o nome de dsData. Qual
dos métodos a seguir você deve usar para copiar os dados?
a. Fill
b. InsertCommand
c. SelectCommand
d. Update
8. Você está desenvolvendo um aplicativo que gerencia os clientes e seus pedidos.
Qual das seguintes situações não é um bom candidato para implementação com
procedimentos armazenados em seu aplicativo?
a. Recuperar a lista de todos os clientes no banco de dados
b. Recuperar a lista de todos os pedidos para clientes específicos
c. Inserir um novo pedido na tabela Orders
d. Consulta ad hoc pelo administrador de banco de dados
9. Seu aplicativo conecta-se a um banco de dados do SQL Server que contém uma
tabela chamada Employees com as seguintes colunas:
EmployeeID (int, identity)
EmployeeType (char(1))
EmployeeDate (datetime)
Você precisa escrever uma consulta que exclui todas as linhas da tabela onde o
valor de EmployeeType é C ou T. Você não quer excluir todas as outras linhas. Que
instrução você deve usar?
a. DELETE FROM Employees
WHERE EmployeeType LIKE '[CT]'
b. DELETE FROM Employees
WHERE EmployeeType LIKE '[C-T]'
c. DELETE FROM Employees
WHERE EmployeeType LIKE 'C' OR 'T'
d. DELETE * FROM Employees
WHERE EmployeeType IN ('C', 'T')
10. Seu aplicativo inclui um objeto SqlDataAdapter denominado sqlDataAdapter que
se conecta à tabela Employees. Com base neste SQLDataAdapter, seu aplicativo
também inclui um objeto DataSet dsEmployees. Qual a linha de código você deve
usar para carregar os dados do banco de dados no objeto DataSet?
a. dsEmployees = sqlDataAdapter.Fill("Employees");
b. sqlDataAdapter.Fill("dsEmployees", "Employees");
c. sqlDataAdapter.Fill(dsEmployees);
d. sqlDataAdapter.Fill(dsEmployees, "Employees");
176 | lição 6

■ Avaliação da competência
Cenário 6-1: criando um diagrama de relacionamento de entidades
Uma empresa tem um número de funcionários, e cada empregado pode ser atribuído a um
ou mais projetos. Além disso, cada projeto pode ter um ou mais empregados trabalhando
nele. Desenhe um diagrama de relacionamento de entidade para esta situação.

Cenário 6-2: criando e executando um procedimento armazenado


Muitas vezes, você precisa gerar uma lista de clientes de um determinado país. Portanto,
você decide criar um procedimento armazenado que aceita o nome do país como um
parâmetro e retorna todos os clientes desse país. Como você faria isto?

■ Avaliação de proficiência
Cenário 6-3: normalizando tabelas
Você está convertendo um diagrama de relacionamento de entidades em tabelas. Você
inventou o seguinte design de tabela:

Books

BookId BookName CategoryId CategoryName


1 Cooking Light 1001 Cooking
2 Prophecy 1002 Mystery & Thriller
3 Shift 1003 Business
4 The Confession 1002 Mystery & Thriller

Você precisa aplicar as regras de normalização para garantir a integridade dos dados.
Como você poderá garantir que a tabela Books esteja na terceira forma normal?

Cenário 6-4: criando e manipulando eventos


Você está trabalhando em um aplicativo que requer que você salve as informações do
cliente da tabela Customers do banco de dados Northwind em um arquivo XML. Esse
arquivo XML será usado para várias tarefas de integração dos dados. Você precisa
ter certeza de que o nó raiz do XML seja chamado Customers. O nó raiz terá um nó
Customer para cada cliente na tabela Customers. Como você deve realizar essa tarefa?
Apêndice A
Conceitos básicos do desenvolvi­mento
de software, exame 98-361
Domínio do objetivo Número de habilidade Número da lição
Noções básicas sobre programação básica
Compreender o armazenamento do computador e os tipos de dados. 1.1 1, 2
Entender as estruturas de decisão em computadores. 1.2 1
Identificar o método adequado para lidar com repetições. 1.3 1
Entender o tratamento de erros. 1.4 1
Noções básicas sobre programação orientada a objeto
Compreender os conceitos básicos de classes. 2.1 2
Compreender a herança. 2.2 2
Compreender o polimorfismo. 2.3 2
Compreender o encapsulamento. 2.4 2
Noções básicas sobre o desenvolvimento de software em geral.
Compreender o gerenciamento do ciclo de vida do aplicativo. 3.1 3
Interpretar as especificações de aplicativos. 3.2
Compreender algoritmos e estruturas de dados. 3.3 3
Noções básicas sobre aplicativos Web
Compreender o desenvolvimento de páginas da Web. 4.1 4
Compreender o desenvolvimento de aplicativos Web do Microsoft ASP.NET. 4.2 4
Compreender a hospedagem Web. 4.3 4
Compreender os serviços Web. 4.4 4
Noções básicas sobre aplicativos da área de trabalho
Entender os aplicativos de formulários do Windows. 5.1 5
Entender aplicativos de console. 5.2 5
Entender os serviços Windows. 5.3 5
Noções básicas sobre bancos de dados
Compreender os métodos de consulta de banco de dados relacional. 6.1 6
Compreender os métodos de consulta de banco de dados. 6.2 6
Compreender os métodos de conexão de banco de dados. 6.3 6

177
Índice

@@IDENTITY, 163 Arquivos binários, 165


<?, 167 Arquivos de texto, lendo e gravando de, 165–167
Arquivos simples
A arquivo de texto, ler de e gravar em, 165–167
Acessador set, 36 definição, 164
Acessadores, 36 ASP.NET
Ajax, 93 ciclo de vida da página, 96–99
Algoritmo de classificação classe Page, 96
BubbleSort, 76–78 classe Page, eventos, execução de, 98–99
QuickSort, 79–81 desenvolvimento de aplicativos, 95–104
Algoritmo. Consulte também Algoritmo de classificação Diretiva @Page, 99
definição, 2 gerenciamento de estado, 99–104
fluxogramas, 2–3 infraestrutura, 95
tabelas de decisão, 3–4 manipuladores de eventos, 97
ALM (gerenciamento do ciclo de vida do aplicativo) postback, 96, 97
análise de requisitos, 66–67 processo de resposta/solicitação HTTP, 95
desenvolvimento de software, 67 processo de solicitação de página, 96
gerenciamento de lançamento, 68 Assinatura, 34
processo de design, 67 Atributo WebMethod, 101
teste de software, 68–70. Consulte também Teste Atributo WebService, 101
Alocação de memória, 45–47 Atributo, 168
Anomalia de atualização, 147
Anomalia de exclusão, 147 B
Anomalia de inserção, 146 Banco de dados, 143
Aplicativos C# Bancos de dados relacionais. Consulte também Bancos de
constantes, 8 dados, relacional
consultas, executando de, 153–155 Bancos de dados SQL Server
escrevendo, 5 conectando a, 150–152
estrutura, 6–8 consultas, aplicativos C#, executando de, 153–155
estruturas de controle, 17–22 consultas, Visual Studio, executando de, 152–153
instrução using, 164 Bancos de dados, relacionais
matrizes, 9–10 conceitos, 143
métodos, 11 definição, 142
natureza imperativa, 150 design, 144
operadores, 10–11 diagramas de relacionamento de entidades, 144–146
procedimentos armazenados, executando de, 161–164 normalização de dados, 146–149
tipos de dados, 8–9 tabelas, 143
variáveis, 8 Bloco finally, 25
Aplicativos de console, 129–131 Bloco switch, 15
Aplicativos desconectados, 170 Bloco try, 25
Aplicativos do Windows Forms BubbleSort, 76–78
criando, 121-123
definição, 120 C
herança visual, 123–126 Cadeias de caracteres de consulta, 100
MDI (interface de vários documentos), 126–129 Campos ocultos, 100
modelo de evento, 123 Chave primária, 144
Aplicativos Web, implantando, 106 Classe Base
Aplicativos, área de trabalho herança, 48–49
baseado em console, 129-131 palavra-chave new, 55–56
serviço Windows, 131–137 palavra-chave override, 55–56
Windows Forms, 120–129
179
180 | Índice

Classe DataAdapter, 170 E


Classe DataSet, 170, 172 elemento <link>, 91
Classe derivada elemento <script>, 93
herança, 48–50 Elemento, 168
palavra-chave new, 55–56 Encapsulamento, 33, 47–48
palavra-chave override, 55–56 Enfileiramento, 73
Classe EventArgs, 41 ERD (diagramas de relacionamento entre entidades)
Classe HttpCookie, 100 atributo, 144
Classe selada, 50, 51 banco de dados, relacional, mapeamento para, 145–146
Classe ServiceInstaller, 135 definição, 144
Classe ServiceProcessorInstaller, 135 entidade, 144
Classe relação, 145
abstrato, criando, 50–51 Espiada, 73, 74
criando, 33-34 Estado da sessão, 101–104. Consulte também Gerenciamento
definição, 7, 33 de estado
derivado, criando, 49 Estado do aplicativo, 101. Consulte também Gerenciamento
modificador de acesso, 34 de estado
Classes abstratas Estruturas de dados
criando, 50-51 filas, 72–73
definição, 50 listas vinculadas, 74–76
Código binário, 4 matrizes, 70–72
CompareTo, 57 pilhas, 73–74
Console, 129 Estruturas de decisão
Constantes, 8 definição, 11
Construtores, 35 instrução if, 11–13
Consultas, SQL. Consulte também Linguagem SQL instrução if-else, 13–15
Aplicativo C#, executando de, 153–154 instrução switch, 15–17
Visual Studio, executando de, 152–153 Estruturas de repetição
Contém, 73, 74 loop do-while, 19–20
Conversão loop for, 20–21
definição, 52 loop foreach, 21–22
entre tipos, 52–53 loop while, 17–19
operador as, 53 método recursivo, 23
operador is, 53 recursão, 22
Cookies, 100 Eventos
CRIAR PROCEDIMENTO, 159–160 Classe Page execução de, 98–99
CSS (folhas de estilos em cascata) definição, 40, 121
arquivo, vinculando a um arquivo HTML, 90–91 publicar e inscrever-se, 41–42
definição, 88 Exceções
projetando, 89 definição, 24
instrução try-catch-finally, 25-26
D manipulação, 24–25
DataSet Expressão de término, 19
definição, 170
objeto, leitura de, 171–172 F
DBMS (sistema de gerenciamento de banco de dados), 143 Filas
Delegado EventHandler, 41 definição, 72
Delegados, 40, 123 desempenho e uso, 73
Dependência funcional, 148 operadores, 73
Desenvolvimento de páginas da Web representação interna, 72
CSS (folhas de estilos em cascata), 88–92 Fluxogramas, 2–3
HTML, 86–88 FTP, 106
JavaScript, 92–94 Gerenciamento de estado
programação, do lado do cliente versus do lado do servidor, cadeias de caracteres de consulta, 100
94–95 campos ocultos, 100
Diretiva @Page, 99 cookies, 100
Diretiva using, 7 definição, 99
Diretório virtual, 105–106 do lado do servidor, 101
estado da sessão, 101–104
Índice | 181

estado do aplicativo, 101 em arquivos externos, vantagens, 94


lado do cliente, 100 trabalhando com, 93–94
ViewState, 100
Gerenciamento de lançamento, 68 L
Linguagem de alto nível, 4
H Linguagem SQL
Herança visual, 123–126 funções de agregação, 157
Herança instrução DELETE, 150, 159
classe abstrata, 50–51 instrução INSERT, 150, 158–159
classe base, 48 instrução SELECT, 150, 155–157
classe derivada, 48–50 instrução UPDATE, 150, 157–158
classe selada, 50, 51 instruções ad-hoc, 150
conversão entre tipos, 52–53 natureza declarativa, 149–150
da classe object, 51–52 Linguagem XML. Consulte XML
definição, 48 Listas vinculadas
operador as, 53 definição, 74
operador is, 53 desempenho e uso, 76
Hospedagem Web operações, 75–76
Aplicativos Web, implantando, 106 representação interna, 74–75
definição, 104 Livre
diretórios virtuais, criando, 105–106 Acessador get, 36
IIS (Serviços de Informações da Internet), 104–105 Loop do-while, 19
Sites da Web, criando, 104 Loop for, 20
HTML (Hypertext Markup Language) Loop foreach, 21
cabeçalho e corpo, 87 Loop while
definição, 86 definição, 17
documento, criando, 87–88 partes, 19
finalidade de, 86–87
tags, 87 M
HTTP (Hypertext Transfer Protocol), 86, 95, 107 Manipuladores de eventos, 97
Matrizes
I acesso, 71
IComparable, 56–58 alocação, 71
IIS (Serviços de Informações da Internet), 104–106 aplicativos C#, 9–10
Inicializador, 19 definição, 9, 70
Instalador, 135 desempenho e uso, 72
Instância, 33 operações, 71
Instrução Case, 15 representação interna, 71
Instrução DELETE, 150, 159 MDI (interface de vários documentos), 126–129
Instrução if, 11 Membros estáticos
Instrução if-else, 13 criando, 43-44
Instrução INSERT, 150, 158–159 definição, 43
Instrução padrão, 15 palavra-chave this, 44
Instrução SELECT, 150, 155–157 Memória de pilha de chamada, 47
Instrução switch, 15 Memória heap, 47
Instrução try-catch-finally, 25–26 Método Main, 7–8, 11
Instrução UPDATE, 150, 157–158 Método recursivo, 23
Instrução using, 164 Métodos de conexão de banco de dados
Instruções de processamento, 167 arquivos simples, 164–167
Integridade do banco de dados, 144 DataSet, 170–173
Interfaces XML, 167–170
definição, 56 Métodos de consulta de banco de dados. Consulte Linguagem SQL
icomparable, 56–58 Métodos
Internet, versus a Web, 86 assinaturas, 34
definição, 11
J InitFields, 34–35
JavaScript instruções return, 34, 35
Ajax, 93 objetos, 34–35
definição, 92 Modificadores de acesso, 34, 37, 48
182 | Índice

N parametrizado, criando, 160–161


Namespaces, 42–43 parametrizado, executando de C#, 161–164
Nome de classe totalmente qualificado, 7 Visual Studio, criando de, 160
Normalização de dados Processo de design, 67
definição, 146 Programa, 4
primeira forma normal, 147–148 Programação do lado do cliente, 94–95
segunda forma normal, 148 Programação do lado do servidor, 94–95
terceira forma normal, 149 Programação orientada a objeto
encapsulamento, 47–48
O herança, 48–53
Objetos interfaces, 56–58
classes, criando, 33–34 objetos, 33–44
construtores, 35 polimorfismo, 53–56
conversão entre tipos, 52–53 valores e referências, 44–47
criando, 35-36 Propriedade Account, 135
DataSet na memória, lendo de, 171 Propriedade Application, 101
definição, 33, 35 Propriedade Namespace, 110
delegados, 40 Propriedade QueryString, 100
eventos, 40–42 Propriedade StartType, 135
membros estáticos, 43–44 Propriedades autoimplementadas, 37–38
métodos, 34–35 Propriedades
namespaces, 42–43 acessadores, 36
palavra-chave new, 35 autoimplementada, 37–38
palavra-chave this, 38–39 criando, 36-37
propriedades, autoimplementadas, 37–38 definição, 36
propriedades, criando, 36–37 somente gravação, 37
Operador +=, 42 somente leitura, 37
Operador As, 53 protocolo SOAP
Operador Is, 53 definição, 107
Operadores binários, 10 elementos, 108
Operadores ternários, 10 Push, 74
Operadores unários, 10
Operadores Q
definição, 10 QuickSort, 79–81
precedência em C#, 10
+=, 42 R
Recursão, 22
P Relação muitos-para-muitos, 145
Palavra-chave new, 35, 55–56 Relação um-para-muitos, 144, 145
Palavra-chave override, 55–56 Relação um-para-um, 145
Palavra-chave static, 43 Remoção da fila, 73
Palavra-chave this, 38–39, 44
Palavra-chave value, 37 S
Parâmetros de linha de comando, 129 Segunda forma normal, 148
Pensamento orientado a objeto, 33 Serviços Web
Pilhas aplicativo cliente, acessando de, 112–114
desempenho e uso, 74 Atributo WebMethod, 110
operações, 74 criando, 108-110
representação interna, 73–74 definição, 107
Polimorfismo SOAP, 107–108
definição, 53 teste, 110–112
usando, 54–55 Serviços Windows
Pop, 74 criando, 132-134
Postback, 96, 97 definição, 131
Primeira forma normal, 147–148 exemplos de, 131
Procedimentos armazenados parametrizados, 160–164 instalador, adicionando a, 134–135
Procedimentos armazenados instalando, 135–136
criando e executando, 159–160 trabalhando com, 136–137
definição, 159 sinal &, 128
Índice | 183

Sistema de número binário, 4 U


Sites da Web, 104–105 URL (Uniform Resource Locator), 86
SQL. Consulte Linguagem SQL
Structs, 44–45 V
Variáveis, 8
T ViewState, 100
Tabelas de decisão, 3–4 Visual Studio
Tabelas, 143, 146–149 consultas, executando de, 152–153
tag <html>, 87 Designer de consultas, 153
tag <img>, 87 Instalador de serviço Windows, adicionando, 134–135
Terceira forma normal, 149 Modelo de serviço Windows, 132–134
Teste caixa branca, 69 Serviço Windows, instalando, 135–136
Teste caixa preta, 69
Teste de aceitação, 70 W
Teste de integração, 69–70 Windows Installer, 106
Teste de loop, 19 World Wild Web, 86
Teste de regressão, 70 WSDL (Web Service Definition Language), 108
Teste de sistema, 70
Teste de software. Consulte Teste
X
Teste de unidade, 69
xcopy, 106
Teste
XML
aceitação, 70
arquivos, lendo de, 168–170
caixa branca, 69
atributos, 168
caixa preta, 69
definição, 167
integração, 69–70
elementos, 168
métodos, 69
tags, 167
níveis, 69–70
XmlDocument, 168
regressão, 70
XmlReader, 168
serviços Web, 110–112
XmlWriter, 168
sistema, 70
unidade, 69
Tipos de dados, 8–9
Tipos de referência, 44–45, 46–47
Tipos de valor, 44, 45, 46
T-SQL. Consulte Linguagem SQL
Observações
Observações
Observações
Observações
Observações
Observações
Observações
Observações
Observações
Observações

Você também pode gostar