Quando alguém aprende a ler e escrever em um novo idioma, geralmente esse aprendizado inclui, pelo menos:
-
Vocabulário — as palavras do idioma.
-
Gramática — como organizar as palavras corretamente, da forma aceita por todos. Isso inclui conhecimentos como estrutura adequada das frases e pontuação.
-
Compreensão — compreender o significado do que está escrito. Compreender significa entender.
Os mesmos princípios básicos se aplicam quando é preciso aprender a ler e escrever em uma linguagem de computação. Há algumas palavras básicas e outros elementos que são as peças usadas para compor seus programas. Você combina essas peças de formas específicas, criando conjuntos semelhantes a frases, inclusive com marcas de pontuação. Tudo isso se destina a transmitir determinado significado ao computador.
Não vamos dividir nossas lições usando exatamente os mesmos cabeçalhos acima, mas você verá esses aspectos surgirem nos capítulos seguintes.
Vocabulary
Assim como nos idiomas, o C# tem um determinado número de palavras que participam diretamente da linguagem. Mas há palavras adicionais, exteriores à linguagem, cuja inclusão é permitida.
Em português, você poderia escrever: "Um gorila chamado Juju vive na floresta de Uganda." A maioria dessas palavras faz parte do idioma português, e você pode encontrá-las no dicionário. Mas as palavras "Juju" e "Uganda" não, pois são nomes próprios. Isso significa que a frase está incorreta? Não, pois é permitido usar palavras:
-
da lista de todos os nomes de seres humanos e animais;
-
da lista oficial de nomes de países;
-
...e de muitas outras listas de palavras.
Da mesma forma, mencionaremos palavras que participam diretamente da linguagem C#. Mas isso não significa que você usará somente essas palavras em seus programas. Dependendo do que quiser expressar, provavelmente você utilizará muitas palavras extras, emprestadas de outras listas, bibliotecas, etc. A Microsoft, em particular, escreveu uma vasta biblioteca de código chamada biblioteca de classes .NET Framework, que você com certeza utilizará nos seus programas em C#. Ela contém muitos nomes de classes, campos e métodos que não são internos ao C#, mas que você pode usar nos seus programas em C#.
Você mesmo definirá novas classes, campos e métodos, atribuindo-lhes nomes — e esses nomes se tornarão palavras que você terá permissão para usar nos programas em C#. É como criar um novo nome, "PatasRajadas", para o seu animal de estimação. Então, você estará autorizado a usar esse nome em frases em português.
Eis aqui algumas palavras internas à linguagem. Algumas delas, você precisará conhecer para escrever programas básicos. Todas são mencionadas neste livro.
-
class
-
do
-
else
-
false
-
for
-
if
-
int
-
new
-
null
-
private
-
protected
-
public
-
return
-
static
-
string
-
this
-
true
-
using
-
void
-
while
Essa não é uma lista completa, mas não se preocupe: não há muitas palavras em C# além dessa lista. As linguagens de computação tendem a ter muito menos palavras do que os idiomas.
O que você faz com as palavras que compõem um idioma? Você as combina em frases bem estruturadas, de acordo com certas regras. Isso se chama gramática. Esse é o assunto dos demais capítulos desta seção.
Some General Grammar Rules
Neste capítulo, abordamos algumas informações gerais sobre a gramática no C#. Em termos técnicos, isso é geralmente chamado de sintaxe.
Capital and Small Letters
A linguagem C# diferencia maiúsculas de minúsculas. Isso significa que você precisa usar as letras minúsculas e maiúsculas nos lugares certos.
Palavras internas
As palavras-chave listadas no capítulo anterior precisam ser sempre escritas exatamente como são mostradas aqui. Você deve ter percebido que todas estão em letras minúsculas.
Então, se você escrever "If" ou "IF" em vez de "if", o computador simplesmente se recusará a prosseguir, pois não entenderá o que você escreveu se não estiver de acordo com as regras.
Mas não o julgue com tanto rigor, afinal, ele tem alguns pontos fortes que nós não temos. Por exemplo, é capaz de lembrar-se de tudo o que você já disse a ele nos últimos 10 anos em uma fração de segundo! Consegue fazer isso? Humm, não vai poder se vangloriar agora, não é? Mas estamos fugindo do assunto. Vamos retomar o raciocínio.
Nomes criados por você
E quanto às palavras criadas por você? Imagine, por exemplo, que você criou uma classe chamada "myClass", com um campo chamado "numberOfSpots".
class myClass
{
int numberOfSpots;
}
O uso de maiúsculas e minúsculas importa? A resposta, logicamente, é "sim". Sempre que você mencionar esses nomes em um programa em C#, precisará escrevê-los exatamente como foram originalmente definidos. O código a seguir, por exemplo, falhará.
class myClass
{
// Field
int numberOfSpots;
// Method
public void Main()
{
MyClass x = new MyClass();
x.NUMBEROFSPOTS = 365;
}
}
Mas, escrito da seguinte forma, o código será executado corretamente:
class myClass
{
// Field
int numberOfSpots;
// Method
public void Main()
{
myClass x = new myClass();
x.numberOfSpots= 365;
}
}
Então, embora você possa optar por escrever um nome de classe, campo, método etc. com uma combinação de letras maiúsculas e minúsculas (NUMBEROFSPOTS, numberofspots ou NuMbErOfSpOtS etc.), é muito importante que continue a escrever esse nome exatamente da mesma forma em todo o programa.
Statements
Em português, temos períodos, declarações, orações, frases etc. Todas são diferentes formas de combinar palavras. Cada uma termina com uma marca de pontuação específica. Um período termina com ponto (também chamado de ponto final). Uma oração pode terminar com ponto-e-vírgula (;).
No C#, isso é um pouco mais simples. Basicamente, usamos instruções, que em geral terminam com ponto-e-vírgula.
Aqui, por exemplo, temos um trecho de código com quatro instruções:
string x;
x = "Nobody wins in war";
myClass m = new myClass();
m.numberOfSpots = 3;
Você dirá que isso é óbvio, pois há quatro linhas. Mas o computador não percebe a divisão em linhas como nós. Para ele, não terá importância se escrevermos as quatro instruções em uma linha muito longa.
string x; x = "Nobody wins in war"; myClass m = new myClass(); m.numberOfSpots = 3;
Essa é a importância do ponto-e-vírgula. O computador sabe que escrevemos quatro coisas distintas na linha, pois encerramos cada uma delas com ponto-e-vírgula. Aliás, não escreva diversas instruções em uma só linha dessa forma, pois os seres humanos estão acostumados com a separação em linhas, e você deve tentar manter seu código o mais legível possível para seres humanos.
Posso apostar que muitos erros encontrados nos seus programas ocorrem porque você se esqueceu de encerrar uma instrução com ponto-e-vírgula. Mas, depois de se esquecer disso umas 5 mil vezes, você provavelmente vai adquirir o hábito. Felizmente, o Visual C# Express é inteligente o bastante para perceber que você deixou de lado detalhes como esse, usando uma linha vermelha ondulada ou outro mecanismo para mostrar como você foi distraído.
Code Blocks - Grouping Statements Together
| Em português, usamos parágrafos para agrupar períodos diretamente relacionados. No C#, usamos as chaves "{" e "}" de forma semelhante aos parágrafos. As chaves são usadas para iniciar e encerrar um bloco que agrupa várias instruções. Vejamos um exemplo. Suponha que temos um programa que faz perguntas ao usuário e verifica as respostas. Suponha que queremos fazer somente duas coisas se alguém responder corretamente. Podemos escrever código desta forma: if ( userAnswer == correctAnswer ) As duas instruções entre chaves serão executadas se a resposta do usuário for correta, pois foram agrupadas em um bloco. Você já viu muitos outros exemplos de código entre chaves neste livro. Sempre que uma classe é definida, você coloca todo o seu código entre chaves: class MyClass E, quando escreve um método na sua classe, você também agrupa suas instruções entre chaves: class MyClass |
Comments - Helping the Humans Out
Você já deve ter percebido que muitos livros têm notas ou comentários escritos nas laterais ou na parte inferior das páginas. Esses comentários não fazem parte do texto principal, mas geralmente são informações extras que explicam em mais detalhes algum aspecto do texto principal.
Você deve estar imaginando se pode fazer o mesmo nos seus programas de computação, e pode. Muitas vezes, você vai querer escrever comentários para você mesmo ou para outros programadores, a fim de explicar as características do seu código. Na verdade, esse é considerado um bom comportamento entre os programadores. É claro que um programador deve ser capaz de descobrir o que acontece em um programa, mas não é preciso perder tempo com isso se um breve comentário em inglês pode fornecer rapidamente uma explicação básica do que o código faz.
E se você estiver pensando, "sou a única pessoa que vai ler o meu código", acredite que, quando voltar ao programa depois de alguns meses, vai lamentar não ter comentado seu próprio código.
Como esses comentários se destinam a pessoas, e não ao computador, é preciso dizer ao computador, de alguma forma, para ignorar o que for escrito na seção de comentários. Você precisa "ocultar" esses comentários dos "olhares digitais".
Há duas formas de fazer isso:
-
Para comentários escritos em uma só linha, você pode simplesmente colocar duas barras // no início da linha.
-
É possível ocultar do computador os comentários que ocupam mais de uma linha iniciando-os com /* e encerrando-os com */.
O trecho de código a seguir mostra os dois tipos de comentários, usados de formas diferentes:
void DrawCircleInSquare( int left, int top, int size)
/*
This is a method for drawing a red circle.
Pass the size of the circle in the 'size' parameter.
Pass the position to draw at in the 'left' and 'top' parameters.
*/
{
Graphics g = this.CreateGraphics(); // Prepare drawing surface
Pen redPen = new Pen(Color.Red, 3); // Use a red pen
// Draw a square (a rectangle with equal width & height)
g.DrawRectangle( redPen, left, top, size, size );
// Draw a circle (an ellipse with equal width & height)
g.DrawEllipse( redPen, left, top, size, size );
// Clean up
g.Dispose();
}
Quando o computador encontra //, ele ignora tudo o que há no restante da linha. Quando encontra /*, ele ignora tudo até o próximo */.
Indenting Your Code
É provável que você já tenha percebido que tendemos a incluir recuos no código, da seguinte forma:
if ( userAnswer == correctAnswer )
{
Console.WriteLine( "That is correct" );
score = score + 1;
if ( score > 10 )
{
Console.WriteLine( "You have qualified!" );
}
else
{
Console.WriteLine( "Bugger. Keep going ..." );
}
}
Fazemos isso em vez de escrever o código todo misturado, desta forma:
if ( userAnswer == correctAnswer )
{
Console.WriteLine( "That is correct" );
score = score + 1;
if ( score > 10 )
{
Console.WriteLine( "You have qualified!" );
}
else
{
Console.WriteLine( "Bugger. Keep going ..." );
}
}
O objetivo é tornar claro onde um bloco específico de código começa e termina. À medida que seus programas se tornarem mais longos, será cada vez mais difícil ver o início e o final de um bloco. Os recuos facilitam muito a leitura do código e de seu significado.
Deixar de utilizar recuos não interrompe o código, pois os recuos não são uma exigência gramatical. No entanto, são considerados uma "prática recomendada" e convém criar esse hábito.
Para recuar o código ao escrever no C# Express, você pode selecionar uma ou mais linhas de código e clicar na tecla TAB do teclado. Se precisar fazer o oposto, mantenha pressionada a tecla SHIFT e pressione TAB. Como alternativa, é possível clicar nos
ícones da barra de ferramentas.
Variables
A palavra "variável" significa "algo que pode ser alterado". Uma variável é um elemento cujo valor pode mudar.
Eis uma forma típica de uso de variável. Escolhemos, neste caso, chamar a variável de "theAnswer", pois queremos que ela contenha a resposta de uma soma, embora pudéssemos escolher qualquer outro nome.
int addPositiveNumbers( int x, int y )
{
int theAnswer;
if ( (x>0) && (y>0) ) // If x and y are positive numbers
{
theAnswer = x + y; // Add them & put the sum into answer
}
else // Otherwise
{
theAnswer = 0; // Put zero into answer
}
return theAnswer ;
}
Nesse exemplo, a variável "theAnswer" é usada para reter a soma do que for passado nos parâmetros x e y. No final, enviamos de volta o valor que estiver retido em theAnswer.
É interessante observar que "theAnswer" é, na verdade, apenas um local na memória do computador. Quando o computador se depara com a linha "int theAnswer", ele encontra um ponto livre na sua memória e o nomeia como "theAnswer". Quando alcança a linha "return theAnswer", ele busca o número que estava armazenado no local chamado "theAnswer". No exemplo acima, como já terminou tudo o que deveria fazer, o computador libera aquele espaço na memória para outras finalidades.
Na verdade, não é tão estranho
Quando nós, humanos, trabalhamos com nosso cérebro, também usamos locais na memória para reter respostas; só que fazemos isso quase sem perceber. Imagine que alguém peça a você para:
-
somar os números 10, 20 e 50;
-
depois, multiplicar a resposta por 2.
Provavelmente, você faria o seguinte:
-
Resolver a soma 10 + 20. Reter a resposta (30) na sua memória.
-
Resolver a soma 30 + 50. Reter a nova resposta (80) na sua memória.
-
Resolver a multiplicação 80 x 2. Reter a resposta na sua memória até estar pronto para transmiti-la à pessoa que fez a pergunta.
-
Depois de fazer o que precisava, você deixa de se esforçar tanto para lembrar-se da resposta, afinal, ela não tem mais valor. Em vez disso, você libera sua memória para ser usada em outras coisas.
Então, não somos tão diferentes dos nossos amigos digitais.
As variáveis são sempre de um tipo específico
Na verdade, uma variável é muito parecida com um campo ou um parâmetro, exceto pelo fato de não ter nenhuma relação direta com uma classe ou um objeto específico — precisamos apenas de um local temporário para armazenar algum elemento, de forma a poder trabalhar com ele.
Mas as variáveis, assim como os campos (que são, na verdade, uma espécie de variável), são sempre de um tipo específico. Por exemplo:
string myString;
int theAnswer;
bool isFinished;
Se você ainda não leu o capítulo "Os campos e seus tipos", deveria lê-lo para compreender melhor os "tipos".
Operators
Suponha que você escreva o seguinte em um dos seus programas:
int theAnswer = x + y;
E, em outro lugar, escreva:
int theAnswer = x - y;
No primeiro caso, você está usando o símbolo de adição e, no segundo caso, o de subtração. Essas ações realizadas com números são chamadas de operações e seus símbolos + e - são chamados de operadores, pois operam nos elementos. Um operador toma um ou mais elementos, opera neles e apresenta um valor resultante.
A figura a seguir ilustra o operador de adição atuando em 2 números. Neste exemplo, ele toma os valores 5 e 2 como entrada e apresenta como resultado o valor 7.
E aqui está o operador de subtração, tomando os mesmos valores como entrada, mas apresentando um valor diferente como resultado:
Todas as linguagens de computação têm pelo menos alguns operadores, e é muito importante familiarizar-se com eles. Então, vamos abordar aqueles que você provavelmente verá com freqüência no C#.
| Símbolo | Operação | Explicação |
| + | somar 2 elementos |
Por exemplo, "how" + " are" + " you" produz a cadeia de caracteres mais longa "how are you". |
| - | subtrair dois elementos |
|
| / | dividir |
|
| * | multiplicar |
|
| > | Maior do que |
|
| < | Menor do que |
|
| = | Definir como igual a |
|
| = = | Testar se é igual a |
|
| <= | Menor ou igual a |
|
| >= | Maior ou igual a |
|
| ! | Não |
|
| != | Diferente de |
|
| && | E |
|
| || | Ou |
|
| ++ | incrementar |
Também é possível escrever ++x (chamada de notação prefixada) em vez de x++ (chamada de notação pós-fixada), mas essas duas notações podem ter efeitos diferentes. Eis um exemplo que revela a diferença entre elas: int x = 15; Os resultados exibidos pelo código acima seriam: 15 |
| -- | decrementar |
Assim como ocorre com o operador ++, você pode escrever --x em vez de x--. Eis um exemplo que mostra a diferença de efeito entre as duas notações. int x = 15; Os resultados exibidos pelo código acima seriam: 15 |
Vamos concluir com mais uma figura, que ilustra o funcionamento de um operador como "--". Neste caso, o operador toma somente um número como entrada e apresenta um número como resultado. O número apresentado como resultado tem 1 a menos do que o número de entrada.
Converting Between Types
Suponha que incluímos o seguinte código em um programa:
// Declare some variables
int x;
string y;
int z;
// Put values into x and y
x = 5;
y = "17";
// Calculate the product of x and y and put the answer into z
z = x * y;
A última linha acima causaria um erro: o computador reclamaria porque não é possível multiplicar cadeias de caracteres, e y é um tipo de cadeia de caracteres. O código mostrado acima significa o mesmo que dizer: "Quanto é 17 multiplicado por engraçado?” Simplesmente não é possível fazer esse cálculo. As cadeias de caracteres não são tipos numéricos e você não pode realizar nenhuma operação matemática com elas.
Felizmente, é possível converter cadeias de caracteres em números. O exemplo a seguir mostra como você poderia contornar esse problema, pois a cadeia de caracteres "5" seria facilmente convertida no número 5. Bastaria uma pequena alteração na última linha.
z = x * Convert.ToInt32( y );
O que fizemos foi usar a classe da Microsoft chamada "convert" e chamar seu método "ToInt32", que faz a conversão para um dos tipos inteiros. Agora que y foi convertido em um número inteiro, o computador multiplicará os dois números sem problemas.
A classe "convert" tem muitos outros métodos, mas você precisará com mais freqüência dos seguintes:
-
Convert.ToInt32()
-
Convert.ToString()
-
Convert.ToBoolean()
É importante lembrar-se de como os computadores são meticulosos em relação aos tipos.
Transmissão
Outra forma de alterar valores de um tipo para outro é com o uso de um recurso chamado transmissão. Transmitir algo significa convertê-lo em um tipo diferente. Só que, ao contrário dos exemplos de "convert" acima, a transmissão só funciona quando o tipo a partir do qual é feita a alteração é muito semelhante ao tipo para o qual é feita a alteração. Isso é útil, por exemplo, para fazer a conversão entre dois tipos numéricos, mas é inútil para a conversão entre um número e uma cadeia de caracteres. A forma como você escreve uma transmissão também é muito diferente dos exemplos acima. Antes da variável que você deseja converter, é preciso escrever, entre parênteses, o tipo para o qual deseja fazer a conversão.
Para mostrar um exemplo, precisamos apresentar um outro tipo numérico: vamos usar o tipo chamado "double". Se você já aprendeu notação científica na escola, nas aulas de matemática ou ciências, encontrará muitas semelhanças com os tipos "double" e "float": eles possibilitam trabalhar com números decimais, permitindo um ponto decimal "flutuante". Por exemplo, 5,0 x 103 é o mesmo número que 50,0 x 102 ou 0,50 x 104, e assim por diante.
int x;
double y;
int theAnswer;
x = 10;
y = 15;
theAnswer = x + (int) y;
O código (int) y converte y em um número inteiro.
Aliás, essa transmissão específica só funcionará se o número mantido em y puder ser convertido corretamente em um número inteiro. Então embora o exemplo acima esteja correto, se y tivesse um valor de 15,5, o código poderia falhar. Em um programa real, você provavelmente acrescentaria mais código para, primeiro, arredondar y para um número inteiro, usando Math.Round(y).
É provável que você não precise usar a transmissão nos seus primeiros programas. Contudo, talvez veja esse recurso sendo utilizado ao analisar exemplos de outras pessoas. Agora, pelo menos, você saberá o que está acontecendo.
Branching
Em geral, quando você quer que o programa realize uma ação, a linha que ele deve executar em seguida depende de algum fator. Você quer que o programa "se ramifique" de uma forma em um caso e de forma diferente em outro caso. O C# tem duas estruturas de ramificação para permitir isso: as instruções if e switch. Não abordaremos aqui a instrução switch, pois é mais complicada e você pode obter os mesmos resultados usando a instrução if.
A instrução if é fácil de entender. Você verifica algo para saber se é verdadeiro e, se o computador descobrir que é verdadeiro, ele executará o código daquele bloco. Caso contrário, passará ao bloco seguinte e refará o teste. Ele prosseguirá até encontrar algo verdadeiro ou alcançar o final de toda a instrução if.
if ( UserAnswer == “Bald Eagle” )
{
Console.WriteLine(“Yup, you got it right !”);
}
else if ( UserAnswer == “Eagle” )
{
Console.WriteLine(“Almost – the answer is ‘Bald Eagle’”);
}
Em geral, você vai querer ter também um bloco final "else" — então, se nenhum dos blocos acima for verdadeiro, o código no bloco "else" será executado.
if ( UserAnswer == “Bald Eagle” )
{
Console.WriteLine(“Yup, you got it right !”);
}
else if ( UserAnswer == “Eagle” )
{
Console.WriteLine(“Almost – the answer is ‘Bald Eagle’”);
}
else
{
Console.WriteLine(“Sorry, you got it wrong. Try again.”);
}
Looping
E se você precisar repetir várias e várias vezes uma ação? Por exemplo, escrever os números de 1 a 10. Seria uma tolice fazer isso da seguinte forma:
Console.WriteLine(“Number “ + 1 );
Console.WriteLine(“Number “ + 2 );
Console.WriteLine(“Number “ + 3 );
Console.WriteLine(“Number “ + 4 );
Console.WriteLine(“Number “ + 5 );
Console.WriteLine(“Number “ + 6 );
Console.WriteLine(“Number “ + 7 );
Console.WriteLine(“Number “ + 8 );
Console.WriteLine(“Number “ + 9 );
Console.WriteLine(“Number “ + 10 );
E seria uma tolice MUITO MAIOR escrever assim os números de 1 a 15.000!
É onde entram os loops. É possível realizar ações repetidamente com muito pouco código. O C# tem alguns tipos de loops, mas vamos abordar apenas dois.
The For Loop
Os loops "for" são geralmente usados em uma contagem. Você pode pensar em um loop FOR da seguinte maneira:
-
comece com um contador definido com um valor (por exemplo, 0);
-
prossiga até que o contador chegue a um valor específico (por exemplo, 11);
-
a cada passagem, faça algo específico com o contador (por exemplo, adicione 1 ao contador).
O trecho de código a seguir — apenas 3 linhas — escreve exatamente o mesmo que as 10 linhas de código acima.
for ( int x = 0; x < 11; x = x + 1 )
{
Console.WriteLine( “Number “ + x );
}
Aliás, é mais comum ver um loop como o mostrado acima escrito da seguinte forma:
for ( int x = 0; x < 11; x++ )
{
Console.WriteLine( “Number “ + x );
}
O símbolo "x++" é uma forma preguiçosa (mas eficiente e curta) de escrever x = x + 1.
Também é possível fazer com que os loops "for" façam contagem regressiva. Basta fazer com que eles subtraiam do contador, em vez de somar.
for ( int x = 11; x > 0; x-- )
{
Console.WriteLine( “Number “ + x );
}
Isso significa "comece com x igual a 11 e, enquanto x for maior do que zero, subtraia 1 de x".
The While Loop
Pense em um loop WHILE da seguinte maneira: "enquanto algo for verdade, continue a executar repetidamente este bloco de código".
Os loops "while" podem ser usados para obter exatamente o mesmo efeito do exemplo de loop "for" acima, mas eis aqui um exemplo que não tem nada a ver com contagem. Este código pede repetidamente ao usuário para digitar a palavra "smokey" usando o teclado. Só quando o usuário digita corretamente, o computador sai do loop e diz "Thank You". Observe que a condição verificada a cada passagem é "s != smokey", ou seja, enquanto a palavra digitada não é igual a "smokey".
string s = "";
while ( s != "smokey" )
{
Console.WriteLine("Please type the word 'smokey' : ");
s = Console.ReadLine();
}
Console.WriteLine("Thank You");
Eis aqui um exemplo que utiliza um loop "while" para fazer exatamente o mesmo do exemplo de loop "for" mostrado mais acima. Nós simplesmente introduzimos uma variável (x, neste caso) a ser usada como contador.
int x = 0;
while ( x < 11 )
{
WriteLine( “Number “ + x );
x = x + 1;
}
Você pode ver que x começa como zero, mas tem 1 adicionado a cada passagem do loop. A cada passagem, o computador verifica novamente se "x ainda é menor que 11". Em algum momento, x torna-se igual a 11 e o computador sai do loop.
Loops intermináveis
Quer experimentar uma verdadeira tolice? Deixe de fora a linha x = x + 1. Assim, x NUNCA se tornará maior e será SEMPRE menor do que 11. O loop se repetirá ETERNAMENTE — ou, pelo menos, até que o a memória do computador seja insuficiente, gerando uma mensagem de erro. Sempre que você escrever um loop interminável, isso o deixará embaraçado.
Whole Program Structure
Introdução
Nos capítulos anteriores, analisamos conceitos específicos e como explicar cada uma dessas idéias ao computador. Mas não levamos em conta como deve ser um "programa completo". Como fazemos para iniciar o programa e quais as partes que ele precisa conter para funcionar.
Então, neste capítulo vamos abordar a estrutura básica necessária a um programa em C#. A idéia não é causar confusão expondo todos os detalhes, mas sim compreender a estrutura básica de um programa — seu "esqueleto".
Existem vários tipos diferentes de programas em C#
Se você fosse acampar nas montanhas no fim de semana, usaria uma estrutura como uma barraca — e não uma casa, que precisa de uma fundação de tijolos. Você usa uma estrutura adequada ao ambiente onde se encontra. Barracas e casas têm a mesma finalidade básica, mas as barracas são especificamente estruturadas para acampamentos.
Fazendo uma analogia, o C# e o .NET Framework podem ser usados para criar aplicativos para ambientes diferentes. A linguagem é a mesma nos dois casos, mas há algumas diferenças específicas na forma como você estrutura o programa, dependendo do ambiente no qual está trabalhando. Eis aqui alguns exemplos de diferentes tipos de programas em C#.
-
Aplicativos do Windows Forms
-
Bibliotecas de classes
-
Serviços do Windows
-
Aplicativos de console
-
Aplicativos Web ASP.NET
Este livro se concentra somente em dois desses tipos de programas — os aplicativos de console e do Windows Forms. Mas o conhecimento obtido nesses dois ambientes também terá uma utilidade direta nos outros tipos de aplicativos.
A estrutura dos aplicativos de console
Um aplicativo de console pode exibir e ler somente texto — nenhuma imagem, gráfico etc. Se você já abriu um "prompt de comando" e digitou um comando como DIR para ver uma lista de arquivos, então já utilizou um aplicativo de console. Quando quiser experimentar algo com rapidez, ou então escrever um programa que não precise de nada além de texto, geralmente você utilizará um aplicativo de console, pois é o tipo mais simples de programa que se pode escrever com o C#.
Eis aqui um exemplo de aplicativo de console simples, mas completo:
1. using System;
2.
3. class PleaseSayYo
4. {
5. static void Main()
6. {
7. Console.WriteLine("Yo!");
Console.ReadLine();
8. }
9. }
E isto é o que você verá na tela ao executá-lo. Ele simplesmente escreve uma linha de texto na tela:
O programa é bem curto, não? Mas vamos dividi-lo e discutir sua estrutura.
-
A linha 1 avisa ao computador que algo mais adiante em nosso programa utilizará uma classe do namespace chamado "System". A classe específica cujo código utilizaremos é "Console". É uma classe escrita pela Microsoft, que produz todos os tipos de elementos necessários aos aplicativos de console. Em vez de escrevermos várias linhas de código para fazer algo simples, como escrever uma palavra na tela, apenas chamamos o método "WriteLine" da classe System.Console.
-
Nas linhas 3 a 9, nós "definimos a classe". Na classe, escrevemos nosso programa, escrevendo propriedades e métodos. Essa classe específica não tem propriedades (pois não precisa de nenhuma), mas tem um método.
-
Nas linhas 5 a 8, nós definimos um método. Esse método é muito parecido com aqueles que discutimos anteriormente neste livro, mas tem uma característica especial: PRECISA ser chamado de "Main". Não temos permissão para escolher um nome. Quando é solicitado que o computador execute um programa em C#, ele precisa saber por onde começar. Ele aprendeu que, nos programas em C#, o programador sempre escreve um método chamado "Main", e é por ele que deve começar. É o ponto de entrada. Você tem permissão para colocar esse método onde quiser na sua classe — na parte superior, inferior ou em qualquer outra parte. O computador vai encontrá-lo, desde que você o chame de "Main".
-
Na linha 7, chamamos o método "WriteLine", da classe System.Console, que escreve o texto que especificarmos.
É claro os aplicativos de console podem fazer muito mais do que mostramos aqui e, normalmente, terão muito mais código, mas em geral começam com uma estrutura básica semelhante aos dois exemplos mostrados acima.
Métodos estáticos
A única palavra estranha que você viu no programa acima foi "static". Para explicá-la, vamos primeiro escrever um exemplo ligeiramente mais complexo de aplicativo de console. Leia atentamente o método "Main". Você compreende o que ele faz?
1. using System;
2.
3. class SimpleConsoleApp
4. {
5. public void MySimpleMethod()
6. {
7. Console.WriteLine("Yo!");
8. }
9.
10. static void Main()
11. {
12. SimpleConsoleApp s;
13. s = new SimpleConsoleApp();
14. s.MySimpleMethod();
15. }
16. }
Esse exemplo realmente mostra a abordagem orientada a objeto melhor do que o exemplo anterior. Em vez de apenas escrever nosso código diretamente no método"Main", nas linhas 12 e 13 nós declaramos e construímos um objeto — uma instância dessa classe. Então, na linha 14, chamamos um método desse objeto.
Você perceberá que o método "MySimpleMethod" não tem a palavra "static" na frente; já o método "Main" tem. Eis o porquê:
-
A palavra "static" é acrescentada ao início de uma definição de método se o método não se destina à operação de um objeto específico.
-
E, como o método "Main" é o "ponto de entrada", ele é chamado antes que qualquer objeto seja construído, então, precisa ser definido como "static".
Eis aqui mais um exemplo para ilustrar o conceito de "static". Preste atenção, especialmente, ao texto em negrito.
using System;
class SchoolTest
{
public string testName;
public decimal total;
public decimal myScore;
// A constructor method for this class
public SchoolTest(string tn, int s, int tot)
{
this.testName = tn;
this.myScore = s;
this.total = tot;
}
// A STATIC method to calculate the percentage from ANY two numbers
public static decimal CalculateAnyPercentage(decimal numerator, decimal denominator)
{
decimal percentage = (numerator / denominator) * 100;
return percentage;
}
// An INSTANCE method to calculate the percentage of an instance of SchoolTest
public decimal CalculateThisPercentage()
{
decimal percentage = (this.myScore / this.total) * 100;
return percentage;
}
static void Main()
{
// Use the static method to calculate a percentage without any instance
Console.WriteLine("123/200 = " + SchoolTest.CalculateAnyPercentage(123, 200));
// Create a new instance of a SchoolTest, passing in the scores
SchoolTest t = new SchoolTest("Geography", 12, 60);
// Use the instance method to calculate the percentage of this instance
Console.WriteLine( "Percentage for test = " + t.CalculateThisPercentage() );
// Wait until ENTER is pressed
Console.ReadLine();
}
}
É importante observar que temos dois métodos muito semelhantes — os dois calculam porcentagens — mas sua utilização é bem diferente. O método que contém a palavra "static" pode ser usado sem a necessidade de declarar uma instância de new SchoolTest(), enquanto o outro funciona SOMENTE em uma instância. No exemplo acima, nossa instância é chamada de "t".
Então, é como se os métodos static dissessem: "Estou acima disso tudo, funciono onde quero!", enquanto os métodos de instância diriam: "Só posso existir quando um objeto real surgir — e então só funcionarei dentro desse objeto."
A estrutura dos aplicativos do Windows Forms
Quando você já conhece a estrutura geral de um aplicativo de console, é fácil passar gradualmente para tipos de programas mais complexos, pois a estrutura básica permanece a mesma. Este é um aplicativo simples do Windows Forms.
using System.Windows.Forms;
class SimpleWindowsApp : Form
{
// Constructor method
public SimpleWindowsApp()
{
this.Text = "A really Simple Form";
}
// Entry point for the program
static void Main()
{
Application.Run( new SimpleWindowsApp() );
}
}
Os dois elementos "novos" são:
-
A parte ": Form".
Quer dizer que "a minha classe vai herdar tudo da classe Form". Esse é um segredo importante, abordado no capítulo chamado "Herança". A Microsoft escreveu um grande conjunto de classes prontas para criar botões, menus, caixas de imagens, caixas de seleção e todos os outros tipos de elementos a serem colocados em aplicativos. Simplesmente adicionando ": Form", a sua classe pode ter acesso imediato a todos esses elementos.
-
A parte "Application.Run". Esse é o modo padrão para iniciar um aplicativo do Windows Forms. É um método que "executa" o seu aplicativo de formulários. Você transmite para o método uma nova instância da sua classe.
Using Class Libraries
Uma biblioteca, no mundo real, é um local que contém uma grande quantidade de livros e outras fontes de informações. Quando as pessoas precisam saber alguma coisa, não precisam descobrir tudo sobre o assunto novamente e escrever seus próprios livros. Basta consultar os livros adequados, poupando muito tempo e esforço.
Da mesma forma, pessoas de todo o mundo escreveram vastas bibliotecas de código em C#. Então, em vez de escrevermos tudo por nós mesmos, geralmente faz sentido utilizar as bibliotecas de outras pessoas em partes dos nossos programas.
Ainda assim, isso exigirá algum esforço, pois será preciso pesquisar o que há na biblioteca e entender quais são as partes úteis para você. Mas isso permitirá que você se concentre mais em fazer o que o seu programa precisa, em vez de perder muito tempo escrevendo o código de plano de fundo.
De longe, a biblioteca mais importante para o C# é a "biblioteca de classes .NET Framework" da Microsoft. Não se pode escrever um programa realmente útil sem usar algum elemento dela. A parte III deste livro é dedicada a essa biblioteca. Quando você instala o .NET Framework no seu computador, a biblioteca é carregada automaticamente e fica disponível para seus programas. Você precisa apenas saber como fazer referência a ela, ou seja, como usá-la a partir dos seus programas.
Um exemplo
A parte "System.Drawing" da biblioteca de classes .NET Framework contém muitas classes úteis para trabalhar com imagens. Vamos utilizá-la para ilustrar como usar o código de outras pessoas no seu programa.
A classe System.Drawing.Image tem um método chamado RotateFlip, que gira ou inverte qualquer imagem que você transmitir a ele. Suponha que você quer usar esse método no seu programa — você quer carregar um arquivo de imagem do disco, invertê-lo horizontalmente e salvar uma cópia da imagem invertida no disco. Eis uma forma de fazer isso. É um programa completo e funcional (se você está experimentando, observe que o programa 9 na coleção de arquivos de exemplo fornecidos com este livro é semelhante).
class PhotoSizer
{
public PhotoSizer()
{
// Load a photograph from disk into the computer's memory
System.Drawing.Image img;
img = new System.Drawing.Bitmap(@"d:\samples\myDog.jpg");
// Flip the image horizontally
img.RotateFlip( System.Drawing.RotateFlipType.RotateNoneFlipX );
// Save the flipped photo to a different disk file
img.Save( @"d:\samples\myDogFlipped.jpg" );
}
static void Main()
{
PhotoSizer p = new PhotoSizer();
}
}
Uma rápida observação sobre o símbolo @:
O símbolo @ do C#, usado acima, pode ser adicionado ao início de uma cadeia de caracteres para "evitar" ou ignorar caracteres de barra invertida, se o caminho incluir caracteres especiais como barras invertidas. As barras invertidas podem causar confusão no C#, pois têm significado especial. Então, normalmente você precisaria escrever um caminho assim com duas barras invertidas, como d:\\samples\\myDog.jpg. O símbolo @ evita a necessidade de fazer isso.
O que fizemos no exemplo acima foi usar uma classe da biblioteca. A classe é chamada Image e está na seção da biblioteca chamada System.Drawing.
Depois de criar um objeto de imagem, chamamos dois métodos da classe Image. Os nomes dos métodos são RotateFlip e Save.
Um modo mais fácil
Mas, como você pode ver, sempre que é preciso falar sobre algo no espaço de System.Drawing, é preciso escrever novamente todas as palavras. Há uma forma de evitar esse desperdício de energia. Você pode simplesmente dizer ao programa uma vez, na parte superior, que vai usar alguns elementos do namespace System.Drawing, e também alguns do namespace System.Drawing.Imaging, especificamente.
using System.Drawing;
using System.Drawing.Imaging;
class PhotoSizer
{
public PhotoSizer()
{
// Load a photograph from disk into the computer's memory
Image img = new Bitmap(@"d:\samples\myDog.jpg");
// Flip the image horizontally
img.RotateFlip( RotateFlipType.RotateNoneFlipX );
// Save the flipped photo to a different disk file
img.Save( @" d:\samples\myDogFlipped.jpg" );
}
static void Main()
{
PhotoSizer p = new PhotoSizer();
}
}
Uma observação sobre referências no C# Express
Ao criar um projeto no Visual C# Express, você precisa criar também um elemento chamado "referência", apontando para o arquivo da biblioteca de classes que contém o código da biblioteca que deseja utilizar (esses arquivos têm uma extensão ".dll", que significa "Dynamic Link Library", ou seja, biblioteca de vínculo dinâmico). Felizmente, as referências mais comuns costumam ser acrescentadas de forma automática.
A figura a seguir, por exemplo, mostra as referências adicionadas quando você cria um projeto de "aplicativo do Windows". O Visual C# Express deduz quais as partes da biblioteca que você poderia usar em um aplicativo assim.
No exemplo acima, você pode ver que as classes do namespace System.Drawing são mantidas em um arquivo chamado System.Drawing.dll.
Se a referência à parte da biblioteca que você deseja usar não tiver sido criada automaticamente, você mesmo precisará adicioná-la. Imagine, por exemplo, que você encontra um exemplo de código que usa a classe System.Web.HttpRequest para recuperar algumas informações em um servidor Web e quer experimentá-lo. Você clica com o botão direito em "References" (Referências), seleciona "Add Reference" (Adicionar Referência) e seleciona a parte System.Web da biblioteca. Agora, é possível usar as classes no seu código.
Conclusão
Então, é muito simples incluir código de uma biblioteca. A parte difícil é saber quais classes, métodos etc. estão disponíveis para uso nessa vasta biblioteca.
Por isso, a parte IV deste livro foi escrita — para que você tenha contato com algumas partes úteis da biblioteca de classes .NET Framework da Microsoft.




Nenhum comentário:
Postar um comentário