[ ittrainning ] - microsoft visual c# parte i
TRANSCRIPT
Microsoft Visual C#
1
1. A LINGUAGEM DE PROGRAMAÇÃO COM MICROSOFT .NET ................. 6
a. Introdução ao .NET e ao Framework .NET ............................................... 6
b. Execução multiplataforma. .................................................................... 6
c. Suporte multilinha. .............................................................................. 7
d. Padrões de desenvolvimento C# ............................................................ 8
e. Endentação de código ........................................................................... 8
f. Comentários ........................................................................................ 9
g. Comentários de classes e métodos ....................................................... 10
h. Declarações ...................................................................................... 10
i. Criando um Projeto de Aplicação para Windows ..................................... 15
2. ENTENDENDO OS FUNDAMENTOS DA LINGUAGEM C# ..................... 23
a. Fundamentos .................................................................................... 23
b. Usando tipos predefinidos no C# .......................................................... 24
c. Os delimitadores de bloco { } .............................................................. 26
d. Outras declarações condicionais ........................................................... 26
e. Exercícios ......................................................................................... 42
3. CRIANDO OBJETOS EM C# .............................................................. 42
a. Classes Abstratas, classes Seladas e Interfaces ..................................... 42
b. Introdução ........................................................................................ 42
c. O que é uma classe abstrata? (Abstract Class) ...................................... 43
d. O que é uma Interface? (Interface) ...................................................... 43
e. Classes Abstratas X Interfaces ............................................................. 44
f. O que é uma classe selada? (Sealed Class) ........................................... 44
g. Classes Abtratas x Interfaces .............................................................. 45
Microsoft Visual C#
2
h. Declarando métodos ........................................................................... 46
i. Moderadores de acesso ....................................................................... 46
j. Estrutura dos métodos ....................................................................... 47
k. Usando Construtores de Instâncias ...................................................... 48
4. TÉCNICAS DE PROGRAMAÇÃO ORIENTADA A OBJETO EM C# .......... 51
a. Classes e Objetos .............................................................................. 51
b. Criando Objetos ................................................................................. 52
c. Usando Herança ................................................................................ 55
d. Polimorfismo ..................................................................................... 56
e. Exercícios ......................................................................................... 58
5. CRIANDO UMA APLICAÇÃO WEB ..................................................... 58
a. Criando um formulário para aplicações Web .......................................... 58
b. Criando uma Master page ................................................................... 59
c. Utilizando uma Mater Page .................................................................. 59
d. Trabalhando com uma Master Page ...................................................... 61
e. Alterando o Título das páginas de conteúdo ........................................... 63
f. Master Pages aninhadas ..................................................................... 64
g. Criando Master Page .......................................................................... 65
h. Acessando dados através do formulário de aplicações Web ..................... 70
i. Modos de Configuração ....................................................................... 71
j. Utilizando a Sessão ............................................................................ 73
k. Exercícios ......................................................................................... 77
6. PROGRAMAÇÃO EM CAMADAS COM C# ............................................ 77
a. Criando a infra-estrutura de Banco de dados ......................................... 80
b. Criando a tabela de Clientes ................................................................ 82
c. Camada de Acesso a Dados ................................................................. 93
Microsoft Visual C#
3
d. Implementar as classes da Camada DAL (Data Access Layer). ............... 108
e. BLL – Camada de Regras de Negócio. ................................................. 133
f. Criando a interface com o usuário – Desktop application ....................... 145
g. User Interface – Formulário de Produtos ............................................. 168
h. User Interface – Formulário de Vendas ............................................... 177
i. User Interface – Formulário de Produtos em Falta ................................ 182
j. Testando as Regras de Negócio ......................................................... 187
k. Estrutura de Arquivos ....................................................................... 188
l. Vantagens do modelo de desenvolvimento em Camadas ....................... 189
7. USANDO ADO.NET PARA ACESSO A DADOS ................................... 190
a. Arquitetura ADO.NET ........................................................................ 190
b. A arquitetura ADO .NET ( System.Data ) ............................................. 190
c. System.Data ................................................................................... 191
d. DataSet .......................................................................................... 191
e. DataTable ....................................................................................... 192
f. DataRow ......................................................................................... 193
g. DataRelation ................................................................................... 193
h. System.Data.OleDB.......................................................................... 194
i. System.Data.SQLClient ..................................................................... 194
j. Criando uma aplicação usando ADO.NET e SQLServer Express .............. 194
k. Introdução a Banco de Dados ............................................................ 195
l. Histórico do acesso aos Dados. .......................................................... 198
m. O que é ADO.NET? ........................................................................... 199
n. DataBind ........................................................................................ 204
o. Utilizando o DataReader ................................................................... 205
p. Utilizando o DataSet ......................................................................... 215
Microsoft Visual C#
4
8. INTRODUÇÃO AO ADO.NET ENTITY FRAMEWORK ......................... 231
a. Implementando CommandTimeOut em DataSets Tipados ..................... 236
b. Introdução ao LINQ para SQL ............................................................ 243
c. .NET Framework 3.5 ......................................................................... 244
d. O/R Mapping ................................................................................... 244
9. CRIANDO UM WINDOWS SERVICE ................................................ 247
a. Entendendo suas necessidades .......................................................... 247
b. Execução de processos periódicos ...................................................... 251
c. Interação entre camadas .................................................................. 253
d. Testando o Controller ....................................................................... 257
e. Finalmente criando o Windows Service ............................................... 260
10. USANDO XML WEB SERVICES DE UMA APLICAÇÃO C# .................. 264
a. Primeiros Passos no WebService ........................................................ 264
b. Implementando WebServices ............................................................ 265
c. Criando meu primeiro WebService ..................................................... 266
d. Consumindo o meu primeiro WebServiçe ............................................ 269
e. Criando um Web service de cálculo .................................................... 271
f. Consumindo Web Service em C-Sharp – Parte 2 ......................................... 274
11. USANDO SOAP HEADERS – SEGURANÇA EM WEBSERVICE ............ 280
12. NOVA IDE DO VISUAL STUDIO 2010 CRIADA COM WPF ................ 283
13. CONSIDERAÇÕES EXTRAS ............................................................. 288
a. Explorando o AJAX ........................................................................... 288
b. Documentação de Projeto ................................................................. 290
c. Utilizando UserControls ..................................................................... 294
d. Carregando dinamicamente na pagina ................................................ 300
Microsoft Visual C#
5
e. Class Libary .................................................................................... 300
f. Classe Exportador XLS ...................................................................... 302
g. Utilizando uma DLL (Class Libary) ...................................................... 303
h. Distribuindo sua Aplicação ................................................................ 306
i. Testes Unitários ............................................................................... 307
j. Criando Relatório com ReportViewer em ASP.NET ................................ 311
Microsoft Visual C#
6
1. A linguagem de programação com Microsoft .NET
a. Introdução ao .NET e ao Framework .NET
Para o desenvolvimento e execução de aplicações neste novo meio
tecnológico, Microsoft proporciona o conjunto de ferramentas conhecido como .NET
Framework SDK, que é possível baixá-lo gratuitamente de seu site web site
diretamente na Microsoft e inclui compiladores de linguagens como C#, Visual
Basic.NET, Managed C++ e JScript.NET especificamente desenhados para criar
aplicações para ele.
O coração da plataforma.NET é o CLR (Common Language Runtime), que é
uma aplicação similar a uma máquina virtual que se encarrega de providenciar a
execução das aplicações para ela escritas interagindo com uma Coleção de
Bibliotecas Unificadas, que juntas são o próprio framework. Esta CLR é capaz de
executar, atualmente, mais de vinte diferentes linguagens de programação,
interagindo entre si como se fossem uma única linguagem. Estas são:
APL; Boo; Fortran; Pascal; C++; Haskell; Perl; C#; Java; Python; COBOL;
Microsoft JScript®; RPG; Component Pascal; Mercury; Scheme; Curriculum;
Mondrian; SmallTalk; Eiffel; Oberon; Standard ML; Forth; Oz; Microsoft Visual
Basic®; Delphi; J#; Ruby; Lua.
São oferecidos a estas aplicações numerosos serviços que facilitam seu
desenvolvimento e manutenção que favorece sua confiança e segurança. Entre eles
os principais são:
Modelo de programação consistente e simples, completamente orientado a
objetos.
Eliminação do temido problema de compatibilidade entre DLLs conhecido
como "inferno das DLLs".
b. Execução multiplataforma.
Execução multilinguagem, é o principio de que é possível, em um programa
escrito em C#, fazer coisas como capturar uma exceção de um outro programa
escrito em Visual Basic.NET que por sua vez herda funcionalidades de um tipo de
exceção escrita em Cobol.NET.
Embora anteriormente houvéssemos dito que no .NET Framework somente
se oferecem compiladores de C#, MC++, VB.NET e JScript.NET, o certo é que a
parte Microsoft e terceiros estão desenvolvendo versões adaptadas a .NET de
Microsoft Visual C#
7
muitíssimas outras linguagens como APL, CAML, Cobol, Eiffel, Fortran, Haskell,
Java, Mercury, ML, Mondrian, Oberon, Oz, Pascal, Perl, Python, RPG, Scheme ou
Smalltalk.
c. Suporte multilinha.
Gestão do acesso a objetos remotos que permite o desenvolvimento de
aplicações distribuídas de maneira transparente ao encontro real de cada um dos
objetos utilizados nas mesmas.
Segurança avançada até o ponto de que é possível limitar as permissões de
execução do código em função de sua procedência (Internet, rede local, CD-ROM,
etc.), o usuário que o executa ou a empresa que o criou.
Interoperabilidade com código pré-existente, de forma que é possível utilizar
com facilidade qualquer livraria de funções ou objetos COM e COM+ criados com
anterioridade à aparição da plataforma .NET.
Adequação automática da eficiência das aplicações às características
concretas de cada máquina onde for executar.
Microsoft .NET é uma iniciativa da Microsoft em que visa uma plataforma
única para desenvolvimento e execução de sistemas e aplicações. Todo e qualquer
código gerado para .NET, pode ser executado em qualquer dispositivo ou
plataforma que possua um framework: a "Plataforma .NET" (.NET Framework).
Com idéia semelhante à plataforma Java, o programador deixa de escrever
código para um sistema ou dispositivo específico, e passa a escrever para a
plataforma .NET.
Arquitetura .NET, A plataforma .NET se baseia em um dos principios
utilizados na tecnologia Java (compiladores JIT), os programas desenvolvidos para
ela são duplo-compilados, ou seja são compilados duas vezes, uma na distribuição
e outra na execução.
Um programa é escrito em qualquer das mais de vinte linguagens de
programação disponível para a plataforma, o código fonte gerado pelo programador
é então compilado pela linguagem escolhida gerando um código intermediário em
uma linguagem chamada MSIL[1] (Microsoft Intermediate Language).
[1] O fato desta arquitetura utilizar a MSIL gera uma possibilidade pouco desejada entre os criadores de software que é a de fazer a "engenharia reversa", ou seja, a partir de um código compilado, recuperar o código original. Isto não é uma idéia agradável para as empresas que sobrevivem da venda de softwares produzidos nesta plataforma. Por causa disso, existem ferramentas que "ofuscam" este código MSIL, trocando nomes de variáveis, métodos, interfaces e etc para dificultar o trabalho de quem tentar uma engenharia reversa num código compilado MSIL.
Microsoft Visual C#
8
Este novo código fonte gera um arquivo chamado de Assembly, de acordo
com o tipo de projeto:
• EXE - Arquivos Executáveis, Programas.
• DLL - Biblioteca de Funções.
• ASPX - Página Web.
• ASMX - Web Service.
No momento da execução do programa ele é novamente compilado, desta
vez pelo JIT (Just In Time Compiler), de acordo com a utilização do programa, por
exemplo, temos um Web Site desenvolvido em ASP.NET[2], ao entrar pela primeira
vez em uma página o JIT irá compila-la, nas outras vezes que algum outro usuário
acessar esta página, ele usará esta compilação.
Também é possível, através de ferramentas específicas, "pré-compilar" o
código para que não se tenha o custo da compilação JIT durante a execução.
A Microsoft disponibiliza gratuitamente uma versão para download do Visual
Studio 2008 Express Edition através do link:
http://www.microsoft.com/express/vcsharp/Default.aspx
d. Padrões de desenvolvimento C#
O objetivo é elaborar uma padronização para o desenvolvimento em C#,
considerando os seguintes tópicos:
Padronização de nomenclatura usada na programação de métodos, objetos,
variáveis e constantes. Além disso, trata como deverá ser feita a documentação
dentro do código.
e. Organização de código
Alguns trechos de código podem ficar muito extensos e você deverá encarar
o dilema de quebrar a linha.
• Quebrar a linha após uma vírgula;
• Quebrar a linha após um operador;
• Alinhar a nova linha no inicio da expressão no mesmo nível da linha anterior.
[2] ASP.NET é a plataforma da Microsoft para o desenvolvimento de aplicações Web e é o sucessor da tecnologia ASP.
Microsoft Visual C#
9
Exemplo:
this .calcularDiferenca(intVal1, intVal2, intVal3,
intVal4, intVal5);
ou
intVal1 = intVal2 * (intVal4 - intVal5 + intVal6) +
4 * intVal7;
Outro fator importante é a utilização de espaços em branco para
endentação. Não use espaços em branco para endentação, use tabulação. Motivos:
Facilidade de incrementar e decrementar blocos de código através de atalhos de
teclas do editor de código.
f. Comentários
Utilizar as três barras “///” para comentários de classes e métodos. O motivo
é utilizar a funcionalidade do Visual Studio .NET de transformar comentários em
documentação de código. Entretanto, para comentários que não necessitam ser
publicados, existem algumas dicas. Para comentários que são importantes para
você ou outra pessoa ser orientada sobre a manutenção de um código fonte, tenha
atenção à forma de destacar o comentário.
Por exemplo, comentários com mais de uma linha poderiam ser assim:
/** Exemplo de comentário no código fonte para orientação do profissional que dará manutenção no código. **/
Para comentários de uma linha somente, o comentário deve ser uma espécie
de marcador de loops ou não deve ser aplicado. A questão é que como exposto em
linhas anteriores, os comentários devem chamar a atenção visando facilitar e
direcionar a manutenção. Somente justifica-se um comentário de uma linha quando
você necessita marcar dentro de um bloco de código o início de um nível de
endentação ou loop. Por exemplo:
//Verifica se somente uma string foi entrada if (args.Length == 1) Console .WriteLine(args[0]); else { ArgumentOutOfRangeException ex; ex = new ArgumentOutOfRangeException ( "Somente string" ); throw (ex);
}
Microsoft Visual C#
10
Outra boa aplicação para comentários de uma linha é a explicação de uma
declaração. Por exemplo:
int nivelStatus; //nível do status
int tamanhoStatus; //tamanho do status
g. Comentários de classes e métodos
Toda classe e método devem ser documentados. O padrão utilizado segue
abaixo:
///<summary> /// Retorna DirectoryEntry representando a unidade orga nizacional. ///</summary> ///<param name=”coopCentral”> Cooperativa Central. </param> ///<param name=”cooperativa”> Cooperativa Desejada. </param> ///<returns> /// Resultado da busca no Active Directory. ///</returns> /// exception cref=”ActiveDirectoryManager.ActiveDirectoryManager Exception”> /// Se não for encontrada a uniudade organizacional. ///</exception> ///<remarks> /// criado por: <nome> /// alterado por: <nome>
///</remarks>
h. Declarações
Variáveis privadas de classe
Utilizar a definição CamelCase (a primeira letra do identificador é minúscula
e a primeira letra de cada identificador subseqüente concatenado é maiúscula).
Exemplo:
String primeiroNome;
Variáveis locais
Utilizar a definição CamelCase.
Namespace
Utiliza-se o nome da empresa seguido pelo nome do projeto, camada de
negocio e o modulo que está sendo desenvolvido.
Exemplo:
namespace ItTrainig.NomeProjeto.CamadaNegocio.AccessControl {
Microsoft Visual C#
11
Interface
O nome de interface deve ser PascalCase (a primeira letra do identificador é
maiúscula e a primeira letra de cada identificador subseqüente concatenado é
maiúscula), e começar com o prefixo “I”, para indicar que o tipo é uma interface.
Exemplo:
IServiceProvider
Métodos
Utilizar a definição PascalCase.
Enumerações
Utilizar a definição PascalCase.
Eventos
Utilizar a definição PascalCase para o nome do evento.
Delegates
Utilizar o sufixo EventHandler para o nome do delegate associado ao evento.
Especificar dois parâmetros “sender” e “e”. O parâmetro “sender” representa o
objeto que disparou o evento e deve ser sempre do tipo Object, mesmo sendo
possível utilizar um tipo especifico. O estado associado com o evento é encapsulado
em uma instancia de um evento de classe chamado “e”.
Exemplos:
public delegate void MouseEventHandler ( object sender, MouseEventArgs e)
public event MouseEventHandlerClick;
Constantes
Nomes de constantes deverão ser todos maiúsculos com as palavras
separadas por um underscore.
Exemplo:
A2A_MAX
Exceções
O nome de uma classe de exceção deve utilizar a definição PascalCase, e
finalizar com a expressão Exception, para indicar que o tipo é uma exceção.
Exemplo:
ServiceProviderException
Microsoft Visual C#
12
Propriedades públicas
Utilizar a definição PascalCase para o nome de propriedades.
Exemplo:
public int PrinterStatus {
}
Windows Forms
Abaixo temos a lista de componentes e os prefixos:
Componente Prefixo Exemplo
Button btn btnExit
Char ch chxxx
CheckBox chk chkReadOnly
CheckedListBox clb clbOptions
ColorDialog cld cldText
ComboBox cbo cboEnglish
ContextMenu cmn cmnOpen
CrystalReportViewer rpt rptSales
DataGrid grd grdQueryResult
DomainUpDown upd updPages
ErrorProvider err errOpen
FontDialog ftd ftdText
Form frm frmEntry
GroupBox grp grpActions
HelpProvider hlp hlpOptions
HScrollBar hsb hsbMove
ImageList ils ilsAllIcons
Label lbl lblHelpMessage
LinkLabel lnk lnkEmail
ListBox lst lstPolicyCodes
ListView lvw lvwHeadings
RadioButton rad radType
TreeView tre treOrganization
VScrollBar vsb vsbMove
Microsoft Visual C#
13
Objeto de dados
Abaixo temos alguns componentes de comunicação de dados:
Variáveis
Veja a lista abaixo de tipos e prefixos:
Microsoft Visual C#
14
Web Forms
Veja a lista abaixo de tipos e prefixos:
Tipo Prefixo
AdRotator adrtr
Button btn
Calendar cldr
CheckBox cbx
CheckBoxList cbxl
CompareValidator cvdr
CrystalReportViewer crvwr
DataGrid dgrd
DataList dlst
DropDownList ddl
HyperLink hlnk
Image img
ImageButton ibtn
Label lbl
LinkButton lbtn
ListBox lbx
Literal ltrl
Panel pnl
PlaceHolder phdr
RadioButton rbtn
RadioButtonList rbtnl
RangeValidator rvdr
RegularExpressionValidator rev
Repeater rptr
Table tbl
TextBox tbx
Xml xml
Microsoft Visual C#
15
Considerações
Ao declarar variáveis, procure seguir as considerações abaixo.
Ao invés de:
int a, b;usar: int a; //Valor de entrada 1 int b; //Valor de entrada 2
Sempre inicializar suas variáveis no local aonde são declaradas.
int a = 1; //Valor de entrada 1
i. Criando um Projeto de Aplicação para Windows
Antes de iniciarmos um projeto, existe um ponto que deve ser vistos para
maior entendimento da estrutura da aplicação.
Namespace:
O Namespace é uma forma organizacional de agrupamento lógico,
permitindo que através de um nome totalmente qualificado você possa identificar
unicamente um recurso. Você pode colocar o namespace que achar necessário, a
seu gosto. O principal namespace do Visual Studio 2008 é o System. Para
referenciá-lo em seu projeto, basta colocar no inicio da página a seguinte
codificação:
using System; //Referenciando namespace System
O Visual Studio. NET conta com diversos recursos importantes para o
desenvolvimento de aplicações Windows.
Abaixo os passos para criar sua primeira aplicação .NET
Entre no Visual Studio.NET 2008.
Crie um novo projeto do tipo Windows Application, informe a pasta de
trabalho: [C:\ITTraining\TurmaXX\WinHello] onde XX é o número da sua
turma com o nome de WinHello.
Microsoft Visual C#
16
O Visual Studio .NET 2008 cria e mostra um formulário baseado em
Windows no modo Design conforme figura.
Vamos agora criar a nossa interface com o usuário.
Microsoft Visual C#
17
Na barra de ferramentas do Visual Studio .NET 2008, selecione no ToolBox o
controle Label e arraste para o formulário criado a label, posicione-o no canto
superior esquerdo do formulário. Conforme vimos anteriormente, altere seu nome
para melhor identificação. No exemplo será usado o nome lblMensagem.
Para colocar um controle no formulário você pode também dar um clique
duplo sobre ele na barra de ferramentas ou clicar uma vez sobre ele na barra de
ferramentas e depois clicar no formulário. O clique duplo posiciona o controle no
canto superior esquerdo. A segunda opção coloca o controle no local onde você
clicar.
Coloque também no formulário um controle TextBox e um controle Button.
Como mostra a figura abaixo e altere seus respectivos nomes. No exemplo será
usado o nome txtMensagem e btnMensagem.
Microsoft Visual C#
18
Na janela Solution Explorer, clique no botão View Code.
O código do arquivo Form1.cs aparece.
Para voltar ao modo design, também na janela Solution Explorer clique em
View Design.
Form1.cs tem todo o código gerado automaticamente pelo Visual Studio
.NET 2008. Note os seguintes elementos no código.
As diretivas usadas no inicio do código referenciando aos namespaces.
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms;
Microsoft Visual C#
19
O Visual Studio .NET 2008 usa o mesmo nome do projeto para criar o
namespace principal.
namespace WinHello { ...
}
Uma classe chamada Form1 dentro do namespace WinHello.
namespace WinHello { public partial class Form1 : Form {
... }
}
O constructor (construtor), é um método especial que tem o mesmo nome
da classe. Ele é o primeiro método a ser executado quando o programa é iniciado.
namespace WinHello { public partial class Form1 : Form { public Form1() { ... } } }
Repare que foi criado dentro da classe Form1 uma chamada a um método
“InitializeComponent();”que é responsável pela inicialização dos controles.
namespace WinHello { public partial class Form1 : Form { public Form1() { InitializeComponent(); } } }
Um método chamado InitializeComponent. O código dentro deste método
configura as propriedades dos controles que adicionamos no modo Design. Atenção,
não modifique o conteúdo do InitializeComponent diretamente no código, use a
janela Properties no modo Design.
#region Windows Form Designer generated code /// <summary> /// Required method for Designer support - do not modi fy /// the contents of this method with the code editor. /// </summary> private void InitializeComponent() { this .lblMensagem = new System.Windows.Forms.Label(); this .txtMensagem = new System.Windows.Forms.TextBox(); this .btnMensagem = new System.Windows.Forms.Button(); this .SuspendLayout(); // // lblMensagem // this .lblMensagem.AutoSize = true ; this .lblMensagem.Location = new System.Drawing.Point(13, 13); this .lblMensagem.Name = "lblMensagem" ; this .lblMensagem.Size = new System.Drawing.Size(159, 13);
Microsoft Visual C#
20
this .lblMensagem.TabIndex = 0; this .lblMensagem.Text = "[Aqui aparecerá sua mensagem]" ; // // txtMensagem // this .txtMensagem.Location = new System.Drawing.Point(16, 47); this .txtMensagem.Name = "txtMensagem" ; this .txtMensagem.Size = new System.Drawing.Size(100, 20); this .txtMensagem.TabIndex = 1; // // btnMensagem // this .btnMensagem.Location = new System.Drawing.Point(122, 47); this .btnMensagem.Name = "btnMensagem" ; this .btnMensagem.Size = new System.Drawing.Size(123, 23); this .btnMensagem.TabIndex = 2; this .btnMensagem.Text = "Mostrar Texto" ; this .btnMensagem.UseVisualStyleBackColor = true ; // // Form1 // this .AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this .AutoScaleMode = System.Windows.Forms.AutoScaleMode .Font; this .ClientSize = new System.Drawing.Size(292, 273); this .Controls.Add( this .btnMensagem); this .Controls.Add( this .txtMensagem); this .Controls.Add( this .lblMensagem); this .Name = "Form1" ; this .Text = "Form1" ; this .ResumeLayout( false ); this .PerformLayout(); } #endregion
Volte para o modo Design. Para voltar ao modo design, também na janela
Solution Explorer clique em View Design.
De um clique sobre o btnMensagem para selecioná-lo.
Na janela Properties, altere a propriedade Text do btnMensagem para
“Mostrar Texto”.
Se não localizar a janela Properties, clique em F4, ou no menu View, clique
em Properties Window.
Altere também a propriedate Text do lblMensagem para “Digite o seu nome”
Altere agora a propriedade Text do controle txtMensagem para “aqui”.
Note que as propriedades modificadas na janela Properties ficam em negrito.
Assim você pode saber se elas estão com seu valor padrão ou não.
Mude para o painel de código.
Note que as propriedades que você modificou estão no método
InitializeComponent. Conforme mostra o código abaixo:
Microsoft Visual C#
21
#region Windows Form Designer generated code /// <summary> /// Required method for Designer support - do not modi fy /// the contents of this method with the code editor. /// </summary> private void InitializeComponent() { this .lblMensagem = new System.Windows.Forms.Label(); this .txtMensagem = new System.Windows.Forms.TextBox(); this .btnMensagem = new System.Windows.Forms.Button(); this .SuspendLayout(); // // lblMensagem // this .lblMensagem.AutoSize = true ; this .lblMensagem.Location = new System.Drawing.Point(13, 13); this .lblMensagem.Name = "lblMensagem" ; this .lblMensagem.Size = new System.Drawing.Size(83, 13); this .lblMensagem.TabIndex = 0; this .lblMensagem.Text = "Digite seu nome" ; // // txtMensagem // this .txtMensagem.Location = new System.Drawing.Point(16, 47); this .txtMensagem.Name = "txtMensagem" ; this .txtMensagem.Size = new System.Drawing.Size(100, 20); this .txtMensagem.TabIndex = 1; this .txtMensagem.Text = "Aqui" ; // // btnMensagem // this .btnMensagem.Location = new System.Drawing.Point(122, 47); this .btnMensagem.Name = "btnMensagem" ; this .btnMensagem.Size = new System.Drawing.Size(123, 23); this .btnMensagem.TabIndex = 2; this .btnMensagem.Text = "Mostrar Texto" ; this .btnMensagem.UseVisualStyleBackColor = true ; // // Form1 // this .AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this .AutoScaleMode = System.Windows.Forms.AutoScaleMode .Font; this .ClientSize = new System.Drawing.Size(292, 273); this .Controls.Add( this .btnMensagem); this .Controls.Add( this .txtMensagem); this .Controls.Add( this .lblMensagem); this .Name = "Form1" ; this .Text = "Form1" ; this .ResumeLayout( false ); this .PerformLayout(); }
#endregion
Volte para o modo Design.
Selecione o formulário. Clicando sobre ele.
Note que aparecem três marcadores. Eles ajudam a redimensionar o
formulário.
Microsoft Visual C#
22
Clique sobre o marcador central na parte de baixo do Form1 e mantendo o
botão pressionado arraste para cima.
Isso serve para os outros controles também, clique sobre os outros controles
e note os marcadores.
No painel de código de um clique duplo sobre o btnMensagem.
Note que ele vai diretamente para o painel de código e é criado
automaticamente o seguinte código.
private void btnMensagem_Click( object sender, EventArgs e) {
}
Tudo que for digitado dentro deste código será executado assim que o
Button1 for clicado quando o programa estiver executando.
Digite o seguinte código:
Tenha atenção com esse código, ele deve ser digitado exatamente como se
segue, lembre-se que o C# é case-sensitive, ou seja, a palavra “ITTraining” é
diferente de “ittraining”. É importante lembrar do ponto-e-virgula no final da linha.
private void btnMensagem_Click( object sender, EventArgs e) { MessageBox.Show( "Ola " + txtMensagem.Text);
}
Execute o programa.
Para executar o programa você pode clicar e Ctrl+F5, ou no menu Debug
clicar em Start Without Debugging.
Automaticamente o Visual Studio .NET salva o programa, compila e o
executa. A seguinte janela aparece:
Digite seu nome e clique em “Mostrar Texto”.
Uma janela aparece exibindo a mensagem “Ola [seu-nome]”.
Clique em “Ok” para fechar a janela com a mensagem.
Na janela executando o Form1 clique em fechar.
Microsoft Visual C#
23
Agora você já esta familiarizado com as ferramentas do Visual Studio.NET
2008.
2. Entendendo os fundamentos da linguagem C#
a. Fundamentos
O objetivo do trabalho é efetuar uma introdução aos principais aspectos da
linguagem C#, incluindo os tipos de dados intrínsecos (valor e referencia),
estruturas de interação e de decisão, o papel do system.Object as técnicas básicas
de construção de classes. Para a ilustração destes fundamentos da linguagem,
vamos olhar para as bibliotecas .NET base e construir um número de aplicações
exemplos utilizando vários espaços de nome .NET
Como a linguagem Java, C# manda que todas as instruções de programa
devam ser inseridas no interior de uma definição de type, normalmente é uma
classe.
O espaço de nome System contêm as classes base e fundamentais que
define os tipos por valor ou referencia mais usados. Outras classes suportam
serviços de conversão de tipos de dados e manipulação de paramentos dos
métodos.
Os métodos podem ser do tipo público ou estáticos, e devem ser entendidos
que os públicos podem ser acessados de outras classes enquanto que os estáticos
apenas podem ser acessados dentro do nível da classe em que são definidos sem
necessidade de criar um novo objeto.
À medida que estamos desenvolvendo nossos códigos, percebemos que
estes podem ser divididos de acordo com suas funcionalidades. Ao efetuar esta
divisão, estamos na verdade criando blocos de códigos que executam uma
determinada tarefa. E, descobrimos que tais blocos de códigos podem ser
reaproveitados com freqüência em um mesmo programa. Assim, ao mecanismo
usado para disparar a execução destes blocos de códigos é dado o nome de método
(ou função em linguagens tais como C e C++).
Um método, em sua forma mais simples, é apenas um conjunto de
instruções que podem ser chamadas a partir de locais estratégicos de um
programa. Veja um exemplo:
// um método que não recebe nenhum argumento // e não retorna nenhum valor static void metodo() { Console.WriteLine( "Sou um método" );
}
Microsoft Visual C#
24
Este método apenas exibe o texto "Sou um método". Veja o uso das chaves
{ e } para delimitar a área de atuação do método (o corpo do método). A palavra-
chave void indica que este método não retorna nenhum valor ao finalizar sua
execução. Todos os métodos em C# possuem parênteses, os quais servem como
marcadores para a lista de parâmetros do método. Parênteses vazios indicam que o
método não possui parâmetros.
Veja agora um trecho de código completo exemplificando a chamada ao
método recém-criado:
// um método que não recebe nenhum argumento // e não retorna nenhum valor static void metodo() { Console.WriteLine( "Sou um método" ); } static void Main( string [] args) { // efetua uma chamada ao método metodo(); Console.WriteLine( "\n\nPressione uma tecla para sair..." ); Console.ReadKey();
}
b. Usando tipos predefinidos no C#
Segue abaixo uma lista sobre os tipos predefinidos no C#
Tipo Tamanho (em bytes) Tipos .NET
byte 1 Byte
char 1 Char
bool 1 Boolean
sbyte 1 Sbyte
short 2 Int16
ushort 2 Uint16
int 4 Int32
uint 4 Uint32
float 4 Single
double 8 Double
decimal 8 Decimal
long 8 Int64
ulong 8 Uint64
Microsoft Visual C#
25
Exemplos de declaração:
byte bytVar1 = 0; char chrVar2 = "" ; bool blnVar3 = false ; sbyte sbytVar4 = 0; short shtVar5 = 0; ushort yshtVar6 = 0; int intVar7 = 0; uint uintVar8 = 0; float fltVar9 = 0; double dblVar10 = 0; decimal dcmVar11 = 0; ulong ulngVar13 = 0;
Escrevendo expressões
chrVar2 = "a" + "b" ; intVar7 += 1; dblVar10 = (fltVar9 * intVar7) / dcmVar11;
Criando estruturas condicionais
Estruturas condicionais são comuns e necessárias em todos os programas. A
declaração if...else está entre as mais utilizadas pelos desenvolvedores. Algumas
delas pouco conhecidas dos novos programadores e mais familiares para quem já
utilizava a linguagem C#.
IF...ELSE com expressões simples
A declaração condicional if...else pode ser escrita de diferentes formas,
especialmente quando estamos construindo uma expressão simples, onde uma
única ação é executada caso a expressão seja verdadeira. Todos os exemplos
apresentados no quadro abaixo são válidos.
// considere as variáveis X e Y int x = 0; int y = 5; // declaração IF em uma única linha if (x > y) return ; // declaração IF...ELSE em duas linhas if (x > y) MessageBox.Show( "X > Y" ); else MessageBox.Show( "X < Y" ); // declaração IF...ELSE com quebra de linha if (x > y) MessageBox.Show( "X > Y" ); else MessageBox.Show( "X < Y" ); // declaração IF...ELSE em uma única linha if (x > y) MessageBox.Show( "X>Y" ); else MessageBox.Show( "X<Y" ); // utilização dos delimitadores de bloco neste caso // apesar de válido é desnecessário. if (x > y) { MessageBox.Show( "X > Y" ); } else { MessageBox.Show( "X < Y" );
}
Microsoft Visual C#
26
c. Os delimitadores de bloco { }
Quando precisamos executar mais de uma ação após avaliar a expressão
condicional, então faz-se necessário a utilização dos delimitadores de bloco, que
tem a função de agrupar um conjunto de instruções ou linhas de comando. Veja o
exemplo no quadro abaixo.
// utilização dos delimitadores de bloco neste caso // é necessária para que várias ações sejam executa das // caso a expressão seja satisfeita. if (x > y) { MessageBox .Show( "X > Y" ); this .Text = "Expressão é verdadeira." ; this .AtivarControles(); } else { MessageBox .Show( "X < Y" ); this .Text = "Expressão é falsa." ; this .DesativarControles(); }
d. Outras declarações condicionais
O C# oferece outra opção para construção de declarações condicionais. Os
operadores ?: representam uma boa alternativa para quem já estava habituado
com a linguagem C#. Podemos até fazer uma comparação grosseira da sintaxe
utilizadas com esses operadores com a função IIF no VB ou VBA. A sintaxe utilizada
é <expressão> ? <verdadeira> : <falsa>. Veja os exemplos no quadro abaixo:
int x = 1; int y = 2; int z = 3; // definindo a mesagem de acordo com a expressão MessageBox .Show(x > y ? "X > Y" : "X < Y" ); // atribui valor para z de acordo com a expressão z = x > y ? x * z : y * z; MessageBox .Show(z.ToString()); // expressões condicionais aninhadas // z = <expr1> ? <true> : <expr2> ? <true> : <false > z = x > y && x == 1 ? x * z : y > 1 ? y * z : y * z + x;
MessageBox .Show(z.ToString());
Numa primeira impressão, esse tipo de construção pode parecer confuso,
contudo se o desenvolvedor analisar esta sintaxe, verá que os operadores ?: podem
ser muito úteis e práticos em diversos cenários de codificação. Expressões simples
ou aninhadas podem ser facilmente construídas com os operadores ?:.
Com certeza você já implementou diversas expressões condicionais e todas
funcionam muito bem. É importante que os principiantes na linguagem C#
entendam a sintaxe correta das diferentes formas de declarações condicionais.
Muitos programadores, mesmo experientes, não conhecem ou não tem o hábito de
utilizar os operadores ?: que podem facilitar a codificação de expressões
Microsoft Visual C#
27
condicionais simples ou aninhadas. Explore as dicas acima e aprimore suas
expressões condicionais.
e. Comandos C#
C# possui um grupo variado de comandos de controle de fluxo do programa
que definirão sua lógica de processamento. A forma com que os comandos são
tratados permanece similar às anteriores. Portanto, na programação sequêncial, na
programação estruturada ou programação orientada à objetos, cada comando é
executado igualmente, ou seja, instrução por instrução. Na verdade, esta é a lei do
processador. Os principais comandos são classificados em:
• Declaração
• Rótulo ou Label
• Desvio ou Jump
• Seleção
• Iteração ou Loop
A maioria destes comandos é familiar para os programadores de linguagens
como C ou C++.
Estes comandos podem ser encontrados dentro de um bloco ou na forma
isolada. O bloco de comandos é representado por chaves ({}). Normalmente, um
bloco de comando é tratado como uma unidade de comando e é utilizado com
instruções como if, for, while, try, entre outros.
//Comando isolado if (a == true ) System. Console .Write( "Verdadeiro" );
//Bloco de comandos { int x = 100; int y = 200; int z = x + y; }
Uma linha de comando em C# pode conter uma ou mais instruções. Todas
elas são terminadas pelo finalizador (end point) ponto e vírgula (;).
//Vários comandos em uma única linha while (a <= 100) if (b == true ) a++;
Um tipo de comando conhecido como vazio (empty) também é válido em C#. //Loop infinito sem comando ou comando vazio for (; ; ) ; //Loop infinito com comando. Último ponto e vírgula representa o finalizador
Microsoft Visual C#
28
for (; ; ) System. Console .Write( "C# é legal" );
Declaração
Indica um recurso a ser utilizado ou exposto. As declarações podem ser de
variáveis, constantes, funções (métodos), propriedades ou campos.
Para declarar uma variável basta especificar o tipo seguido de uma literal. A
definição de uma constante ocorre da mesma forma que a variável, porém é
prefixada a a palavra-chave const e obrigatoriamente sufixada com o sinal de igual
(=) e seu valor. A atribuição para uma variável pode ocorrer a qualquer momento
dentro da aplicação ou na sua definição inicial, no entanto, para uma constante,
somente a atribuição inicial é válida e permanecerá inalterada durante a execução.
Uma variável ou constante é dependente de escopo, ou seja, da visibilidade dentro
de uma aplicação. Por exemplo, a variável x abaixo não pode ser utilizada
diretamente fora da função Main. Neste caso, ela deve ser utilizada através de um
argumento de uma função ou outra variável com escopo mais elevado. Os
principais escopos são local e classe. Todas as variáveis ou constantes dentro do
escopo de classe podem, obviamente, ser utilizadas dentro da classe como um
todo. Para não alargarmos a discussão, não citarei, neste momento, detalhes de
orientação à objetos tais como propriedades, métodos, campos e visibilidades
internas e externas (public, private, internal ou protected). O exemplo abaixo
ilustra os casos mais usuais de declaração:
using System; class Declares { private static int f = 1000, g; //Variáveis de escopo de classe private const int m = 1000, n = 10000; //Constantes de escopo de classe public static void Main() { //Constantes de escopo local const int x = 10; const long y = 100; //Variáveis de escopo local int a = 10; long b; b = 100; g = 10000; printf(x, y, a, b); } //Função
Microsoft Visual C#
29
private static void printf( int ix, long ly, int ia, long lb) { Console .WriteLine( "Locais\nconstantes: x={0} y={1} váriaveis: a={2} b={3}" , ix, ly, ia, lb); Console .WriteLine( "Classe\nconstantes: m={0} n={1} váriaveis: f={2} g={3}" , m, n, f, g); }
}
Para compilar o exemplo acima, no prompt, digite csc Declares.cs. Execute o
programa digitando Declares. A Figura 1, mostra compilação e execução da
aplicação em C#.
Figura 1: Compilação e Execução do exemplo Declares
As declarações de variáveis ou constantes de mesmo tipo podem ser feitas
na mesma linha.
int x; int y;
int z = 10;
Pode ser o mesmo que:
int x, y, z = 10;
Sobre escopo de variáveis e constantes um escopo interno tem prioridade
sobre o escopo externo, para qualquer resolução sempre o interno será utilizado.
Variáveis ou constantes dentro do mesmo escopo não poderão possuir o mesmo
nome, pois o compilador tratará isto como um conflito. Porém, elas poderão ser
encontradas com o mesmo nome em escopos ou locais diferentes. O conflito de
nomes também deve ser considerado para funções (métodos), propriedades e
campos.
class MyClass{
Microsoft Visual C#
30
private int x = 10; private int MyFunction(){ int x = 100; System. Console .Write(x); //Exibe o valor 100 } private int MyFunction2(){ System. Console .Write(x); //Exibe o valor 10 }
}
Rótulo (Label)
Discutir sobre rótulos (labels) sem falar sobre comandos de desvio é
impossível. Mas a única função de um rótulo é marcar, com uma palavra não
reservada, uma área do código que pode ser saltada através do comando goto.
Mesmo que C# permitida, este tipo de prática não é aconselhável em linguagens de
alto ou médio nível desde a evolução da programação sequencial.
using System; class Jumps{ public static void Main(){ bool a = true ; goto mylabel; //Este comando não será executado if (a == true ){ Console .Write( "Verdadeiro" ); goto end; } mylabel: Console .Write( "Falso" ); //o label é sempre seguido por um comando, neste ca so um comando vazio end: ; }
}
Desvio (Jump)
Os comandos de desvio em C# são: break, continue, goto, return e throw.
Basicamente, sua funcionalidade é desviar a execução do código para uma outra
localização.
Adorado por alguns e odiado pela maioria dos programadores e
especialistas, a instrução goto não foi abolidada da linguagem C#, tendo papel
fundamental quando aplicada com o comando switch, que veremos mais adiante. O
comando goto simplesmente executa um desvio de código através de um rótulo.
Microsoft Visual C#
31
Este desvio pode ser top-down (de cima para baixo) ou bottom-up (de baixo para
cima).
//Loop infinito endless: goto endless;
O comando return é utilizado para devolver um valor e sair de uma função
ou método chamado. Neste caso, o processamento é retornado para o chamador
para a continuação do processamento. Em caso de funções que não retornam valor
(void), o comando return poderá ser encontrado isolado, ou omitido se o mesmo
deverá ser encontrado no fim da função. Os snippets abaixo exibem os casos mais
comuns:
long z = Sum(10,20); //continuação do programa... private static long Sum( int x, int y){ //Soma os valores e retorna um long return x+y; } private static bool boolFromint( int a){ //Verifica se o valor do inteiro é 0 e retorna fals e, senão retorna true if (a==0) return false ; else return true ; } private static void printf( string s){ //Imprime a string e retorna logo em seguida, cláus ula return omitida System.Console.Write(s);
}
O comando throw é utilizado para produzir uma exceção, e pode ser
interceptado em tempo de execução pelo bloco try/catch.
private static double Division( int x, int y){ //Se o divisor for zero disparar a excessão da BCL DivideByZeroException if (y==0) throw new DivideByZeroException(); return x/y;
}
Os comandos break e continue são utilizados com os comandos de iteração
switch, while, do, for ou foreach. O comando break interrompe a execução do bloco
Microsoft Visual C#
32
destes comandos passando para próxima instrução ou bloco de execução. O
comando continue, ao contrário do break, passa para a próxima iteração e
verificação destes comandos.
int b=0; for ( int a = 0; a < 100; ++a){ //Loop infinito while ( true ){ if (++b==100) break ; //Se b igual a 100, o break força a saída do loop while } b=0; continue ; //Passa para próxima iteração do comando for System.Console.Write( "a={0} b={1}" ,a,b); //Esta linha não é executada }
//Continuação após o bloco for...
Seleção
Os comandos de seleção são utilizados na escolha de uma possibilidade
entre uma ou mais possíveis. Os comandos if e switch fazem parte deste grupo.
Comando if
O comando if utiliza uma expressão, ou expressões, booleana para executar
um comando ou um bloco de comandos. A cláusula else é opcional na utilização do
if, no entanto, seu uso é comum em decisões com duas ou mais opções.
//if com uma única possibilidade. Exibe a string "V erdadeiro" no Console caso a //expressão (a==true) seja verdadeira if (a== true ) System.Console.Write( "Verdadeiro" ); //if com uma única possibilidade. Exibe a string "V erdadeiro" no Console caso a //expressão (a==true) seja verdadeira, senão exibe a string "Falso" if (a== true ) System.Console.Write( "Verdadeiro" ); else
System.Console.Write( "Falso" );
Toda expressão do comando if deve ser embutida em parênteses (()) e
possui o conceito de curto-circuito (short-circuit). Isto quer dizer que se uma
expressão composta por And (&&), fornecer na sua primeira análise um valor
booleano false (falso), as restantes não serão analisadas. Este conceito é válido
para todas expressões booleanas. Por exemplo:
//&& (And). Somente a primeira função é executada if (MyFunc() && MyFunc2()); //|| (Or). Ambas funções são executadas
Microsoft Visual C#
33
if (MyFunc() || MyFunc2()); public static bool MyFunc(){ return false ; }
public static bool MyFunc2(){ return true ; }
Assim como outros comandos. O if também pode ser encontrado na forma
aninhada.
if (x==1) if (y==100) if (z==1000)
System.Console.Write( "OK" );
Porém, devido a característica de curto-circuito nas expressões, as linhas de
cima podem e devem ser reescritas para:
if (x==1 && y==100 && z==1000) System.Console.Write( "OK" );
O comando if também pode ser encontrado num formato escada if-else-if,
quando existem mais do que duas possibilidades. Porém, na maioria destes casos,
se as expressões não forem compostas ou utilizarem de funções, a cláusula switch
substitui este tipo de construção.
using System; class Ifs{ public static void Main(){ char chOpt; Console .WriteLine( "1-Inserir" ); Console .WriteLine( "2-Atualizar" ); Console .WriteLine( "3-Apagar" ); Console .WriteLine( "4-Procurar" ); Console .Write( "Escolha entre [1] a [4]:" ); //Verifica se os valores entrados esta entre 1 e 4 //caso contrário pede reentrada do{ chOpt = ( char ) Console .Read(); } while (chOpt< '1' || chOpt> '4' ); if (chOpt== '1' ){ Console .WriteLine( "Inserir..." ); //InsertFunction(); } else if (chOpt== '2' ){ Console .WriteLine( "Atualizar..." ); //UpdateFunction(); } else if (chOpt== '3' ){ Console .WriteLine( "Apagar..." );
Microsoft Visual C#
34
//DeleteFunction(); } else { Console .WriteLine( "Procurar..." ); //FindFunction(); } }
O comando if com a cláusula else única pode ser encontrado em sua forma
reduzida com operador ternário representado por interrogação (?:). É chamado de
operador ternário por possuir 3 expressões: a primeira refere-se a condição
boolena, a segunda se a condição é verdadeira e a terceira se a condição é falsa.
int x; if (f== true ) x = 100; else x = 1000;
As linhas acima podem ser substituídas por:
int x = f== true ?100:1000;
Comando switch
O comando switch utiliza o valor de uma determina expressão contra uma
lista de valores constantes para execução de um ou mais comandos. Os valor
constante é tratado através da cláusula case e este pode ser númerico, caracter ou
string. A cláusula default é utilizada para qualquer caso não interceptado pelo case.
O exemplo abaixo implementa a versão com o comando switch do exemplo,
previamente mostrado com o comando if:
using System; class Switchs{ public static void Main(){ char chOpt; Console .WriteLine( "1-Inserir" ); Console .WriteLine( "2-Atualizar" ); Console .WriteLine( "3-Apagar" ); Console .WriteLine( "4-Procurar" ); Console .Write( "Escolha entre [1] a [4]:" ); //Verifica se os valores entrados esta entre 1 e 4 //caso contrário pede reentrada do{ chOpt = ( char ) Console .Read(); } while (chOpt< '1' || chOpt> '4' ); switch (chOpt){
Microsoft Visual C#
35
case '1' : Console .WriteLine( "Inserir..." ); //InsertFunction(); break ; case '2' : Console .WriteLine( "Atualizar..." ); //UpdateFunction(); break ; case '3' : Console .WriteLine( "Apagar..." ); //DeleteFunction(); break ; default : Console .WriteLine( "Procurar..." ); //FindFunction(); }
}
Para compilar o exemplo acima, no prompt, digite csc Switchs.cs. Execute o
programa digitando Switchs. A Figura 2, mostra compilação e execução da
aplicação em C#.
Figura 2: Compilação e Execução do exemplo Switchs
No entanto, o comando switch não herda as características do mesmo em C
ou C++, uma cláusula case força um comando de desvio como break, goto ou
return assim as outras cláusulas case não serão processadas, o break em C# não
causa o efeito fall through. Se o programa precisar tratar mais do que uma
cláusula case com códigos distintos no mesmo switch, o comando goto deverá ser
utilizado. Uma ou mais cláusulas case podem ser encontradas seguidamente
quando mais do que uma opção é permitida para um comando ou bloco de
comandos. O exemplo abaixo apresenta essa condição:
switch (sProduct){ case “Windows 2000”: case “Windows NT”: System.Console.Write(“Sistema Operacional”); break ;
Microsoft Visual C#
36
case “MSDE”: System.Console.Write(“Mecanismo Simplificado”); goto case “SQL Server”; case “SQL Server”: System.Console.Write(“Banco de Dados”);
}
Assim como o comando if é possível encontrar o comando switch em sua
forma aninhada.
switch (x){ case 10: switch (y){ case 100: case 1000: } break ; case 100: break ;
}
Iteração ou Loop
Conhecidos como laço ou loop, os comandos de iteração executam
repetidamente um comando ou bloco de comandos, a partir de uma determinada
condição. Esta condição pode ser pré-definida ou com final em aberto. Em C#,
fazem parte dos comandos de iteração: while, do, for e foreach.
Comando for
O comando for possui 3 declarações opcionais, separadas por ponto e
vírgula (;), dentro dos parênteses: inicialização, condição e a iteração. Em cada
parâmetro, mais de uma expressão pode ser encontrada separada por vírgula.
for ( int x=0; x < 100; ++x) System.Console.WriteLine(x); for (;;) System.Console.WriteLine(“Hello, World!”);
for ( int y=100, int x = 0; x < y; ++x, --y)
System.Console.WriteLine(y);
Quando a cláusula for é processada pela primeira vez, se presente, a
expressão ou expressões da declaração inicializadora são executadas na ordem que
elas estão escritas, este passo ocorre apenas uma vez. Se a declaração condicional
estiver presente, será avaliada, caso contrário o for assume o valor verdadeiro
(true). Na avaliação, se o valor obtido for verdadeiro (true) o comando ou bloco de
comandos associados serão executados, ao seu final a terceira declaração ou
declaração de iteração é processada e, então, novamente a declaração condicional
é processada. Este fluxo ocorre continuamente até que a declaração condicional
Microsoft Visual C#
37
seja avaliada como falsa (false) ou o comando break seja encontrado, como visto
anteriormente. O comando continue força uma nova iteração.
using System; class Fibonacci{ public static void Main(){ int iVezes; Console .Write( "Entre de 1 a 100 para o n° de elementos a exibir na sequência de Fibonacci:" ); //Verifica se os valores entrados esta entre 1 e 10 0 //caso contrário pede reentrada do{ iVezes = Console .ReadLine().ToInt32(); } while (iVezes < 1 || iVezes > 100); //Cria o vetor dinâmicamente int [] iSeq = new int [iVezes]; iSeq[0] = 1; //Preenche o vetor if (iVezes > 1){ iSeq[1] = 1; for ( int a = 2; a < iVezes; ++a) iSeq[a] = iSeq[a - 1] + iSeq[a - 2] ; } //Exibe o vetor for ( int a = 0; a < iVezes; ++a){ Console .Write(iSeq[a]); Console .Write( " " ); } }
}
Para compilar o exemplo acima, no prompt, digite csc Fibonacci.cs. Execute
o programa digitando Fibonacci. A Figura 3, mostra compilação e execução da
aplicação em C#.
Microsoft Visual C#
38
Figura 3: Compilação e Execução do exemplo Fibonacci
Comando foreach
O comando foreach enumera os elementos de uma coleção. O código abaixo
implementa a funcionalidade do exemplo anterior:
using System; class Fibonacci{ public static void Main(){ int iVezes; Console .Write( "Entre de 1 a 100 para o n° de elementos a exibir na sequência de Fibonacci:" ); //Verifica se os valores entrados esta entre 1 e 10 0 //caso contrário pede reentrada do{ iVezes = Console .ReadLine().ToInt32(); } while (iVezes < 1 || iVezes > 100); //Cria o vetor dinâmicamente int [] iSeq = new int [iVezes]; iSeq[0] = 1; //Preenche o vetor if (iVezes > 1){ iSeq[1] = 1; for ( int a = 2; a < iVezes; ++a) iSeq[a] = iSeq[a - 1] + iSeq[a - 2] ; } //Exibe o vetor foreach ( int a in iSeq){ Console .Write(a); Console .Write( " " ); } }
}
Microsoft Visual C#
39
Os vetores em C# herdam da classe System.Array do .NET Framework e
implementam a interface IEnumerable que possui o método GetEnumerator que
retorna a interface IEnumerator que possui 3 membros: a propriedade Current que
retorna o objeto atual, o método MoveNext que pula para o próximo elemento e o
método Reset que reinicializa o posicionamento do elemento atual. Qualquer
interface ou classe que implemente IEnumerable e IEnumerator pode utilizar o
comando for each.
O comando foreach compacta a sequência abaixo:
System.Collections.IEnumerator ienumSeq = iSeq.GetE numerator(); while (ienumSeq.MoveNext()){ System.Console.WriteLine(ienumSeq.Current); } foreach ( int a in iSeq){ System.Console.WriteLine(a);
}
Comandos do while
Os comandos do e while têm características semelhantes. Ambos executam
condicionalmente um comando ou bloco de comandos. No entanto, o comando do
pode ser executado uma ou mais vezes e o comando while pode ser executado
nenhuma ou mais vezes, isto ocorre porque a expressão condicional do comando do
é encontrada no final do bloco.
int a = 0; bool f = true ; while (f){ if (++a==100) f = true ; System.Console.WriteLine(a); } int a = 0; bool f = true ; do{ if (++a==100) f = true ; System.Console.WriteLine(a); } while (f);
Microsoft Visual C#
40
Assim como para os comandos for e foreach, as cláusulas break e continue
podem ser utilizadas para interferir no fluxo de execução.
Outros comandos
Outros comandos, com finalidades distintas e não agrupados nos itens
citados anteriormente, são: try, catch, finally, checked, unchecked, unsafe, fixed e
lock.
Os comandos try, catch e finally são utilizados na intercepção e tratamento
de exceção em tempo de execução.
using System; class try_catch_finally{ public static void Main(){ try { Console .WriteLine( "Bloco try" ); throw new NullReferenceException (); } catch ( DivideByZeroException e){ Console .WriteLine( "Bloco catch #1. Mensagem: {0}" , e.Message); } catch ( NullReferenceException e){ Console .WriteLine( "Bloco catch #2. Mensagem: {0}" , e.Message); } catch ( Exception e){ Console .WriteLine( "Bloco catch #3. Mensagem: {0}" , e.Message); } finally { Console .WriteLine( "Bloco finally" ); } }
}
Os comandos checked e unchecked, tratam de overflow aritmético. O
comando checked dispara a exceção OverflowException e o comando unchecked
trunca o valor. O parâmetro /checked+ do compilador trata o overflow como
checked e o parâmetro /checked- do compilador trata o overflow como unchecked,
este é o padrão se não especificado.
using System; class Overflows{ public static void Main(){ try { short a = 32767; short b = ( short )(a + 1); Console .Write( "{1} + 1 = {0}" , b, a); } catch ( OverflowException e){ Console .WriteLine( "Mensagem: {0}" , e.Message); } }
}
Microsoft Visual C#
41
Para compilar o exemplo acima, no prompt, digite csc /checked+
Overflows.cs para a condição checked. Execute o programa digitando Overflows.
Depois no prompt, digite csc /checked- Overflows.cs para a condição unchecked.
Execute o programa digitando Overflows. A Figura 4, mostra as compilações e
execuções da aplicação em C#.
Figura 4: Compilações e Execuções do exemplo Overflows
Os comandos checked e unchecked podem ser utilizados dentro do
programa para alterar a condição especificada na compilação.
using System; class Overflows2{ public static void Main(){ try { short a = 32767; short b = unchecked (( short )(a + 1)); Console .WriteLine( "unchecked: {1} + 1 = {0}" , b, a); short c = 32767; short d = checked (( short )(c + 1)); Console .WriteLine( "checked: {1} + 1 = {0}" , d, c); } catch ( OverflowException e){ Console .WriteLine( "checked: Mensagem - {0}" , e.Message); } }
}
Os comandos unsafe e fixed é utilizado na operação com ponteiros. O
parâmetro /unsafe+ do compilador torna todo o código apto ao tratamento de
ponteiros. Por exemplo:
Microsoft Visual C#
42
using System; class Pointers{ unsafe public static void Process( int [] a){ fixed ( int * pa = a){ for ( int i = 0; i < a.Length; ++i) Console .Write( "{0} " , *(pa + i)); } } public static void Main(){ int [] arr = {1,2,3,4,5,6,7,8,9,0}; unsafe Process(arr); }
}
O comando lock utiliza critical section para bloqueio de acesso consecutivo
dentro de uma thread.
using System; using System.Threading; class Locks{ static int x = 0; public static void ThreadProc(){ lock ( typeof (Locks)){ x++; } Console .WriteLine( "x = {0}" , x); } public static void Main(){ for ( int a = 0; a < 10; ++a){ Thread t = new Thread ( new ThreadStart (ThreadProc)); t.Start(); } }
}
a. Exercícios
Criando uma calculadora
Adicionando funcionalidades a sua calculadora
3. Criando objetos em C#
a. Classes Abstratas, classes Seladas e Interfaces
Aqui descrevemos o que são Classes Abstratas, Seladas e Interfaces, e
também explicamos quando devemos implementar cada uma delas em nosso
código.
b. Introdução
Microsoft Visual C#
43
Utilizar classes seladas é um novo conceito adicionado ao C#. O conceito de
quando utilizar cada tipo de classe pode parecer um pouco confuso no início, mas
após ter entendido bem os conceitos de cada uma e entender suas similaridades,
poderemos partir para um desenvolvimento mais seguro e escalável.
c. O que é uma classe abstrata? (Abstract Class)
A classe abstrata é um tipo de classe que somente pode ser herdada e não
instanciada, de certa forma pode se dizer que este tipo de classe é uma classe
conceitual que pode definir funcionalidades para que as suas subclasses (classes
que herdam desta classe) possam implementá-las de forma não obrigatória, ou
seja ao se definir um conjunto de métodos na classe abstrata não é de total
obrigatoriedade a implementação de todos os métodos em suas subclasses, em
uma classe abstrata os métodos declarados podem ser abstratos ou não, e suas
implementações devem ser obrigatórias na subclasse ou não, quando criamos um
método abstrato em uma classe abstrata sua implementação é obrigatória, caso
você não implemente o compilador criará um erro em tempo de compilação.
Exemplo:
abstract class formaClasse { abstract public int Area(); } class quadrado : formaClasse { int x, y; // Se não for implementado o método Area() // será gerado um compile-time error. public override int Area() { return x * y; } }
d. O que é uma Interface? (Interface)
As interfaces são fundamentais em um sistema orientado a objetos, quando
dizemos que um objeto é a instância de uma classe, na verdade queremos dizer,
que este objeto implementa a interface definida pela classe, ou seja uma interface
define as operações que um objeto será obrigado a implementar. Para cada
operação declarada por um objeto deve ser especificado o nome da operação, os
objetos que esta operação aceita como parâmetro e o tipo de valor retornado pela
operação; este conjunto de informações sobre uma determinada operação tem o
nome de assinatura da operação, e um conjunto de assinaturas de operações dá-se
o nome de interface.
Microsoft Visual C#
44
É importante lembrar que uma interface nunca contém implementação, ou
seja numa interface não se pode definir campos, pois o mesmo é uma
implementação de um atributo objeto, a interface também não permite
construtores pois num contrutor temos as instruções usadas para inicializar
campos. Para podermos usar uma interface devemos criar uma classe ou estrutura
e herdar da interface, com isso é obrigatório implementar todos os métodos da
interface.
Exemplo:
interface IExemploInterface { void ExemploMetodo(); } class Implementacaoclasse : IExemploInterface { // Implementação explicita da interface void IExemploInterface .ExemploMetodo() { // Implementação do método } static void Main() { // Declarando uma instancia de uma interface IExemploInterface obj = new Implementacaoclasse (); // chame o método. obj.ExemploMetodo(); }
}
e. Classes Abstratas X Interfaces
Classes Abstratas podem adicionar mais funcionalidades, sem destruir as
funcionalidades das classes filhos que poderiam estar usando uma versão mais
antiga. Classes abstratas fornecem uma maneira simples e fácil para versionar
nossos componentes. Através da atualização da classe base, todas as classes que
herdam são atualizadas automaticamente com a mudança. Em uma interface, a
criação de funções adicionais terá um efeito sobre suas classes filhos, devido à
necessidade de implementação dos Métodos criados na interface. Classes abstratas
deveriam ser usadas principalmente para objetos que estão estritamente
relacionados, enquanto o uso de interfaces é mais adequado para fornecer
funcionalidade comum a classes independentes.
Digamos que existem duas classes, de pássaros e de aviões, e nas duas
exista os métodos chamados voar(). Seria estranho para uma classe aviões herdar
a partir de umas classe pássaros apenas porque necessita do método voar(). Em
vez disso, o método voar() deve ser definido em uma interface e em ambas as
classes pássaros e aviões devem implementar a interface. Se quisermos
Microsoft Visual C#
45
proporcionar uma funcionalidade em comum para os componentes, devemos
utilizar uma classe abstrata.
Classes abstratas nos permitem implementar parcialmente uma classe,
enquanto a interface não contem a implementação de qualquer membro. Por isso, a
seleção de interface ou classes abstratas depende das necessidades e design do
nosso projeto. Podemos fazer uma classe abstrata, interface, ou até uma
combinação de ambas dependendo de nossas necessidades. Se desejarmos criar
uma classe ou método interno para um componente ou library o ideal é utilizar o
tipo sealed porque qualquer tentativa de anular algumas das suas funcionalidades
não será permitida.
Nós podemos marcar uma classe ou método como selados por motivos
comerciais, a fim de impedir um terceiro de modificar nossa classe. Por exemplo,
no .NET a string é uma classe selada. Não devemos usar a palavra-chave sealed
com um método a menos que o método seja uma mudança de outro método, ou se
estamos definindo um novo método e não queremos que ninguém mais o
sobreponha, não se deve declará-lo como virtual em primeiro lugar. A palavra-
chave selado fornece uma maneira de garantir que ao sobrepor um método seja
fornecido um "final" significa que ninguém mais poderá sobrepor-lo novamente.
Devemos utilizar classes abstratas quando queremos compartilhar
funcionalidades em comum entre classes, e utilizar interfaces quando desejamos
que uma classe possua as mesmas assinaturas porem a implementação de cada
método não precise ser a mesma.
f. O que é uma classe selada? (Sealed Class)
Uma classe selada é utilizada para restringir características da herança do
objeto, quando uma classe é definida como sealed, está classe não poderá ser
herdada, caso você tente o compilador criara um erro em tempo de compilação.
Após criar uma classe selada pode se observar que o intelisense não mostra o
nome da classe definida como sealed quando você tenta criar uma herança para
novas classes.
Exemplo:
sealed class ClasseSelada { public int x; public int y; } class MainClass { static void Main() {
Microsoft Visual C#
46
ClasseSelada sc = new ClasseSelada (); sc.x = 110; sc.y = 150; Console .WriteLine( "x = {0}, y = {1}" , sc.x, sc.y); }
}
g. Declarando métodos
A declaração mais simples que podemos fazer de um método (lembrando
que isso deve ser feito dentro de uma classe) é a seguinte:
private void nomeMetodo() { //corpo do método
}
Onde o nomeMetodo é um identificador que define o nome pelo qual o
método é conhecido, e [corpo do método] consiste de uma lista ordenada de
declaração de variáveis, de expressões e de comandos. A primeira palavra-chave,
void, define o valor retornado pelo método, neste caso, nenhum. E o private
informa o tipo do método, ele pode ser private, public, static e protect. Podemos
usar qualquer tipo de dado válido como valor de retorno de um método. Nesse
caso, ao terminar, o método seria obrigado a devolver um dado do tipo
especificado. Por exemplo:
class Numero { double x = 1; private void print() { Console .WriteLine( "O valor e " + x); }
}
h. Moderadores de acesso
Os moderadores de acesso são empregados para restringir o acesso a um
método. Entretanto, independentemente do moderador escolhido, um método é
sempre acessível, isto é, pode ser chamado, a partir de qualquer outro método
contido na mesma classe. Os moderadores de acesso existentes em Java são os
seguintes:
Public
O método declarado com este moderador é público e pode ser chamado a
partir de métodos contidos em qualquer outra classe. Esta é a condição de menor
restrição possível.
Private
Microsoft Visual C#
47
O método é privativo da classe que o contém e seu uso é vedado a
qualquer.
Protected
O método é protegido pode ser chamado por todas as classes que compõe
um conjunto maior chamado package.
É importante avisar que você pode ter problemas em identificar violações
com respeito à chamada de métodos protegidos. Isso se deve ao fato do
compilador não sinalizar esse fato precisamente, isto é, a tentativa de chamar um
método protegido a partir de uma classe que não faz parte do package. Ao invés
disso a mensagem poderá se parecer com a seguinte:
No method matching funcao() found in class Matematica.
Internal
Esse tipo poder ser acessado por qualquer classe do projeto.
Protected Private
O método é acessível pela classe que o contém, assim como por qualquer
classe que tenha sido derivada dessa classe. Porém, isso somente é permitido
apenas dentro de um mesmo arquivo-fonte.
Static
Uma classe estática é basicamente a mesma que uma classe não-estática,
mas a diferença é que uma classe estática não pode ser instanciada. Em outras
palavras, você não pode usar a palavra-chave new para criar uma variável do tipo
da classe. Como não há nenhuma variável de instância, você acessa os membros
de uma classe estática usando o nome de classe propriamente dito. Por exemplo,
se você tiver uma classe estática denominada classeUtilidade contendo um
método público chamado criptografaSenha(), você chama o método conforme o
exemplo seguinte:
classeUtilidade.criptografaSenha();
i.Estrutura dos métodos
O par de parênteses adiante do nome do método introduz uma lista (vazia,
neste caso) de argumentos. A chamada de um método pode ser acrescida de
parâmetros, os quais são associados aos seus respectivos argumentos.
Um exemplo de métodos que retornam valores é o seguinte:
class Calculo {
Microsoft Visual C#
48
int Soma( int a, int b) { return a + b; } double Produto( double a, double b) { return a * b; } }
O primeiro método, Soma(), realiza a adição de dois números inteiros
fornecidos pelos argumentos a e b, e retorna o valor dessa soma. O segundo
método, Produto(), realiza a multiplicação de dois números de ponto-flutuante a e
b e retorna seu produto.
A sintaxe completa para a declaração de um método é a seguinte:
[moderadores de acesso] [modificador] [tipo do valor de retorno] [nome]
([argumentos])
throws [lista de excessões]
{
[corpo]
}
j. Usando Construtores de Instâncias
Construtores de instância são usados para criar e inicializar instâncias. O
construtor da classe é chamado quando você Criar um novo objeto, por exemplo:
class CoOrds { public int x, y; // constructor public CoOrds() { x = 0; y = 0; }
}
Esse construtor é chamada sempre que um objeto com base na classe
CoOrds é criado. Um construtor que leva sem argumentos, como este, é chamado
de construtor de padrão. No entanto, geralmente é útil fornecer construtores
adicionais. Por exemplo, podemos adicionar um construtor para a classe CoOrds
que permite especificar os valores iniciais para os membros de dados:
// A constructor with two arguments: public CoOrds( int x, int y) { this .x = x; this .y = y;
}
Microsoft Visual C#
49
Isso permite que objetos CoOrd poder ser criados com padrão ou valores
iniciais específicos, como este:
CoOrds p1 = new CoOrds ();
CoOrds p2 = new CoOrds (5, 3);
Se uma classe não tem um construtor padrão, uma é gerada
automaticamente e valores padrão são usados para inicializar os campos de objeto,
por exemplo, uma de int é inicializada com 0. Portanto, o construtor padrão da
classe CoOrds inicializa todas as variáveis com zero, ele pode ser removido
completamente sem alterar o funcionamento da classe.
Construtores de instância também podem ser usadas para chamar os
construtores de instância de classes base. O construtor da classe filho pode chamar
o construtor da classe base através do inicializador, da seguinte maneira:
class Circle : Shape {
public Circle( double radius) : base (radius, 0) { }
}
Neste exemplo, a classe Circle passa valores que representa o raio e altura
para o construtor fornecido pelo Shape do qual Circle é derivada.
Exemplo 1
O exemplo a seguir demonstra uma classe com construtores de classe dois,
sem argumentos e outra com dois argumentos.
class CoOrds { public int x, y; // Default constructor: public CoOrds() { x = 0; y = 0; } // A constructor with two arguments: public CoOrds( int x, int y) { this .x = x; this .y = y; } // Override the ToString method: public override string ToString() { return ( String .Format( "({0},{1})" , x, y)); } } class MainClass { static void Main() { CoOrds p1 = new CoOrds (); CoOrds p2 = new CoOrds (5, 3); // Display the results using the overriden ToString method: Console .WriteLine( "CoOrds #1 at {0}" , p1);
Microsoft Visual C#
50
Console .WriteLine( "CoOrds #2 at {0}" , p2); Console .ReadKey(); } } /* Output: CoOrds #1 at (0,0) CoOrds #2 at (5,3)
*/
Exemplo 2
Neste exemplo, a classe Person não tem nenhum construtor, um construtor
padrão é fornecido automaticamente e os campos são inicializados com seus
valores padrão.
public class Person { public int age; public string name; } class TestPerson { static void Main() { Person person = new Person (); Console .WriteLine( "Name: {0}, Age: {1}" , person.name, person.age); // Keep the console window open in debug mode. Console .WriteLine( "Press any key to exit." ); Console .ReadKey(); } }
// Output: Name: , Age: 0
Observe que o valor padrão de age é 0 e o valor padrão de name é null.
Exemplo 3
O exemplo a seguir demonstra o uso o inicializador de classe base. A classe
Circle é derivada da classe geral Shape, e a classe Cylinder é derivada da classe
Circle. O construtor em cada classe derivada está usando o inicializador de classe
base.
abstract class Shape { public const double pi = Math .PI; protected double x, y; public Shape( double x, double y) { this .x = x; this .y = y; } public abstract double Area(); } class Circle : Shape { public Circle( double radius) : base (radius, 0) { } public override double Area() { return pi * x * x; } }
Microsoft Visual C#
51
class Cylinder : Circle { public Cylinder( double radius, double height) : base (radius) { y = height; } public override double Area() { return (2 * base .Area()) + (2 * pi * x * y); } } class TestShapes { static void Main() { double radius = 2.5; double height = 3.0; Circle ring = new Circle (radius); Cylinder tube = new Cylinder (radius, height); Console .WriteLine( "Area of the circle = {0:F2}" , ring.Area()); Console .WriteLine( "Area of the cylinder = {0:F2}" , tube.Area()); // Keep the console window open in debug mode. Console .WriteLine( "Press any key to exit." ); Console .ReadKey(); } } /* Output: Area of the circle = 19.63 Area of the cylinder = 86.39 */
4. Técnicas de programação orientada a objeto em C#
a. Classes e Objetos
No mundo orientado a objetos, tudo é focado em classes e em objetos.
Precisamos então defini-los para podermos entender as diferenças entre os dois e
começarmos a entrar realmente no mundo da POO (Programação Orientada a
Objetos).
Quando construindo algo, temos duas fases distintas, mas que são
imprescindíveis ao sucesso do nosso projeto: a formalização do que estamos
criando e a transformação da formalização (projeto) em algo físico. Essas duas
fases estão representadas no mundo orientado a objetos pela classe (formalização,
projeto de algo) e pelo objeto (transformação do projeto em algo físico, ou seja,
uma variável na memória).
Vamos imaginar o caso em que temos de construir um computador. Antes
de construir o computador, temos que definir suas propriedades, formas, ações que
executará. Teríamos então que montar um projeto do computador, o que na
orientação a objetos significa criar uma classe. Se pensarmos que um computador
possui monitor, mouse, teclado e gabinete, devemos então acrescentar essas
características do computador ao nosso projeto. Cada característica de uma classe
Microsoft Visual C#
52
é chamada de atributo. Devemos então ter uma classe chamada Computador que
possui quatro atributos.
Além de declarar as características das classes, devemos também definir as
ações que o nosso futuro objeto poderá executar. Essas ações são definidas por
meios de métodos, que serão estudados mais adiante.
Vamos então definir uma classe em C# utilizando a palavra chave "class" no
início do código e guardando seus atributos com seus respectivos tipos. Os
atributos nada mais são que variáveis globais a classe.
Veja no código abaixo a definição da classe Computador:
class Computador { Monitor monitor; Teclado teclado; Mouse mouse; /*abaixo podemos criar vários métodos que definem as ações de um computador */ }
b. Criando Objetos
Agora que já sabemos como definir uma classe, podemos passar ao ponto
de criar objetos da classe definida. É importante perceber o fato de que podemos
criar vários objetos da mesma classe, não ficando limitado a apenas um objeto.
Quando vamos criar um objeto em C# utilizamos a palavra chave "new"
seguindo o seguinte esquema:
<Tipo> <nome> = new <Tipo>()
Veja então um exemplo do objeto Computador com o nome comp1:
Computador comp1 = new Computador ();
Perceba que na criação do objeto, após o new, chamamos o tipo
Computador seguido de parênteses. Essa notação significa que neste momento será
executado um método especial da classe Computador chamado construtor.
O construtor é um método que possui o mesmo nome da classe, que não
retorna nenhum valor e que é chamado cada vez que um objeto da classe é criado.
Quando não criamos nenhum construtor (como na classe Computador acima), o
construtor vazio, que não recebe nenhum parâmetro e também não executa
nenhum código, é criado automaticamente.
Microsoft Visual C#
53
Veja a classe Computador modificada com um construtor que recebe 3
strings e preenche os atributos da classe com essas strings:
namespace Construtor { class Computador { string monitor; string teclado; string mouse; public Computador( string m, string t, string r) { monitor = m; teclado = t; mouse = r; } } public class App { public static void Main() { Computador comp1 = new Computador ( "Monitor" , "Teclado" , "Mouse" ); Computador comp2 = new Computador ( "Monitor2" , "Teclado2" , "Mouse2" ); //essa linha daria erro de compilação: new Computador(); } }
}
Nesse código, criar um objeto com o construtor vazio daria um erro de
compilação já que, ao criar o construtor que recebe 3 string, "apagamos" o
construtor vazio.
Tipos por valor x Tipos por referência.
Os tipos pré-definidos em C# são normalmente conhecidos como tipos por
valor. Esses tipos devem permitir um acesso rápido já que são muitas vezes
utilizados no código. Dessa forma, os tipos por valor têm guardados na memória
apenas o seu valor, sem nenhuma outra informação adicional que poderia causar
um gasto desnecessário de memória.
Os tipos criados por classes, os objetos, são conhecidos como tipos "por
referência". Essa denominação vem do fato de que esses tipos não guardam o seu
valor, mas sim uma referência para um local na memória que contém o valor.
Com essas definições, é importante perceber que, se copiarmos as
informações de variáveis de tipos por valor e de variáveis de tipos por referência,
teremos comportamentos diferentes. Caso copiemos uma variável por valor, o que
ocorre é que uma nova cópia do valor é passada para a outra variável. Isso
significa que caso modifiquemos uma das variáveis, nada ocorrerá com a outra.
Microsoft Visual C#
54
Em variáveis por referência o que ocorre ao copiarmos para outra variável é
que apenas a referência é copiada, não o valor. Após a cópia o que acontece é que
teremos duas variáveis apontando para um mesmo valor. Isso significa que, ao
modificarmos uma variável, estaremos na realidade modificando o valor para o qual
a outra variável também está apontando, significando que o valor da outra variável
também será modificado.
Veja o código abaixo e observe o resultado:
class Computador { public string monitor; public string teclado; public string mouse; public Computador( string m, string t, string r) { monitor = m; teclado = t; mouse = r; } public override string ToString() { return this .monitor + " " + this .teclado + " " + this .mouse; } } public class App { public static void Main() { //cria uma variável de tipo por valor int valor1 = 10; //copia para outra variável int valor2 = valor1; //adiciona 5 a valor2 valor2 += 5; //imprime o valor das duas: Console .WriteLine( "valor1: " + valor1); Console .WriteLine( "valor2: " + valor2); //cria um objeto de tipo por referência Computador comp1 = new Computador ( "Monitor1" , "Teclado1" , "Mouse1" ); //copia a referência Computador comp2 = comp1; //modifica o valor do monitor: comp2.monitor = "Modificado!" ; //imprime as duas datas: Console .WriteLine( "comp1: " + comp1); Console .WriteLine( "comp2: " + comp2); }
}
Veja o resultado:
Microsoft Visual C#
55
Mesmo tendo modificado apenas um dos objetos (o comp2), o comp1
também foi modificado, provando que na verdade os dois objetos referenciam o
mesmo endereço na memória.
Perceba que tivemos que modificar a classe Calculadora adicionando a ela o
método ToString() para que o Console.WriteLine() pudesse recuperar o valor da
comp1 e comp2 automaticamente para uma string.
c. Usando Herança
Herança é uma dos três princípios fundamentais da programação orientada a
objetos porque ela permite a criação de hierarquia nos objetos que compõem o
sistema. Em C#, uma classe que tem seus dados e métodos herdados por outra é
chamada de classe base ou super classe e a classe que herda tais dados é chamada
de classe derivada ou sub-classe.
O que um aluno, um professor e um funcionário possuem em comum? Todos
eles são pessoas e, portanto, compartilham alguns dados comuns. Todos têm
nome, idade, endereço, etc. E, o que diferencia um aluno de uma outra pessoa
qualquer? Um aluno possui uma matrícula; Um funcionário possui um código de
funcionário, data de admissão, salário, etc; Um professor possui um código de
professor e informações relacionadas à sua formação.
É aqui que a herança se torna uma ferramenta de grande utilidade. Podemos
criar uma classe Pessoa, que possui todos os atributos e métodos comuns a todas
as pessoas e herdar estes atributos e métodos em classes mais específicas, ou seja,
a herança parte do geral para o mais específico. Comece criando uma classe Pessoa
como mostrado no código a seguir:
class Pessoa { public string nome; public int idade;
}
Esta classe possui os atributos nome e idade. Estes atributos são comuns a
todas as pessoas. Veja agora como podemos criar uma classe Aluno que herda
estes atributos da classe Pessoa e inclui seu próprio atributo, a saber, seu número
de matrícula:
Microsoft Visual C#
56
class Aluno : Pessoa { public string matricula;
}
Observe que, em C#, os dois-pontos são usados para indicar a herança. A
classe Aluno agora possui três atributos: nome, idade e matricula. Veja um
aplicativo demonstrando este relacionamento:
static void Main( string [] args) { // cria um objeto da classe Aluno Aluno aluno = new Aluno (); aluno.nome = "Osmar J. Silva" ; aluno.idade = 36; aluno.matricula = "AC33-65" ; // Exibe o resultado Console .WriteLine( "Nome: " + aluno.nome + "\n" + "Idade: " + aluno.idade + "\n" + "Matrícula: " + aluno.matricula); Console .WriteLine( "\n\nPressione uma tecla para sair..." ); Console .ReadKey();
}
A herança nos fornece um grande benefício. Ao concentrarmos
características comuns em uma classe e derivar as classes mais específicas a partir
desta, nós estamos preparados para a adição de novas funcionalidades ao sistema.
Se mais adiante uma nova propriedade comum tiver que ser adicionada, não
precisaremos efetuar alterações em todas as classes. Basta alterar a superclasse e
pronto. As classes derivadas serão automaticamente atualizadas.
d. Polimorfismo
O polimorfismo é uma facilidade que permite que dois ou mais objetos
diferentes respondam a mesma mensagem.
Utilizar polimorfismo, em linguagens de Programação Orientada a Objeto
(OOP), podemos dizer que é quase indispensável, já que esta é uma maneira de
desenvolvimento que traz muitos benefícios, Clareza no código, Distribui melhor a
complexidade da aplicação entre outras.
Neste modelo de desenvolvimento OOP, é fundamental a utilização de
classes, no modelo do polimorfismo. Algumas classes serão objetos e outras classes
“filhas” serão métodos do objeto.
Objeto é tudo aquilo que existe, como casa, carro, avião, cachorro e etc.
Métodos são todas as ações que estes objetos possuem.
Microsoft Visual C#
57
Para que fique claro este assunto de objeto e método, vamos imaginar 3
classes: Carro, Acelerar e Frear.
Vamos verificar um exemplo de Polimorfismo:
//Classe public abstract class Carro { public abstract bool acao();
}
Verifique que no código acima, crio a classe carro e determinando qual
evento este objeto terá.
//Classe public class Acelerar : Carro { public override bool acao() { Console .WriteLine( "O Carro está acelerando." ); return true ; } } public class Frear : Carro { public override bool acao() { Console .WriteLine( "O Carro está freando." ); return true ; }
}
Verifique que no código acima crio outras 2 classes herdando a classe carro,
ou seja, essas classes passarão a ser métodos da classes Carro.
//Formulário public bool carro_em_movimento(Carro car) { return car.acao(); } private void btn_cal_Click( object sender, System. EventArgs e){ if ( this .opt_acelera. checked ){ carro_em_movimento( new Acelerar ()); } else { carro_em_movimento( new Frear ()); } }
Verifique que no formulário foi criado uma função CARRO_EM_MOVIMENTO,
para referenciar o objeto Carro, assim que, a função é chamada e você faz a
passagem do parâmetro, é possível visualizar os métodos disponíveis na classe
Carro. No polimorfismo os métodos de um objeto somente serão visualizados,
quando o objeto que eles pertencem é chamado na aplicação.
Com o uso do Polimorfismo fica muito mais fácil a manutenção do código
fonte e a criação de novos métodos da classe, para isso, basta criar uma nova
classe (ex: Ligar_a_Luz) herdando a classe Carro, a classe Ligar_a_Luz passará a
ser método da Classe Carro.
Microsoft Visual C#
58
e. Exercícios
Criando estrutura de classes para uma sala de aula
5. Criando uma aplicação Web
a. Criando um formulário para aplicações Web
Entendendo o que é MasterPage
É comum em aplicações convencionais ou mesmo Web a necessidades de
criarmos partes de conteúdo que serão exibidas em todas ou pelo menos em
diversas páginas. No ASP clássico isso era resolvido da seguinte forma: Você
desenvolvia o conteúdo separadamente e sua inclusão era feito onde necessário
através de uma tag Include.
No ASP.NET 1.1 surgiu uma novidade: os chamados Web User Controls, que
são arquivos com a extensão ascx, que podiam ser programados na IDE do Visual
Studio e adicionados a qualquer Web Form. Trouxe significativas vantagens em
relação ao uso do include, como o fato da pagina host ter a possibilidade de ler ou
alterar valores de controles ou propriedades.
Sua grande desvantagem era que não possuía herança visual como já há um
longo tempo era possível em aplicações convencionais: O user control em tempo de
design eram representados na IDE do VS como um botão cinza.
No ASP.NET 2.0 uma das grandes novidades apresentadas e que obviamente
continuam disponíveis na versão 3.5 são as Master Pages, que trazem finalmente a
herança de conteúdo de forma visual.
Uma MasterPage é um arquivo com extensão master. Pode ser criada no IDE
do VS no modelo code-behing ou code-inline, assim como um Web Form. Sua
estrutura básica também é muito parecida com um Web Form:
<%@ Master Language ="VB" CodeFile ="Master.master.vb" Inherits ="Master" %> <! DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitiona l.dtd"> <html xmlns ="http://www.w3.org/1999/xhtml" > <head id ="Head1" runat ="server"> <title >Untitled Page </ title > </ head > <body > <form id ="form1" runat ="server"> <div > <asp : contentplaceholder id ="ContentPlaceHolder1" runat ="server"> </ asp : contentplaceholder > </ div >
Microsoft Visual C#
59
</ form > </ body >
</ html >
A principal diferença é a diretiva de compilação @Master, no lugar de
@Page. Esta diretiva informa ao ASP.NET durante o processo de compilação que
trata-se uma Master Page.
Uma página aspx que utiliza uma Master Page é chamada de página de
conteúdo (Content Page). Uma página de conteúdo não contem os elementos que
formam uma página HTML comum, pois estes serão herdados da Master Page.
Numa Master Page, as áreas onde uma pagina de conteúdo terão disponível para
exibir seu conteúdo são definidas através de controles de servidor
contentplaceholder. No código acima você pode ver um controle contentplaceholder
criado por padrão na criação da MasterPage.
b. Criando uma Master page
Criar uma Master Page no Visual Studio é simples: Na caixa de dialogo Add
New Item Selecione Master Page, defina um nome para a página. O VS cria a
MasterPage com o nome escolhido.
Se você optou pelo modelo code-behind, serão criados dois arquivos: um
arquivo master e um vb ou cs, conforme a linguagem escolhida. Se a opção foi
code-inline, será criado apenas o arquivo .master.
c. Utilizando uma Mater Page
Definir a(s) página(s) de conteúdo é simples e pode ser feito quatro
maneiras diferentes:
Durante a criação da página, na caixa de dialogo Add New Item, marque a
opção Select Master Page
Microsoft Visual C#
60
Será exibida a caixa de dialogo Master Page, que exibe as Master Pages
disponíveis no projeto:
Baste selecionar a página Master e clicar em Ok.
Microsoft Visual C#
61
A segunda é através da própria pagina Master, selecionando a opção Add
Content Page. Será criada uma página de conteúdo em branco. Você não poderá
escolher o nome da página no momento da sua criação.
A terceira é de forma manual. Crie um Web Form normalmente, remova
todo o HTML gerado, com exceção da diretiva de página. Adicione a diretiva de
página o atributo MasterPageFile, que indica que esta é uma página de conteúdo
que utiliza a Master Page especificada no atributo.
Finalmente, a quarta e última, e em tempo de execução:
protected void Page_PreInit( object sender, EventArgs e) { Page.MasterPageFile = "~/MasterUm.master" ;
}
A defninição de uma pagina Master em tempo de execução deve ser feito no
evento PreInit da página.
Obviamente que esta última forma nos priva dos beneficios da herança
visual.
d. Trabalhando com uma Master Page
Este não é um curso de Web Design, portanto não perca tempo ou se
preocupe com a aparência de suas atividades práticas.
Nesta sessão vamos demonstrar de maneira prática como tirar proveito da
utilização de uma Master Page.
Crie uma nova aplicação ASP.NET;
Crie uma nova Master Page;
Defina o layout da Master Page de acordo com a figura abaixo:
Microsoft Visual C#
62
Para os quatro controles da esquerda, que deverão funcionar como
HyperLinks, utilize controles de Servidor HyperLinks, defina a propriedade text de
cada um como Desentupimento, Hidráulica, Limpeza e Hidrojateamento. A
propriedade NavigateUrl de cada um deve ser definida pelo mesmo conteúdo da
propriedade text mais a extesão aspx, por exemplo: Desentupimento.aspx.
Crie quatro páginas de conteúdo com os nomes especificados nas
propriedades NavigateUrl acima, especificando como Master Page a página criada.
Defina um conteúdo especifico para cada página de conteúdo, conforme
exemplo abaixo:
Na área Content da página de conteúdo você pode trabalhar livremente:
adicionar controles, eventos etc.
Microsoft Visual C#
63
Defina uma das páginas de conteúdo criada como página inicial e rode a
aplicação.
Navega entre as páginas e veja na prática o funcionamento da aplicação.
Acessando a página Master da página de conteúdo
Você pode facilmente acessar qualquer controle ou propriedade da página
Master, na página de conteúdo, através da propriedade Master.
Por exemplo, para ler o conteúdo de um dos HyperLinks da página Master:
if (!Page.IsPostBack) { string s = (Master.FindControl( "Desentupimento" ) as HyperLink ).Text;
}
Também podemos alterar o texto ou mesmo qualquer propriedade do
controle na Master Page, pois nossa operação é por referencia:
HyperLink Hyper; Hyper = (Master.FindControl( "Desentupimento" ) as HyperLink ); Hyper.ForeColor = System.Drawing. Color .Red;
Neste exemplo, estamos mudando a cor do HyperLink do conteúdo da
página Master para vermelho.
e. Alterando o Título das páginas de conteúdo
Microsoft Visual C#
64
A página de conteúdo deve conter um atributo title, onde deve ser definido o
titulo para exibição da página. Na ausência deste, será exibido o titulo da Master
Page.
Outra alternativa é definir no código o título para a página:
Master.Page.Title = "Titulo definido em tempo de execução" ;
Trabalhando com conteúdo padrão
Outra possibilidade interessante é a de trabalhar com conteúdo padrão. Você
pode definir um conteúdo padrão de exibição na área da página de conteúdo, da
mesma forma que você define o restante da página. Na página de conteúdo, para
exibir o conteúdo padrão, basta clicar em Default to Master Content na Smart Tag
do controle de conteúdo.
f. Master Pages aninhadas
Alem de tudo o que estudamos, é possível mais. Você pode criar Master
Pages aninhadas, em diferentes níveis. O VS 2005 não da suporte em sua IDE para
este recurso, portanto você terá que fazer todo o trabalho manualmente.
Uma grande novidade que podemos encontrar no ASP.NET 2.0 é o recurso
Master Page (Herança Visual). Com esse recurso podemos criar uma pagina padrão
e depois replicar a aparência visual para as outras paginas. Caso precise mudar,
basta alterar em um único ponto. A Master Page pode ser definida na diretiva da
pagina, dinamicamente via código e até no web.config para que todas paginas já
saiam com uma Master Page. Confira na figura 01 uma Master Page e na figura
02 sua utilização dentro de um web form.
Microsoft Visual C#
65
Figura 01 - Master Page
Figura 02 - Pagina usando uma Master Page
g. Criando Master Page
Vá ao Solution Explorer, botão direito no seu projeto, Add New Item e
escolha o tempate Master Page conforme figura 03. Confirmando será criado um
arquivo com a extensão "*.master" que indica que esse arquivo é uma Master
Page.
Microsoft Visual C#
66
Figura 03 - Criando uma Master Page
Com a Master Page criada conforme figura 04, adicione um texto que
usaremos como padrão. A área que aparece como ContentPlaceHolder será o
espaço reservado para adicionar o contéudo do WebForm. Você pode adicionar
quantos Contents forem necessários.
Figura 04 - Nova Master Page
Apartir desse momento já podemos criar uma nova pagina (webform) que
utilize uma Master Page para definir sua aparência. Adicione então um novo
WebForm conforme figura 05 e marque o checkbox "select master page". Após
confirmar vai mostrar a tela da figura 06, onde você deve escolher uma Master
Page.
Microsoft Visual C#
67
Figura 05 - Criando nova pagina e relacionando Master Page
Figura 06 - Selecionando Master Page
Após confirmar teremos o resultado apresentando na figura 07, adicione
um texto dentro do Content e execute sua pagina no navegador, o resultado deve
ser similar a figura 08.
Microsoft Visual C#
68
Figura 07 - Nova Pagina
Figura 08- Testando a pagina
Acesso objetos da Master Page
É possível acessar objetos em uma Master Page e alterar valores dinamicamente.
Retorne a nossa PaginaPadrao.Master e onde tinha colocado um texto "Master
Page" retire o mesmo e coloque um Label, com as propriedades:
Text="",ID=lblTitulo. Confira na figura 09.
Figura 09 - Adicionando Label na Master Page.
Agora efetue dois cliques na Master Page e vamos ao code behind. Adicione a
propriedade AlteraTitulo conforme listagem 01.
Microsoft Visual C#
69
Public WriteOnly Property AlteraTitulo() As String
Set(ByVal value As String)
Me.lblMaster.Text = value
End Set
End Property
Listagem 01 - Propriedade AlteraTitulo
Agora retorne ao webform que criamos e adicione um Label, um TextBox e
um Button conforme figura 10. Ainda nessa pagina efetue a codificação do botão
conforme listagem 02.
Figura 10 - Alterando Pagina (WebForm)
Protected Sub Button1_Click(ByVal sender As Object, ByVal e As
System.EventArgs) Handles Button1.Click
CType(Master, PaginaPadrao).AlteraTitulo = Me.TextBox1.Text
End Sub
Listagem 02 - Propriedade AlteraTitulo
Após adicionar o código já poderemos testar conforme figura 11.
Figura 11 – Testando
Microsoft Visual C#
70
Diretivas de Pagina
O arquivo.master contém a diretiva @Master :
<%@ Master Language="VB" CodeFile="Mastermodelo.master.vb"
Inherits="Mastermodelo" %>
A pagina contém a diretiva MasterPageFile :
<%@ Page Language="VB"
MasterPageFile="~/MasterPages/PaginaPadrao.master" AutoEventWireup="false"
CodeFile="Nova_Pagina.aspx.vb" Inherits="Nova_Pagina" title="Untitled Page" %>
Observando código da listagem 02 foi necessário fazer casting para ter
acesso a propriedade da Master, para não ser necessário, na pagina adicione o
atributo MasterType:
<%@ MasterType VirtualPath="PaginaPadrao.master" %>
Adicionando essa diretiva na pagina poderemos alterar código conforme
listagem 03.
Protected Sub Button1_Click(ByVal sender As Object, ByVal e As
System.EventArgs) Handles Button1.Click
'CType(Master, PaginaPadrao).AlteraTitulo = Me.TextBox1.Text
Master.AlteraTitulo = Me.TextBox1.Text
End Sub
Listagem 03 - Propriedade sem fazer casting
Finalizando
Master Pages conforme você conferiu veio para facilitar mais ainda o
trabalhado do desenvolvedor que agora vai ter uma pagina padrão com o layout
que pode ser alterado a qualquer momento em um único ponto.
Faça o download do código.
h. Acessando dados através do formulário de aplicações Web
Configurando e utilizando Session
Session (sessão) é o período de tempo em que o usuário interage com a
aplicação. Em termos de programação a sessão é a memória em forma de
dicionário ou ainda de uma tabela hash. Por exemplo, a sessão pode ser um
Microsoft Visual C#
71
conjunto de valores-chave que podem ser definidos e lidos por um usuário, durante
a utilização da aplicação web pelo mesmo.
A configuração da sessão é feita diretamente no web.config:
Figura 1 - Configuração do web.config para InProc
As opções para a configuração são as seguintes:
Mode: O Asp.Net suporta dois modos: no processo e fora do processo.
Sendo assim o modo de configuração suporta três opções: inproc, stateserver e
sqlserver;
Cookieless: Define se o cookie estará ativo ou não para o Asp.Net, é definido
por um valor booleano;
Timeout: Define por quanto tempo a sessão é válida. É calculado pelo tempo
atual mais o tempo de timeout. Deve-se passar o valor em minutos e por default no
.NET a sessão dura vinte minutos;
SqlConnectionString: É a referência da conexão de banco de dados do SQL
Server;
Server: No modo StateServer é o nome do servidor que está executando os
serviços do Windows NT: ASPSTATE;
Port: Identifica o número da porta do servidor quando este se encontra
configurado no modo stateserver;
i. Modos de Configuração
InProc
O mode de processo (InProc) utiliza basicamente a sessão do Asp.NET, ou
seja, a sessão é controlada em processo e caso o processo seja re-cíclico o estado é
perdido. Em termos de desempenho é o mais rápido, pois o dado já está em
processo. Quanto à configuração utiliza cokieless e o timeout da configuração
padrão da sessão do ASP.NET.
Microsoft Visual C#
72
No caso de perder a sessão os dados serão perdidos, para fazer um teste
basta adicionar um valor na sessão (vide o tópico utilizando a sessão deste mesmo
artigo) e logo em seguida parar e iniciar novamente o serviço do ISS (iisreset) e
verificar que o valor foi perdido.
StateServer
Neste modo de configuração a sessão é gerenciada por um serviço, o
ASPSTATE que deve ser iniciado. Para iniciar o serviço abra o prompt de comando
navegue até o diretório da framework "v1.0.2204" (Ex: "c:\Windows\Microsoft
.net\framework\v1.0.2204") e execute o comando:
Figura 2 - Iniciando o serviço aspstate.
Depois de iniciado o serviço basta mudar no web.config a opção mode para
stateserver, conforme figura abaixo:
Figura 3 - Configuração do web.config para stateserver.
Podemos agora repetir o teste realizado no modo InProc que ao pausar e
iniciar novamente o serviço do IIS o valor adicionado na sessão será mantido.
SQL Server Mode
Funciona da mesma maneira que o stateserver, porém a sessão é
armazenada no SQL. Para utilizar o SQL Server state é necessário criar as tabelas
em que o Asp.NET irá procurar os dados, para isso o .NET SDK já nos trás um
script pronto o state.sql. O script se encontra no mesmo caminho que o aspstate
modificando somente a versão do framework desejada.
Para executar o script utilizaremos linha de comando no prompt de comando e o
comando osql conforme a figura abaixo:
Figura 4 - Executando o state.sql.
Microsoft Visual C#
73
Após executado o script deve-se reiniciar o serviço do SQL Server para que
os novos serviços criados a partir do state.sql possam também ser iniciados. Em
seguida deve-se alterar o web.config de maneira que fique semelhante ao exemplo
a seguir.
Figura 5 - Configurando o web.config para o SQL Server mode. Se novamente
repetirmos o teste e reiniciarmos o serviço do ISS notaremos que não perdemos o
valor da sessão e desta vez temos um nível de confiança maior, pois dificilmente o
SQL pararia de funcionar e em caso desse servidor parar outro poderia assumir em
sua lugar.
j. Utilizando a Sessão
Depois de configurarmos vamos ver como utilizar a sessão. Primeiramente
vamos abrir o visual Studio e criar um aplicação web utilizando o menu File -> New
Project -> (C# ou VB) Web -> Asp.NET Web Application. Vamos dar o nome do
projeto de "Sessao".
Agora vamos adicionar duas textbox e três botões para podermos verificar o
funcionamento da sessão.
Primeiro iremos adicionar um método que será responsável pela verificação
da variável de sessão que vamos chamar de "variavelSessao" e em caso desta
existir e possuir valor irá passar este valor a txtSessao2.
Microsoft Visual C#
74
Vamos agora adicionar um evento para cada botão e juntamente de cada
um os valores de como inserir, alterar e limpar a sessão.
Inserindo o valor na sessão:
Alterando o valor na sessão:
Ao fazer a alteração no valor que está na sessão também pode ser utilizado
a mesma linha de quando inserimos o valor na sessão, uma vez que se o a variável
já existir ela terá seu valor sobrescrito.
Excluindo o valor na sessão:
Limpando a sessão:
Microsoft Visual C#
75
Para limpar a sessão ainda é possível utilizar o seguinte comando:
Agora no Page_Load vamos acrescer o código que irá verificar o postback e
também verificar o valor da sessão.
Agora que já configuramos e aprendemos a utilizar a Session, devemos
lembrar que não se deve colocar tudo na Session, pois não temos controle de
quanta informação ela pode guardar. A session não é como um array que estoura
quando chega ao seu limite, ela sobrescreve os dados. Fica o conselho de usar a
session quando for tramitar valores entre as páginas ao invés de usar querystrings
e ou ainda utilizá-la para guardar valores temporários como um login de usuário
por exemplo.
Nunca se esqueçam, depois de usarem os valores e não necessitarem mais
dos mesmos, retirem-nos da session!
Como armazenar uma informação temporária e que preciso acessar
rapidamente? Qual o desenvolvedor que nunca se deparou com tal pergunta ou não
sabia o que seria melhor para resolver seu problema.
Session, ViewState e Cache são três grandes ferramentas que podem nos
ajudar nesta tarefa. Mas você deve estar se perguntando qual deles é a melhor
solução? Depende da situação e este artigo visa lhe levar até o caminho da melhor
solução.
Session (sessão) é o período de tempo em que o usuário interage com a
aplicação. Em termos de programação a sessão é a memória em forma de
Microsoft Visual C#
76
dicionário ou ainda de uma tabela hash. Por exemplo, a sessão pode ser um
conjunto de valores-chave que podem ser definidos e lidos por um usuário, durante
a utilização da aplicação web pelo mesmo.
A Session por default no .NET possui um timeout de vinte minutos podendo
ser redefinida (este caso será abordado num próximo artigo). Estes vintes minutos
são contados a partir do momento em que o usuário deixa de interagir com o
sistema, enquanto isso não ocorre este tempo não é válido.
ViewState é um conjunto de informações escondidas mantidas pela página
ASP.NET. Ele monitora as mudanças feitas na página durante o post back.
Nas páginas do ASP.NET o ViewState é habilitado por default para todos os
componentes do .NET Framework e pode ser visto (criptografado) ao término do
carregamento da página .aspx clicando-se com o botão direito do mouse e em
seguida em “Exibir Código Fonte”, após isto basta localizar a tag “_VIEWSTATE”.
Cache também é um tipo de memória, no caso do ASP.NET é a memória da
máquina/servidor onde o código fonte está em execução.
Pode-se verificar a ação do Cache neste momento, ao entrar no site pela
primeira vez o carregamento da página foi um pouco lento e se nesse exato
momento você apertar o botão F5 do seu teclado perceberá que esta página irá
carregar bem mais rápido do que a primeira vez. Isto se deve a ação do Cache, no
primeiro acesso a página o servidor é iniciado e os dados são recebidos pelo seu
computador, que armazena estes dados no Cache permitindo assim que no futuro a
ação seja executada com maior rapidez.
Vantagens:
Session
o Aceita qualquer tipo de variável e pode ser acessada a todo o momento,
lembrando sempre de verificar se o valor adicionado não é nulo ou se ainda a
sessão não for perdida.
o Muito boa para trafegar pequenos dados como algumas variáveis ou
valores de referência.
ViewState
o Excelente para quem deseja armazenar informações numa página que
precisa ser recuperada de maneira rápida e prática, ou ainda algum valor que é de
real importância para a página.
Microsoft Visual C#
77
Cache
o Rapidez na aquisição da informação uma vez que a mesma já se
encontra carregada.
o Possibilidade de configuração para estender o cachê a longos períodos
como horas.
Desvantagens:
Session
o Possui timeout que pode dificultar a recuperação dos dados.
o Deve-se tomar cuidado ao adicionar valores, pois a Session não “estoura”
como um array ela simplesmente sobrescreve os dados.
ViewState
o Não Transporta valores entre as páginas, é único para cada página.
o Não recria dinamicamente os controles da página.
o Não restaura os valores dos controles após o postback.
o Quanto maior o ViewState mais pesada/lenta fica a página.
Cache
o Possibilidade de StackOverFlow se não for bem controlado.
Várias configurações podem ser feitas para estas três ferramentas, mas
estas serão abordadas junto das demonstrações nos próximos artigos.
k. Exercícios
Criando uma autenticação de usuário via código
Usando MasterPage
6. Programação em camadas com C#
Aqui vamos demonstrar passo-a-passo a construção de uma aplicação .Net
utilizando o conceito de desenvolvimento em camadas.
Nosso objetivo é permitir à você praticar o desenvolvimento de uma
aplicação real em .Net para que você adquira habilidades para a construção ou
manutenção de aplicações mais complexas.
Conforme você for evoluindo nos módulos, irá adquirir conhecimentos sobre:
Microsoft Visual C#
78
Comunicação entre as camadas;
Vantagens do modelo de desenvolvimento em camadas;
Controle de transações do banco de dados com o ADO .Net;
Construção de uma aplicação para Windows;
Construção de uma aplicação para a Web;
A importância da segurança no desenvolvimento de aplicações.
A metodologia utilizada será o desenvolvimento em três camadas. Veremos
a diferença entre:
Camada de acesso à dados ou Data Access Layer (DAL);
Camada de regras de negócio ou Business Logic Layer (BLL); e
Camada de interface do usuário ou User Interface (UI).
Microsoft Visual C#
79
Na camada de interface com o usuário reutilizaremos as camadas DAL e BLL
para criarmos dois projetos de interface para o usuário. Um projeto será uma
aplicação que rodará no Microsoft Windows e o outro será uma aplicação para a
Web.
Esse passo-a-passo será usado como exemplos práticos da utilização de
conceitos como: programação orientada a objetos, integridade referencial de banco
de dados, uso de transações via linguagem de programação C# .Net e
implementação de algoritmos de segurança no desenvolvimento de aplicações.
Esse projeto será desenvolvido utilizando os softwares: Microsoft Windows
XP Professional com Microsoft SQL Server 2005 utilizando o Microsoft Visual Studio
2008.
Microsoft Visual C#
80
a. Criando a infra-estrutura de Banco de dados
Para o nosso projeto vamos precisar de uma infra-estrutura simples de
banco de dados com apenas três tabelas: clientes, produtos e vendas.
Se você estiver utilizando o MS SQL Server 2005, poderá abrir o Microsoft
SQL Server Management Studio.
Selecione o servidor de banco de dados e o usuário para realizar a conexão
como a seguir:
Estabelecida a conexão, podemos criar um banco de dados para o nosso
projeto.
Para isso, clique com o botão direito sobre Databases e escolha a opção
“New Database...”
Microsoft Visual C#
81
Vamos dar o nome do nosso database de Loja.
Deixe a configuração padrão para o tamanho inicial dos arquivos de dados e
Log. Clique em Ok para criar o database:
Após clicar em Ok provavelmente precisaremos aguardar alguns segundos
para que o MS SQL Server 2005 crie o banco de dados Loja.
Microsoft Visual C#
82
Quando esta janela de título New Database desaparecer, podemos verificar
que o banco de dados Loja foi criado com sucesso conforme figura abaixo:
Agora que já temos o nosso banco de dados, vamos executar os scripts para
criar as três tabelas necessárias ao nosso projeto.
b. Criando a tabela de Clientes
Clicando com o botão direito sobre o database Loja, escolha a opção New
Query:
Microsoft Visual C#
83
Digite o script SQL abaixo na janela de Query aberta.
CREATE TABLE [CLIENTES] (
[CODIGO] [int] IDENTITY (1, 1) NOT NULL ,
[NOME] [varchar] (100) ,
[EMAIL] [varchar] (100) ,
[TELEFONE] [varchar] (80) ,
CONSTRAINT [PK_CLIENTES] PRIMARY KEY CLUSTERED
(
[CODIGO]
) ON [PRIMARY]
) ON [PRIMARY]
GO
O código deverá ficar assim:
Para executar esse script e criar a tabela de Clientes, clique no botão
Execute:
Se a mensagem “Command(s) completed successfully.” for exibida,
podemos expandir o database Loja e depois expandir Tables para vermos a tabela
CLIENTES que acabamos de criar.
Microsoft Visual C#
84
O campo Código da nossa tabela de Clientes foi criado como Identity e
Primary Key. O que significa isso?
Bem, Primary key (chave primária) é um campo que será único para cada
registro da tabela, ou seja, só existirá um campo com o código igual a 1, só existirá
um campo com o código igual a 2 etc. É um campo que não admite valores
repetidos. Se tentarmos incluir um valor na chave primária já existente na tabela, o
MS SQL Server vai exibir uma mensagem de erro e não permitirá essa inclusão.
A característica Identity desse campo significa que ele será gerenciado pelo
MS SQL Server e nós não precisamos nos preocupar em inserir um valor inexistente
na tabela para evitar a duplicidade. Na prática isso quer dizer que nós nem
precisamos mencionar esse campo nas operações de inserção pois é o gerenciador
de banco de dados que se encarrega de inserir uma chave primária válida.
Vamos inserir um registro na tabela de clientes com o comando a seguir.
Salve o script que acabou de criar em uma pasta de sua preferência e feche-
o. Abra uma nova janela do Query e digite o comando abaixo:
insert into clientes(nome,email,telefone)
values ('Carlos Camacho','[email protected]','(11) 9999-5555')
Clique em Execute para executar o comando de inserção:
Microsoft Visual C#
85
Se a mensagem “1 row(s) affected” for exibida, significa que o registro foi
inserido com sucesso.
Execute o comando de seleção a seguir para visualizarmos o registro que
acabamos de inserir na tabela de Clientes:
Select * from clientes
Perceba que apesar de não mencionarmos o campo Codigo no comando de
insert executado anteriormente, o MS SQL Server providenciou a inserção desse
valor automaticamente.
Se executarmos outro comando de insert, o MS SQL Server vai gerar um
código diferente para inserir no campo Codigo do novo registro.
Microsoft Visual C#
86
Parabéns! Acabamos de preparar a infra-estrutura do nosso projeto com a
tabela de Clientes criada corretamente.
Agora vamos executar o script para criar a tabela de produtos. O processo é
o mesmo. Abra uma nova janela de query e digite o script abaixo. Não se esqueça
de salvar o script anterior.
CREATE TABLE [PRODUTOS] (
[CODIGO] [int] IDENTITY (1, 1) NOT NULL ,
[NOME] [varchar] (100) ,
[PRECO] decimal(10,2) ,
[ESTOQUE] [int] ,
CONSTRAINT [PK_PRODUTOS] PRIMARY KEY CLUSTERED
(
[CODIGO]
) ON [PRIMARY]
) ON [PRIMARY]
GO
Com o script na janela de query, clique em Executar para criarmos a tabela
de produtos.
Microsoft Visual C#
87
Depois que você clicou no Execute apareceu a mensagem “Command(s)
completed successfully.”, mas a tabela PRODUTOS não apareceu em Tables.
Precisamos atualizar o Management Studio para ver a tabela recém-criada.
Para isso, vamos clicar com o botão direito do mouse em Tables e escolher a
opção Refresh:
Veja o Management Studio após o Refresh:
Agora podemos ver a tabela de Produtos.
Microsoft Visual C#
88
Agora nós vamos inserir dois produtos nessa tabela. Abra uma nova janela
de query e digite o código abaixo. Feito isso clique em Execute para a inserção dos
dois produtos.
insert into produtos (nome, preco, estoque)
values ('Computador Pentium Dual Core','1500.00','15')
insert into produtos (nome, preco, estoque)
values ('Impressora Deskjet HP','599.90','150')
Vamos ver o resultado:
Na janela de mensagens podemos ver que os dois registros foram inseridos
com sucesso.
Utilize o comando select para consultar os produtos cadastrados. Abra uma
nova janela do query e digite o comando abaixo e clique em Execute.
select * from produtos
Microsoft Visual C#
89
O resultado é esse:
Agora nós já temos dois produtos cadastrados. Cadastraremos 10
equipamentos com valores e descrição diferentes. Agora a nossa tabela de Produtos
está pronta só falta criarmos a tabela de Vendas!
Para criar a tabela para armazenar as Vendas, abra uma nova janela de
query e digite o comando abaixo e clique em Execute.
CREATE TABLE [VENDAS] (
[CODIGO] [int] IDENTITY (1, 1) NOT NULL ,
[DATA] [datetime],
[QUANTIDADE] [int],
[FATURADO] bit,
[CODIGOCLIENTE] [int],
[CODIGOPRODUTO] [int],
CONSTRAINT [PK_VENDAS] PRIMARY KEY CLUSTERED
(
[CODIGO]
) ON [PRIMARY],
CONSTRAINT [FK_Codigo_Cliente] FOREIGN KEY
Microsoft Visual C#
90
(
[CODIGOCLIENTE]
) REFERENCES [Clientes] (
[Codigo]
),
CONSTRAINT [FK_Codigo_Produto] FOREIGN KEY
(
[CODIGOPRODUTO]
) REFERENCES [Produtos] (
[Codigo]
)
) ON [PRIMARY]
GO
Vejamos o resultado:
Microsoft Visual C#
91
Dê um Refresh clicando com o botão direito tem Tables para que a tabela
de Vendas seja exibida:
A tabela de Vendas que acabamos de criar possui duas foreign keys
(chaves estrangeiras). Essas duas chaves são os campos: CodigoCliente e
CodigoProduto.
Isso significa que quando um registro for inserido nesta tabela, o campo
CodigoCliente incluído deverá existir na tabela de Clientes, assim como o campo
CodigoProduto deverá existir na tabela Produtos.
Se alguém tentar incluir valores nestes campos que não existam nas tabelas
citadas o Microsoft SQL Server vai informar a ocorrência de um erro e não permitirá
a inclusão.
Esse mecanismo do sistema gerenciador de banco de dados existe para
manter a integridade dos dados. Chamamos isso de integridade referencial.
Uma regra que vamos usar no nosso projeto é que ao realizar uma venda,
atualizaremos o estoque do produto na tabela de Produtos. Faremos com que o
estoque fique atualizado com a seguinte fórmula:
Estoque = Estoque – Quantidade Vendida .
Essa tarefa será realizada juntamente com a tarefa de inclusão da Venda na
tabela de Vendas.
Microsoft Visual C#
92
Assim, para manter a integridade dos dados, precisaremos garantir que as
duas coisas aconteçam: a inclusão na tabela de Vendas e a atualização do estoque
na tabela de Produtos. Para isso usaremos uma Transação. Com a transação
podemos garantir a execução das duas tarefas. Se uma delas for bem sucedida e a
outra falhar, a transação desfaz a primeira tarefa mantendo assim a integridade
referencial. Em outras palavras, não exisitirá na tabela de Vendas um registro que
tenha o código do produto vendido mas que o estoque deste produto na tabela de
Produtos esteja desatualizado.
Veremos isso com mais detalhes nas próximas definições em “Camada de
Acesso a Dados (Data Access Layer)”. Implementaremos as classes de acesso a
dados e faremos esse controle transacional no método Incluir da classe de Vendas.
Para futura utilização no nosso projeto, precisaremos guardar as seguintes
informações sobre o banco de dados:
Nome do servidor de banco de dados que estamos usando;
Nome do banco de dados onde as três tabelas foram criadas;
Nome do usuário e senha utilizados para acessar o banco de dados.
Essa informação é importante para a construção da nossa string de
conexão ou connectionstring. A connectionstring será usada para a conexão
com o banco de dados através da aplicação que desenvolveremos neste projeto.
Um bom site para consulta sobre a correta connectionstring que devemos
utilizar é o http://www.connectionstrigs.com/. Neste site existem dicas para criar
connectionstrings para diferentes versões de bancos de dados.
No nosso caso, se fecharmos a janela de Query que estávamos usando,
poderei ver o nome do servidor de banco de dados que estamos usando, conforme
demonstra a figura a seguir.
Microsoft Visual C#
93
Abaixo segue informações para conexão com nosso servidor do SQL Server
Express.
Nome do Servidor: MAQ-607567\SQLEXPRESS
Nome do banco de dados: Loja
Usuário: ittraining
Senha: csharp
Assim, a nossa connectionstring ficará assim:
"server=MAQ-
607567\SQLEXPRESS;database=Loja;user=ittraining;pwd=csharp"
A sua connectionstring vai depender dos nomes que você usou para:
- Criar o servidor de banco de dados;
- Criar o banco de dados;
- Criar usuário e senha que terão acesso ao banco de dados.
c. Camada de Acesso a Dados
Essa camada é normalmente também chamada de DAL (Data Access Layer).
Nessa camada vamos implementar os métodos de inserção, atualização, exclusão e
listagem referentes a todas as tabelas existentes no nosso projeto.
Essa é uma tarefa simples, já que para criar cada classe usaremos os nomes
dos campos da respectiva tabela existente no banco de dados.
Microsoft Visual C#
94
Você se lembra do nosso desenho que representa as três camadas? Aqui
está ele:
Nós começamos o desenvolvimento da aplicação da camada mais interna até
a mais externa. Dessa forma, iniciaremos a implementação com a camada de
acesso a dados (DAL). Dentro da camada DAL nós temos o projeto Modelos. Agora
vamos criar um projeto chamado Modelos iremos implementar as classes:
ClienteInformation.cs
ProdutoInformation.cs e
VendaInformation.cs
É necessário criar uma classe para cada tabela do nosso projeto.
Microsoft Visual C#
95
A partir do menu Iniciar > Programas > Microsoft Visual Studio 2008, abra o
Microsoft Visual Studio 2008.
Clique no Menu File > New > Project...
Acompanhe as seleções da janela New Project:
No tipo de projeto selecione Visual C#;
No tipo de template selecione Class Library;
No Nome do projeto digite Modelos;
Microsoft Visual C#
96
Na localização do projeto digite C:\Loja;
Deixe a opção “Create directory for solution” selecionada e clique em Ok
para criar o projeto. Abrindo o Windows Explorer, podemos ver que a pasta Loja foi
criada no drive C:
Dentro da pasta Loja foi criada a pasta do projeto Modelos.
Ok, agora vamos voltar para o MS Visual Studio e do lado direito vemos a
área do Solution Explorer.
Clique com o botão direito sobre o arquivo Class1.cs e escolha Rename
para renomear a classe para ClienteInformation.cs.
Ao renomear o arquivo da classe, perceba que o nome da classe muda
automaticamente na janela de código (public class ClienteInformation).
Na janela de código à esquerda, inclua o nome do nosso projeto (Loja) no
namespace, de maneira que o namespace fique Loja.Modelos como na figura a
seguir.
Microsoft Visual C#
97
Vamos codificar a classe ClienteInformation. Para isso, digite o código
abaixo entre as chaves da classe ClienteInformation:
private int _codigo; public int Codigo { get { return _codigo; } set { _codigo = value; } } private string _nome; public string Nome { get { return _nome; } set { _nome = value; } } private string _email; public string Email { get { return _email; } set { _email = value; } } private string _telefone; public string Telefone { get { return _telefone; } set { _telefone = value; }
}
Na implementação da classe ClienteInformation vemos que estamos
definindo campos e propriedades para cada campo da tabela de Clientes que
criamos no banco de dados.
Microsoft Visual C#
98
Agora a codificação da classe ClienteInformation está completa como na
listagem a seguir:
using System; using System.Collections.Generic; using System.Text; namespace Loja.Modelos { public class ClienteInformation { private int _codigo; public int Codigo { get { return _codigo; } set { _codigo = value ; } } private string _nome; public string Nome { get { return _nome; } set { _nome = value ; } } private string _email; public string Email { get { return _email; } set { _email = value ; } } private string _telefone; public string Telefone { get { return _telefone; } set { _telefone = value ; } } }
}
Vamos implementar a Classe ProdutoInformation.cs.
Clique com o botão direito sobre o projeto Modelos e então escolha Add.
Em seguida escolha New Item... como na figura abaixo:
Microsoft Visual C#
99
Na janela Add New Item, escolha o template Class e digite
ProdutoInformation.cs no campo nome. Clique em Add para adicionar a nova
classe ao projeto Modelos.
A nova classe ProdutoInformation.cs agora já esta criada:
Microsoft Visual C#
100
Altere o namespace de modo que ele fique assim:
namespace Loja.Modelos
Ok. Agora copie e cole o código abaixo dentro da classe ProdutoInformation:
private int _codigo; public int Codigo { get { return _codigo; } set { _codigo = value ; } } private string _nome; public string Nome { get { return _nome; } set { _nome = value ; } } private decimal _preco; public decimal Preco { get { return _preco; } set { _preco = value ; } } private int _estoque; public int Estoque { get { return _estoque; } set { _estoque = value ; }
}
O código completo da nossa classe ProdutoInformation.cs ficará assim:
using System; using System.Collections.Generic; using System.Text; namespace Loja.Modelos { public class ProdutoInformation { private int _codigo; public int Codigo { get { return _codigo; } set { _codigo = value ; } } private string _nome; public string Nome { get { return _nome; } set { _nome = value ; } } private decimal _preco; public decimal Preco { get { return _preco; } set { _preco = value ; } } private int _estoque; public int Estoque { get { return _estoque; } set { _estoque = value ; } } }
}
Microsoft Visual C#
101
Muito bem, já implementamos as classes do projeto Modelo para a tabela
de Clientes e para a tabela de Produtos. Agora vamos fazer o mesmo para a
tabela de Vendas:
Clique com o botão direito sobre o projeto Modelos e então escolha Add.
Em seguida escolha New Item... como na figura abaixo:
Na janela Add New Item, escolha o template Class e digite
VendaInformation.cs no campo nome. Clique em Add para adicionar a nova
classe ao projeto Modelos.
Microsoft Visual C#
102
A nova classe VendaInformation.cs agora já esta criada:
Altere o namespace de modo que ele fique assim:
namespace Loja.Modelos
Ok. Agora copie e cole o código abaixo dentro da classe VendaInformation:
private int _codigo; public int Codigo { get { return _codigo; } set { _codigo = value; } } private DateTime _data; public DateTime Data { get { return _data; } set { _data = value; } } private int _quantidade; public int Quantidade { get { return _quantidade; } set { _quantidade = value; } } private bool _faturado; public bool Faturado {
Microsoft Visual C#
103
get { return _faturado; } set { _faturado = value; } } private int _codigoCliente; public int CodigoCliente { get { return _codigoCliente; } set { _codigoCliente = value; } } private int _codigoProduto; public int CodigoProduto { get { return _codigoProduto; } set { _codigoProduto = value; } } private string _nomeCliente; public string NomeCliente { get { return _nomeCliente; } set { _nomeCliente = value; }
}
O código completo da nossa classe VendaInformation.cs ficará assim:
using System; using System.Collections.Generic; using System.Text; namespace Loja.Modelos { public class VendaInformation { private int _codigo; public int Codigo { get { return _codigo; } set { _codigo = value ; } } private DateTime _data; public DateTime Data { get { return _data; } set { _data = value ; } } private int _quantidade; public int Quantidade { get { return _quantidade; } set { _quantidade = value ; } } private bool _faturado; public bool Faturado { get { return _faturado; } set { _faturado = value ; } } private int _codigoCliente; public int CodigoCliente { get { return _codigoCliente; } set { _codigoCliente = value ; } } private int _codigoProduto; public int CodigoProduto { get { return _codigoProduto; } set { _codigoProduto = value ; } } private string _nomeCliente;
Microsoft Visual C#
104
public string NomeCliente { get { return _nomeCliente; } set { _nomeCliente = value ; } } }
}
Agora que implementamos no projeto Modelos as classes referentes a todas
as tabelas contempladas no nosso projeto, vamos compilar o projeto através da
opção Build.
Para compilar o projeto vamos fazer o seguinte. No Solution Explorer,
clique com o botão direito sobre o projeto Modelos e escolha a opção Build:
Se a compilação do nosso projeto for realizada com sucesso, aparecerá a
mensagem “Build succeeded” na barra de status do Microsoft Visual Studio
conforme figura a seguir.
Microsoft Visual C#
105
No Windows Explorer, observe que na pasta do projeto Modelos foi criado
um arquivo para cada classe que implementamos.
Quando compilamos o projeto com a opção Build, o MS Visual Studio criou o
arquivo Modelos.dll.
O arquivo Modelos.dll contém toda a informação que implementamos nas
classes desse projeto e é ele que será usado no próximo projeto a ser
implementado, que é a Camada de Acesso a Dados ou DAL (Data Access Layer).
Microsoft Visual C#
106
Após terminar o projeto Modelos, muitos programadores costumam criar um
Diagrama de Classes para ter uma visão melhor do seu projeto então agora
vamos criar o Diagrama de Classe.
De volta ao Visual Studio, clique com o botão direito sobre o projeto
Modelos e escolha Add > New Item...
Na janela Add New Item, escolha o template Class Diagram. Digite
Modelos.cd no nome e clique em Add para criar o nosso diagrama de classes
como a seguir.
Microsoft Visual C#
107
O ambiente chamado Class Designer é exibido.
Para a criação do diagrama vamos arrastar as classes ClienteInformation,
ProdutoInformation e VendaInformation do Solution Explorer para o Class
Designer (Arquivo Modelos.cd) como a seguir:
Microsoft Visual C#
108
Com o Diagrama de Classes fica fácil a distinção entre os campos e as
propriedades que implementamos no nosso projeto.
O asterisco ao lado do nome do diagrama Modelos.cd* indica que ele ainda
não foi salvo. Digite <Ctrl> + S para salvar o arquivo.
d. Implementar as classes da Camada DAL (Data Access Layer).
Jà criamos as classes referente aos Modelos, agora iremos criar as as classes
que pertencem a camada de dados. Iremos criar um novo projeto chamado DAL e
dentro dele adicionar as seguintes classes:
ClientesDAL.cs
ProdutosDAL.cs
VendasDAL.cs
Dados.cs
Você verá que a classe ClientesDAL, por exemplo, conterá os métodos de
inclusão, alteração, exclusão e consulta referentes a tabela de Clientes. O mesmo
ocorrerá para as classes ProdutosDAL e VendasDAL.
Microsoft Visual C#
109
Usaremos a classe Dados para armazenarmos a string de conexão com o
banco de dados. Para começar você deve abrir nosso projeto de Modelos que
criamos no item anterior.
- Vamos adicionar um novo projeto. No menu File do Visual Studio, clique
em Add > New Project...
Na janela Add New Project:
- Escolha Visual C# para o tipo de projeto;
- Class Library para o template;
- Digite DAL no campo nome;
- Digite C:\Loja\DAL na localização;
- Clique em Ok para adicionar o novo projeto à nossa Solution (solução).
Nota: Quando temos um conjunto de projetos reunidos para atender uma
necessidade chamamos esse conjunto de Solution.
Microsoft Visual C#
110
Agora o nosso projeto DAL foi adicionado à nossa Solution conforme mostra
a figura a seguir.
Microsoft Visual C#
111
O nome da nossa Solution está como Modelos porque o MS Visual Studio usa
o nome do primeiro projeto criado.
No Solution Explorer, clique com o botão direito sobre a Solution ‘Modelos’ e
escolha a opção Rename. Renomeie a Solution para Loja.
Depois que você renomear a nossa Solution, ela ficará assim:
No projeto DAL, renomeie a classe Class1.cs para ClientesDAL.cs e altere
o namespace para namespace Loja.DAL.
Microsoft Visual C#
112
A nossa classe ClientesDAL ficará assim:
Você se lembra quando comentamos que a nossa implementação
aconteceria da camada mais interna para a mais externa do desenho do nosso
projeto? Abaixo segue a ordem em que os projetos serão criados.
[Modelos] – DAL – BLL - User Interface
O projeto Modelos é o mais interno e o próximo é a camada de acesso a
dados DAL. Isso significa que o nosso projeto DAL poderá usar tudo o que já foi
construído no projeto Modelos.
Microsoft Visual C#
113
Em termos de programação, dizemos que o projeto DAL faz referência ao
projeto Modelos. Para que o nosso projeto DAL consiga ver o que já construímos
no projeto Modelos, vamos criar essa referência.
Abra a pasta References do projeto DAL para ver o que já existe como
referência sempre que criamos um novo projeto:
Precisamos incluir no projeto DAL uma referência para o Modelos. Faça o
da seguinte forma. Clique com o botão direito na pasta References do projeto DAL
e escolha Add Reference conforme mostra a figura a seguir.
Microsoft Visual C#
114
Na janela Add Reference que abrirá, clique na aba Projects:
Microsoft Visual C#
115
Veremos o nosso projeto Modelos. Clique sobre ele para selecioná-lo e então
clique em Ok para criar a referência.
Muito bom, agora já podemos ver a referência para o nosso projeto
Modelos dentro do nosso projeto DAL como a seguir:
Microsoft Visual C#
116
Para enxergar os Modelos dentro da nossa classe ClientesDAL vamos
adicionar a cláusula using como segue:
Após digitarmos using Loja. (coloque o ponto após digitar Loja) perceba que
o MS Visual Studio já nos mostra as referências disponíveis. Com as setas de
direção posicione a seleção em Modelos e dê um ENTER para selecioná-lo.
Microsoft Visual C#
117
Aquele tracinho vermelho após Loja.Modelos indica que há algo errado. É o
comando using que não foi fechado. Para fechá-lo devemos digitar “;”. Então digite
ponto-e-vírgula ( ; ) para fechar o comando using:
Microsoft Visual C#
118
Para que tenhamos acesso as definições do namespace do MS SQL Server,
vamos inserir mais uma cláusula using para System.Data.SqlClient como a
seguir:
Microsoft Visual C#
119
Para o código da classe ClientesDAL digite o código abaixo entre as chaves
da classe:
public void Incluir(ClienteInformation cliente) { //conexao SqlConnection cn = new SqlConnection(); try { cn.ConnectionString = Dados.StringD eConexao; //command SqlCommand cmd = new SqlCommand(); cmd.Connection = cn; cmd.CommandText = "insert into Clientes(nome,email,telefone) values (@nome,@email, @telefone); select @@IDENTITY;"; cmd.Parameters.AddWithValue( "@nome", cliente.Nome); cmd.Parameters.AddWithValue( "@email" , cliente.Email); cmd.Parameters.AddWithValue( "@telefone" , cliente.Telefone); cn.Open(); cliente.Codigo = Convert .ToInt32(cmd.ExecuteScalar()); } catch (SqlException ex) { throw new Exception ( "Servidor SQL Erro:" + ex.Number);
Microsoft Visual C#
120
} catch ( Exception ex) { throw new Exception (ex.Message); } finally { cn.Close(); } } public void Alterar(ClienteInformation cliente) { // conexao SqlConnection cn = new SqlConnection(); try { cn.ConnectionString = Dados.StringD eConexao; SqlCommand cmd = new SqlCommand(); cmd.Connection = cn; cmd.CommandType = CommandType.Text; cmd.CommandText = "update Clientes set nome = @nome, email = @email, telefone = @telefone where codigo = @codigo;" ; cmd.Parameters.AddWithValue( "@codigo" , cliente.Codigo); cmd.Parameters.AddWithValue( "@nome", cliente.Nome); cmd.Parameters.AddWithValue( "@email" , cliente.Email); cmd.Parameters.AddWithValue( "@telefone" , cliente.Telefone); cn.Open(); cmd.ExecuteNonQuery(); } catch (SqlException ex) { throw new Exception ( "Servidor SQL Erro:" + ex.Number); } catch ( Exception ex) { throw new Exception (ex.Message); } finally { cn.Close(); } } public void Excluir( int codigo) { //conexao SqlConnection cn = new SqlConnection(); try { cn.ConnectionString = Dados.StringD eConexao; //command SqlCommand cmd = new SqlCommand(); cmd.Connection = cn; cmd.CommandText = "delete from Clientes where codigo = " + codigo; cn.Open(); int resultado = cmd.ExecuteNonQuery(); if (resultado != 1) { throw new Exception ( "Não foi possível excluir o cliente " + codigo); } } catch (SqlException ex) { throw new Exception ( "Servidor SQL Erro:" + ex.Number); } catch ( Exception ex) { throw new Exception (ex.Message); } finally { cn.Close(); } } public DataTable Listagem() { DataTable tabela = new DataTable(); SqlDataAdapter da = new SqlDataAdapter( "select * from clientes" , Dados.StringDeConexao);