Transcrições
1. 0-1. Este é o curse para você e sobre o instrutor: Então, bem-vindos a todos. Bem-vindo ao meu curso tutorial em
vídeo da C Sharp. Aqui tenho cerca de
11 horas de filmagem ensinando tudo,
desde o básico Isso pressupõe que você não tenha nenhum conhecimento de
programação. E ao final disso,
você terá o mesmo,
se não mais, conhecimento sobre programação
e C Sharp do que um estudante
universitário típico. Então, se você quiser aprender C sharp como um hobby
, não tem problema. Você vai
tirar isso desse curso. No entanto, se você quiser
conseguir um emprego ou potencialmente, uma carreira
no final deste curso
, também
não terá problemas em fazer isso. E para aqueles
que talvez queiram
uma atualização de C Sharp ou uma atualização de programação
genérica
, esse curso também é
bom para isso Então, este curso
tutorial em vídeo de loja é bom para você? Bem, você quer aprender a fazer compras? Então a resposta é sim. Mas talvez uma
pergunta melhor seja por que eu
deveria escolher este
curso em vez de qualquer outro? Bem, o segredo do
aprendizado é, em primeiro lugar, o professor, e é como o professor ensina
as informações. E número dois, o processo
de aprendizado. O curso é envolvente? Sim, é. É chato Não, certamente não.
É confuso Não, porque eu explico
os princípios não apenas de uma forma, mas talvez de duas ou
três maneiras diferentes. Então, ao final disso,
você terá uma compreensão completa de todas as técnicas que eu
ensino neste curso. E o ritmo,
é um ritmo rápido? Não, não é nem um
pouco rápido. Este curso foi desenvolvido
para iniciantes absolutos. Portanto, o ritmo é lento, na melhor das hipóteses. Para quem é esse curso? Este curso é para iniciantes
absolutos. Ele pressupõe que você não tenha nenhum conhecimento de
programação, nenhum conhecimento de
desenvolvimento de software e queira
começar a programar em C sharp Talvez você queira fazer
alguns jogos no Unity. Talvez você queira desenvolver aplicativos
de software, aplicativos
móveis, sites na loja C. Tudo isso é possível
assistindo a este curso
tutorial em vídeo Este curso pressupõe
que você saiba como usar um computador. Você sabe, genericamente,
você pode mover um mouse, talvez verificar seus e-mails
e baixar um arquivo Mas a questão é que ele não pressupõe nenhum
conhecimento de programação. Então, a
experiência de aprendizado, bem, eu gosto de psicologia
no meu tempo livre, então eu entendo como
a mente humana funciona, especialmente quando aprendo
e retendo informações Mas talvez seja um assunto novo e
assustador. Então isso me leva ao
próximo ponto, o ritmo. Qual é o ritmo
do curso? Bem, a programação tem muitas palavras
técnicas
grandes e complicadas. Mas não se preocupe, eu introduzo palavras
técnicas muito lentamente
ao longo do curso. Muitos professores usam
palavras complicadas imediatamente, que causa
muita confusão e
dificulta a capacidade de
reter o assunto em questão Acho que esse é um
passo muito importante para evitar
seu maior inimigo, que é a sobrecarga de informações Portanto, não se preocupe,
você aprenderá palavras
técnicas e complicadas, mas não antes do
tópico em questão. Vou
apresentá-lo lentamente para que a experiência de aprendizado
seja muito agradável Portanto, à medida que o curso progride, vou lentamente começar a apresentar
os termos corretos do setor e o jargão técnico ao assistir aos vídeos
deste Agradeço que você
não esteja lá para fazer perguntas imediatamente
e obter feedback direto. Então, o que eu faço é explicar os tópicos de várias
maneiras diferentes, não apenas de uma maneira,
e dessa forma você pode entender completamente
o assunto em questão. Acho que esse método de
aprendizado é muito melhor do que fazer vídeos em que você não
fornece informações suficientes. Se não forem fornecidas
informações suficientes, você se sentirá perdido
e frustrado e não há nenhum professor
para fazer perguntas Você não experimentará
isso com meu curso. E eu garanto isso
porque mesmo depois eu ter explicado um
assunto complicado,
por exemplo várias maneiras diferentes, se você tiver alguma dúvida, à vontade para
me deixar uma mensagem ou um comentário. E ficarei mais do que
feliz em responder a qualquer dúvida ou preocupação que você tenha a qualquer momento
durante este curso. E, por fim, se eu ensinar
um princípio de programação, não ensino apenas as
informações Na verdade, explico
por que eles são úteis, por que você aplica isso
na vida cotidiana
e por que é importante, no desenvolvimento de
C sharp,
seguir esse princípio específico. Então é aí que meu curso difere de muitos
cursos por aí. Você aprende o como e o quê, mas também o porquê, que é muito importante. engajamento, um dos
maiores assassinos do
aprendizado de novas informações, é o
engajamento e a motivação Os dois tipos andam de mãos dadas. Então, o que eu faço é
usar exemplos divertidos. Além disso, também uso
exemplos de tendências para manter
as coisas interessantes Eu entendo o que é perder
a motivação, perder engajamento e ficar um pouco entediado ao
aprender um novo tópico Por isso, tento manter
as coisas frescas e atualizadas para que você
nunca perca a motivação. E você sempre se envolverá
com os tópicos em questão. Então, o que vou ganhar
ao aprender este curso? Por que eu deveria aprender com você? Qual é o resultado final? O que eu posso conseguir? Bem, perguntas
muito boas. Vou te ensinar tudo o
que você precisa saber sobre loja, mas não apenas
programação C shop em geral. As ferramentas, técnicas e princípios para fazer de
você um bom desenvolvedor, um bom programador,
especialmente na loja E será semelhante,
se não melhor, do que um estudante
universitário. Como posso garantir
essas afirmações ousadas? Bem, eu estive na universidade, fui por quatro anos inteiros. E posso garantir
que o conteúdo
desse curso é exatamente o que
eu aprendi na universidade. Mas não só isso, mas muito mais. E também ensino
as ferramentas, técnicas e melhores práticas que
aprendi trabalhando na
indústria,
portanto, de forma profissional. Então, se você vai para uma
faculdade universitária ou não, você tem uma vantagem porque
não está sentado em uma sala de aula cheia de pessoas
com muitas distrações Essa é uma experiência única
e individual. Por fim,
resumirei dizendo não importa que
tipo de aluno você
seja, se você é um aprendiz visual
ou não,
você pode assistir a este
curso sentado em uma cadeira e comendo
uma
pizza, por cadeira e comendo
uma
pizza No entanto, se você quiser
ser mais interativo
, forneço os arquivos completos do projeto junto
com este curso, todo o código-fonte que eu uso. Então, se você quiser
acompanhar em seu computador, você pode fazer isso. Sem nenhum problema. Este curso oferece
várias maneiras de aprender para vários
tipos diferentes de alunos Então, sobre mim, quem sou
eu, qual é o meu nome? Bem, eu sou Sean e é um
prazer conhecer todos vocês. Sou engenheiro de software profissional e
autônomo. Mas não só isso, eu ensino desenvolvimento
e programação de
software. Eu trabalho com muitas linguagens de
programação diferentes e também com muitas
arquiteturas diferentes Mas, como
ensino alunos regularmente, não perdi a capacidade de
me comunicar
com novos alunos, especialmente em um nível iniciante Eu me formei na universidade
agora em 2007. Tenho mais de 20 anos de experiência
profissional
em desenvolvimento de software. Eu estava até trabalhando junto com meus estudos universitários
na mesma área. Eu ensino
programação desde 2003. Então, há muito tempo, eu o usei como uma forma de financiar meus estudos universitários antes mesmo de o
Youtube existir. Agora vou mostrar meu site muito
antigo, onde fiz
cursos tutoriais em vídeo em Visual Basic, seis C mais Java, Direct X e várias coisas. Então você pode ver que agora eu ensinei programação para muitas
pessoas. E eles sempre
voltam para mim mais tarde, você sabe, dez anos
depois, 15 anos depois. E conte-me tudo sobre
suas histórias de sucesso, as empresas em que
trabalham agora e em quais projetos
estão envolvidos. Portanto, é muito saudável
e interessante
ouvir essas histórias de sucesso
de meus ex-alunos E adoro quando os alunos voltam para mim
e me contam sobre suas histórias de sucesso e
como suas vidas mudaram. Aprender, programar,
é muito interessante e é a
melhor parte do ensino. Então, eu sou autônomo agora, mas trabalhei para muitas
empresas no passado. Pequenas e
grandes empresas também, talvez você já tenha ouvido falar de algumas. Eu trabalhei para o The Guardian, que é uma empresa jornalística
com sede no centro de Londres. Trabalhei para o
Ministério da Defesa britânico, onde trabalhamos no software
CAD para modelar seus
navios de superfície e submarinos Eu trabalhei para a Pfizer, uma empresa farmacêutica, da qual tenho certeza que todos vocês já
ouviram falar atualmente Mas quando eu estava trabalhando lá, muitas pessoas
não
ouviram falar dessa empresa. E trabalhei para
várias pequenas agências das quais talvez
você nunca tenha ouvido falar. Assim, posso compartilhar minhas
experiências de trabalho em equipes
pequenas e também em equipes
muito grandes. E também compartilharei exemplos
desses dois tipos diferentes de experiências
ao longo deste curso. Então, se você está se perguntando de onde vem
meu sotaque, bem, eu nasci no Reino Unido e meus empreendimentos de programação me
levaram por todo o mundo Eu me mudei para a América quando tinha 25 anos e obtive a cidadania lá. E agora estou morando
na América do Sul. Mas uma coisa que
permaneceu consistente, em vez de minha casa
e meu sotaque, por exemplo, é que eu
sempre ensinei programação e
sempre fiz desenvolvimento de software Então, chega de falar sobre mim. Vamos
falar sobre C sharp agora.
2. 0-3. O que é C# no design de jogos? e por que aprender C#?: Então, o que é C Sharp? Bem, C sharp é o que chamamos de linguagem
de
programação orientada a objetos. E não se preocupe,
falaremos sobre isso mais tarde. Ele foi criado pela Microsoft e é executado no que é chamado
de.net Framework C Sharp tem suas raízes
na família C. Então, eu não sei se você já
ouviu falar de C ou C Plus, mas é bem parecido
com essas linguagens, e foi daí que ele
foi desenvolvido. É muito semelhante a linguagens
populares como
C plus e Java. E a primeira versão do C Sharp foi lançada
no ano de 2002. Agora, então tem mais de 20 anos. E a
versão mais recente no momento da filmagem é C Sharp versão 11 Portanto, a linguagem C Sharp
evolui lentamente , como
tudo na vida. Então, por que eu deveria aprender C
Sharp? Para que é usado? Bem, você pode criar aplicativos
móveis, aplicativos desktop, aplicativos da web como
sites, videogames, jogos realidade
virtual, por
exemplo, aprendizado de máquina, software, aplicativos de banco de dados
e muito, muito mais. É uma das linguagens
de
programação mais populares do mundo. E é por isso que é
muito bom aprender um idioma como o C
Sharp, porque
haverá mais
oportunidades de emprego e mais oportunidades para você aplicar seus conhecimentos. É fácil de aprender e
simples de usar. Tem um grande apoio da comunidade. Se você já conhece C
ou C plus plus ou Java, ou talvez queira
aprendê-los no futuro, então eles são muito parecidos. Os princípios
que eu ensino neste curso podem ser aplicados ao C plus e ao
Java se quiser aprender uma
nova linguagem no futuro. Uma das tendências no
momento é criar videogames em um pacote de
desenvolvimento de software chamado Unity O Unity suporta C Sharp nos
bastidores. Se você quiser fazer seu
videogame fazer coisas, fazer seus personagens se moverem
, você pode usar C sharp
para fazer isso. Então, agora, as pessoas estão
aprendendo C sharp mais do que nunca, só para que possam criar
videogames no Unity. Então, aqui estão muitas
razões para aprender C sharp e por que você deveria aprender C Sharp em vez de talvez
outras linguagens. Então, espero que, por meio da
minha explicação até agora, eu tenha convencido você a
começar sua jornada aprendendo C Sharp e se tornando
talvez um programador profissional, ou mesmo amador Agora vamos começar nossas
aventuras em C Sharp e baixar as ferramentas necessárias para começar.
3. 0-4. Baixe e instale o Visual Studio (C# IDE): Como começamos a
codificar em C Sharp? Bem, a maneira mais fácil de
começar é usar
o que é chamado de IDE. Isso significa Ambiente de
Desenvolvimento Integrado. E o ambiente que
vamos
usar é chamado de Visual Studio. Então, não vamos
codificar no Bloco de
Notas ou algo
assustador parecido Vamos usar ferramentas
fáceis de
usar para iniciantes, fornecidas pela Microsoft E não só isso,
eles são gratuitos. Deixe-me mostrar como
baixar e começar a usar o Visual Studio. Vamos começar a baixar o
Visual Studio agora. Se entrarmos no Google e simplesmente digitarmos o Visual
Studio Community, podemos clicar no
primeiro resultado aqui. Agora, a versão mais recente
no
momento da filmagem é o
Visual Studio 2022 Mas mesmo que você tenha
uma versão anterior ou posterior, muitas das técnicas que
abordaremos
neste curso funcionarão
. Sem problemas. Então, vamos clicar
nesse primeiro link aqui. Aqui, podemos baixar
o IDE
aqui mesmo se você estiver usando um
Apple Mac, por exemplo. Então você pode clicar
nesse botão aqui. E então o Visual Studio vem
em três tipos diferentes. Temos o do
Windows aqui, o do MacOS e também um leve
para Mac, Windows e Linux Portanto, dependendo do seu sistema
operacional, você deve estar
praticamente coberto. Mas estou executando uma máquina
Windows e isso realmente não combina. Se você usa Mac, ainda pode seguir os tutoriais,
sem problemas Então, vou clicar
neste link de download aqui
e, em seguida, o Visual Studio começará a
baixar. É apenas um arquivo de 34 megabytes, então é muito pequeno, mas tudo
será baixado dentro do próprio arquivo de configuração Pouco antes de instalarmos o
Visual Studio, quero mencionar uma coisa. O Visual Studio não está
vinculado apenas ao desenvolvimento em C Sharp. Você pode fazer muitas coisas
no Visual Studio. O Visual Studio funciona com
HTML, CSS, Javascript. Você pode até mesmo criar aplicativos
móveis, Php, Python, Spot, Todas essas várias coisas, ferramentas, tecnologias e linguagens de
programação que você pode fazer no Visual Studio. Portanto, se você já conhece
um idioma diferente, ou talvez queira
experimentar idiomas diferentes no futuro depois de
examinar o C Sharp, Visual Studio também o
apoiará nesses esforços Portanto, é um software muito poderoso
e, novamente, é gratuito. Vamos abrir o arquivo de instalação do Visual
Studio, que acabamos de baixar e obter com a instalação do
Visual Studio. Então, vamos clicar em continuar aqui. Agora está apenas preparando
o instalador, está baixando um arquivo um
pouco maior. Agora, essa é a janela
que você
verá quando a
configuração for inicializada Então, muitas
coisas diferentes que você pode fazer aqui para os propósitos
deste curso. A única coisa com a
qual vamos trabalhar é C Sharp. A única coisa que precisamos é do
ambiente de trabalho.net aqui Então, basta clicar
nesta caixa aqui
e, em seguida, podemos
começar a instalar esses componentes. Algo mais? Aqui é totalmente
opcional e, dependendo de você, temos várias coisas para
desenvolver sites em Aspet Também temos Azure Node, Python. Novamente, coisas de desktop e celular, coisas no C Plus Plus. E você pode até mesmo instalar o
Unity de dentro do instalador do Visual Studio e também de vários
componentes de dados. Portanto, há muito a ser
feito, muito a ser instalado e muito a aprender em termos de programação e trabalho
com o Visual Studio. Mas o que precisamos é apenas
dessa caixa simples aqui. Se você fala outro idioma ou está mais familiarizado com
um idioma diferente, você pode selecioná-lo aqui. Não tem problema nenhum. Então, se chegarmos aqui agora, isso é tudo o que
será instalado aqui. Para ser honesto, não
acho que precisemos construtores de modelos de compartilhamento
ao vivo ou do Blend Isso só vai
explodir nossa instalação. Mas acho que essa é uma boa
configuração para começar
e
fornecerá tudo o que
você precisa para seguir este curso e
até um pouco mais. Então, agora o que vamos fazer é clicar neste botão de instalação. Aqui você tem
algumas opções. Você pode baixar tudo e depois instalar ou pode
instalar durante o download. Isso realmente não importa,
depende apenas da sua preferência e talvez da
sua conexão com a Internet. Então, vamos clicar no
botão de instalação e começar. A instalação pode
levar alguns minutos, mas quando você vê essa
tela aqui, significa
que o Visual Studio
foi instalado com sucesso. Você também pode ter ícones na área de trabalho ou
no menu de programas, dependendo do
sistema operacional em execução. Mas, essencialmente, uma vez que
aparece nessa lista
, você tem o Visual
Studio instalado. O que podemos fazer é simplesmente clicar nesse botão agora e
iniciar o Visual Studio
e, em seguida, começar com nosso desenvolvimento de
software
em C. Sharp.
4. 1-1. Hello World (logotipo Mr. Beast): Nesta lição,
criaremos um
software muito simples chamado aplicativo de console, que
exibirá o logotipo do Sr. Besta para quem abrir
nosso software Vamos embora agora. O Visual Studio foi instalado
recentemente. Vamos criar nosso primeiro aplicativo
de software. Vai ser o
nosso primeiro. Será amigável para
iniciantes, e vamos começar
do início. Vamos embora. Depois que o Visual Studio estiver aberto, clicaremos em
Arquivo, Novo projeto. Então, teremos uma janela
parecida com essa. Agora, se você não tem o
Visual Studio 2022, essa é a versão que
estou usando agora. Pode parecer um pouco diferente. Você pode ver as configurações
em lugares diferentes. As coisas podem ser chamadas de
algo um pouco diferente. Mas o tipo geral de
princípio ainda se aplica. Agora, nosso primeiro aplicativo de
software
, será um aplicativo de console. E isso é representado por
este modelo de projeto aqui. O que é um aplicativo de console, é como
uma janela preta. Só tem texto nele. E a razão pela qual estou usando isso é
porque é muito amigável para
iniciantes Não há botões, listas, imagens ou qualquer coisa complicada. Isso é muito amigável para iniciantes e é por isso que estou usando
um aplicativo de console Se você realmente não
vê isso nessa lista, pode
procurá-la aqui digitando no aplicativo do
console ou no aplicativo
do console E você pode ver que todos esses
modelos serão carregados aqui. Queremos esse porque
estamos escrevendo em C Sharp. Na verdade, ele será executado em
Linux, Mac, Windows. Vamos usar este,
vamos clicar em Avançar. Podemos chamar isso do que
quisermos. Depende de você. Você pode deixar
assim ou
escolher algo
mais descritivo Então, vamos chamá-lo de
primeiro programa, o local. Você pode escolher um
diretório no qual
deseja manter todos os
seus arquivos de projeto. Isso depende de você.
Então, vamos clicar em Avançar. Agora, nesta estrutura,
vou falar de tudo sobre estruturas
em um tutorial posterior Eu quero manter isso
muito simples, essa lista, pode ter 4567,
todos números diferentes Só vamos
sair às sete. Se o seu quatro estiver bem,
ainda vai funcionar. Se você ver esta caixa de seleção
aqui que diz, não use declarações de nível superior Certifique-se de que esteja verificado. Isso é muito importante. Vamos clicar em Criar. E isso
é o que vemos aqui. Agora, na verdade, o Visual Studio recebeu todo esse código para nós, e a razão pela qual eles
fazem isso é para
torná-lo mais fácil de usar para que
possamos começar. Como usuário iniciante, você provavelmente não tem
ideia do que isso significa. Isso realmente não importa. Eu
abordarei todas essas linhas aqui em um
tutorial posterior e você
aprenderá o que elas
significam a tempo de manter isso amigável para
iniciantes De qualquer forma, a única linha
com a
qual você precisa se preocupar agora é esta aqui neste tutorial. Vamos colocar
todo o nosso código entre essa chave encaracolada aqui e essa aqui, tudo
no E podemos colocar mais linhas
aqui se quisermos. Neste tutorial, estamos
falando apenas sobre essa seção aqui. Não se preocupe com nada disso. Vamos remover toda
essa complexidade. Vamos falar sobre isso.
O que isso faz? Diz
linha direita do console, Hello world. Para realmente tentar
executar esse programa, preciso falar sobre o que
é chamado de compilador. Agora, o Visual Studio tem um compilador embutido porque
estamos escrevendo C Tem um
compilador Sharp lá dentro. O que o compilador C Sharp faz, ele pega todo o nosso código aqui, isso é tudo nesta janela
branca, o compila. Se estivermos usando o
Windows, por exemplo, ele criará um
arquivo EX para nós, o que é um arquivo E. É chamado de arquivo binário, talvez você realmente não precise
saber disso agora, mas é chamado de arquivo binário. Se quisermos executar
esse programa em, digamos, um Mac, por exemplo
, ele
criará um arquivo binário que um Mac entenderia. Se quisermos que ele execute um Android, como um telefone Android, ele criará um arquivo binário que o
telefone Android possa entender. Isso é realmente o que um compilador faz em poucas palavras e não
complicadas Ele pega todo o nosso
código e o compila em um arquivo binário Para fazer isso, para executar o compilador, você vê este pequeno botão
verde de reprodução aqui onde diz o
nome do nosso projeto chamado Primeiro Programa Quando clicamos nesse botão, é aqui que dizemos,
oh, ei, Visual Studio. Você pode dizer ao nosso
compilador que pegue todo o nosso código e transforme em um arquivo para que possamos
executar o software Isso é exatamente o que ele faz, então vamos
clicar aqui. O que acontece é que nossa
pequena janela preta aparece e
desaparece imediatamente Duas coisas aqui, todas
essas coisas aqui embaixo, você viu todo aquele
texto ficando louco. Esse é o compilador. O compilador está dizendo,
ok, eu fiz isso, isso, isso, posso cuspir esse
arquivo EXE na parte inferior Isso é porque eu estou
usando o Windows. Ele criou um arquivo EXE para mim. Agora, o arquivo EXC
foi criado. O software está em execução. Ele tenta abrir
o arquivo EC para nós. Era aquela janela preta
que acabou de aparecer. Mas então ele
desapareceu instantaneamente. Ele desapareceu instantaneamente porque na verdade, não
estamos
dizendo que ele permaneça aberto. Visual Studio fez um bom trabalho ao inserir esse código
de
amostra para nós, mas também manteve o software aberto para que
possamos realmente ver
o que está acontecendo. Vou digitar mais uma
linha e isso vai
manter a janela preta aberta para nós. Então, vou digitar console porque o console é
a janela preta. Então, queremos dizer, oh, ei, linha de leitura
do console, certo? Então é isso que estou
colocando lá e isso manterá a janela do
console aberta. Vamos falar sobre essa
linha bem rápido. O que isso faz é
aguardar a entrada do usuário. Então, por exemplo,
você viu um software, algum software que diz,
ei, qual é o seu nome? E então você digita seu nome? Então, o que acontece é que quando
executamos essa linha de código, a janela preta está
aguardando nossa entrada. E isso só mantém
a janela aberta. Vamos executar
esse software agora. Agora você pode ver que a
janela está aberta. Na verdade, ficou aberto
, não vai desaparecer. Isso é só porque ele está
aguardando a entrada do nosso usuário. Mas é uma
forma meio suja meio maluca de se manter Assim, podemos ver o que está acontecendo. Essa janela preta aqui é
nosso aplicativo de console. É nosso primeiro
software. Dê tapinhas na mochila
. Não faz muita coisa. A única coisa que ele faz
é dizer olá mundo. Está te dizendo que está vivo. É dizer olá para o mundo. Isso é tudo o que ele faz agora. Muito simples, mas não
se
menospreze, é o seu primeiro
software. Podemos fechar isso
pressionando Enter ou
riscando-o aqui E é isso em poucas palavras, nosso primeiro aplicativo de
software Agora, como podemos expandir isso? Bem, vamos falar sobre outra
coisa primeiro, que é a distinção entre maiúsculas e
minúsculas em C sharp. E também algumas pequenas
ressalvas. Você percebe que aqui onde está escrito linha
vermelha e linha direita, na verdade
faz distinção entre maiúsculas e minúsculas. O que isso significa é que se eu mudar esse L maiúsculo
para um L minúsculo, você pode ver que eu tenho essa linha vermelha abaixo que diz, oh, eu não consigo encontrar isso no sistema.
Não existe. Isso porque um L
minúsculo e um L
maiúsculo em C nítido são duas coisas
muito diferentes. Tenha isso em mente. Precisa
diferenciar maiúsculas de minúsculas. A última coisa é que todas as linhas devem terminar com ponto e vírgula Se você esquecer o ponto e vírgula
, vamos fazer algo
semelhante Você vê esse pequeno rabisco
vermelho aqui. Se passarmos o mouse sobre
isso, estamos dizendo que o ponto e vírgula
é Então, na verdade, está
lhe dizendo qual é o problema. Se você já teve uma
época em que teve a linha
ondulada vermelha e
tentou executar o programa, obterá
algo assim E você se familiarizará
muito com esse diálogo em seus empreendimentos de
programação, confie em mim. E então ele lhe dirá qual é
o problema aqui embaixo. Você pode clicar duas vezes nele
e ele o alertará sobre isso. E isso é apenas dizer que falta
o ponto e vírgula. Agora, falei muito
brevemente sobre o que eles fazem. Vamos falar
sobre essa parte aqui. O que queremos fazer é dizer, oh, ei, janela preta. Escreva a linha na janela e queremos
escrever hello world. Isso é tudo que está fazendo. Você resolveu
isso totalmente sozinho. Mas agora eu lhe disse que
podemos realmente expandir isso. Na verdade, podemos dizer, oh, ei, isso mesmo,
Three Hello Worlds. Salvamos isso, clicamos no botão e agora temos três deles. Agora você vê para onde isso
está indo em nosso exemplo. Logo no início, eu
disse que vamos
exibir o logotipo do Sr. Besta Agora eu tenho um
arquivo de solicitação para o logotipo do Mr. Beast O esqui é apenas uma
representação em texto de uma imagem. Vou te mostrar o que
isso significa agora. Tudo vai fazer sentido. Então você pode ver
aqui, eu tenho um logotipo do Mr. Beast aqui no Bloco de Notas E eu adicionei o console
logo antes dele, então podemos ver isso aqui. Eu só vou
copiar tudo isso. E vou
colá-lo entre
esses colchetes encaracolados, como
falei anteriormente.
Eu vou guardar isso. Vou apertar
o botão verde. Vou abrir essa
janela para que possamos vê-la. E eu vou rolar para cima. Esse é o nosso primeiro
software. Assim que alguém abrir
seu software, verá o logotipo
do Mr. Beast É tão simples como podemos modificar essa mensagem e
criar uma imagem totalmente nova. Quando analisamos o código aqui, apenas várias declarações da
linha direita que criam todos esses Ms aqui e um
design de personagem muito bom no logotipo aqui. Antes de terminar esta lição, vou mostrar
como tudo isso se relaciona. Faz sentido na sua cabeça. Lembra quando criamos um projeto totalmente novo e
temos esse campo de localização? Bem, eu vou
entrar nesta pasta agora mesmo. Agora estou nesse diretório
em nosso computador. Podemos ver que o Visual
Studios criou uma série de pastas
e arquivos para nós. Aqui dentro, temos o que é
chamado de arquivo de solução e ele criou outra pasta. Então, vamos entrar lá. Ele
criou ainda mais arquivos. Este tem nossa codificação. Mas se olharmos dentro
desta pasta bin aqui, e depois dentro desta pasta de
depuração aqui, dentro desta,
você pode ver que há alguns arquivos aqui
no meio aqui Este é o nosso arquivo binário
e, como estou usando o Windows, ele criou um arquivo EXE, o Fas. Se clicarmos duas vezes nele, podemos até mesmo enviá-lo para
um amigo, por exemplo. Eles podem clicar duas vezes nele. Ao maximizá-lo,
você pode ver o logotipo do Mr. Beast. Você pode ver que
é assim que tudo se une. Visual Studio diz
ao compilador, oh hey, pegue todo o código,
crie um arquivo EXE, Fas, e coloque-o nesta
pasta aqui Falarei sobre todos os outros arquivos em uma data posterior. Mas, para fins
de simplicidade, ele cria nosso arquivo EXE rapidamente, e esse é o nosso
primeiro software.
5. 1-2. Variáveis: Agora vamos falar sobre se vou introduzir
uma variável muito simples. Vou
mostrar como funciona, quais são as variáveis
e como elas podem se beneficiar e coisas
assim, variáveis. Vamos falar sobre o que são. Para começar, temos um
exemplo de aplicativo aqui. Apenas diz “Olá,
mundo” para uma janela preta. E isso é tudo o que ele faz, como
você pode ver ali. Agora vou
apresentar o que é chamado de variável e
vou falar sobre
como elas podem nos ajudar. Vamos apenas introduzir uma variável. Eu posso falar sobre
isso em um segundo. Vou chamar isso de teste. Vamos dar a ele o valor
de Hello world. Vou apenas colocar o nome
da variável aqui. Então, vamos falar sobre isso
e o que isso faz. Então, o que estou fazendo aqui inicializar o que é
chamado de variável Agora essa é a variável. É chamado de teste, então esse é
o nome da nossa variável. Agora, essa variável pode ser
chamada do que você quiser. Pode ser chamado de sanduíche de presunto. Realmente não importa. Mas a questão é que você
precisa dar um nome
que faça sentido para
você, você pode se referir a ele. Porque quando você tem
um aplicativo de software que tem milhares de variáveis, você vai
ficar muito confuso se chamar todos eles de tipos
diferentes de sanduíches ou nomes aleatórios como teste ou
algo parecido Então, isso precisa
fazer sentido para você. Então, vou
chamá-lo de Hello World. Então esse é o nome
da nossa variável, esse é o valor
da nossa variável. Então é isso que estamos colocando
dentro da nossa variável aqui. Agora, essa parte aqui
é chamada de tipo. Agora, essa é uma variável de string. O que é uma variável de string,
é um contêiner para
palavras, frases. Você pode colocar um livro
inteiro aqui, se quiser. Tudo são letras
e números alfanuméricos , mas como uma sequência de caracteres, não são números por si
só, não são um valor decimal, não são uma data ou hora ou algo
complicado assim Isso é o que é uma string. Isso é chamado de tipo
de variável. Esse é o tipo de variável
que diz, ei, computador, queremos iniciar uma nova variável
e colocá-la na memória. O nome da nossa
variável é esse. O sinal de igual é como o
inicializamos, por
exemplo, atribuímos um valor a ele Quando você está trabalhando
com strings, sempre
colocamos o valor
entre aspas duplas Como dentro das aspas duplas está o valor da nossa variável. Sempre terminamos cada
linha com ponto e vírgula. Agora, nossa variável se chama Hello World. Vamos
executar o programa. Você pode ver que ele exibe
Hello World na janela. Ele faz exatamente o
mesmo que fazia antes. Isso era de se esperar porque não
mudamos nada. Acabamos de declarar
e inicializar uma variável e a estamos enviando para a janela
preta como Exatamente a mesma coisa
que estamos fazendo aqui. Uma coisa bem rápida,
com nomes de variáveis, o que eu sempre faço é usar letras maiúsculas e minúsculas sempre com um caractere
menor no início. Agora, isso depende de você, mas geralmente é assim que
as pessoas tendem a usar variáveis. Talvez quando você trabalhar em uma
empresa no futuro, se é isso que você quer fazer, outras pessoas
façam algo semelhante. É bom introduzir
boas práticas. Agora, essa é a única
razão pela qual eu faço isso. Então, a cada próxima
palavra, olá mundo. Isso terá letras maiúsculas. Se tivermos outra palavra aqui
, essa
começará com maiúsculas. Isso é exatamente o que chamamos de
padrões, é opcional. Vamos falar sobre o que é
declaração e o que é inicialização para
cobrir esses dois termos Vou expandir
nosso pequeno exemplo aqui. Agora vou perguntar: Como você
está assim? E então eu vou reenviar a variável para a tela. Em seguida, vou
executar o aplicativo. Então você pode ver o que está acontecendo. Você pode ver aqui na
janela que diz, olá mundo. Como você está? Dê uma
olhada em como isso funciona? Você pode ver aqui,
definimos nossa variável, demos a ela um tipo. Agora, só atribuímos um tipo à
variável uma vez. Estamos dizendo, oh, ei, computador, essa é a nossa variável
que eu quero usar. Essa é nossa nova variável, aliás, é uma variável de
string. Agora, fizemos isso uma vez. Não precisamos mais dizer
ao computador que é uma string, o computador já sabe
e se lembra disso Agora, toda vez que
modificarmos nossa variável, atribuirmos a ela um novo valor, vamos sobrescrever
o que já está lá Quando essa linha aparecer, essa parte será
substituída por “Como você está?” E então vamos
colocá-lo de volta aqui. Não precisamos declarar e inicializar nossa
variável em uma linha Vamos dar uma olhada
nesse exemplo aqui. Eu também poderia fazer isso. A mesma coisa vai acontecer. O que estou fazendo aqui é
declarar nossa variável,
declarar significa, ei, computador, eu quero criar uma nova Sei que será
uma string, mas ainda não sei qual será o
valor. Talvez eu decida mais
tarde. Em um momento posterior. Ok, eu decidi qual será
o valor. Vai ser Hello World. Então eu quero
enviá-lo para a tela. E então eu estou reinicializando aqui e enviando para
a tela Isso é declaração ou
declaração de uma variável. Isso é inicialização
ou atribuição. Há algumas palavras que você
ouvirá no futuro
se continuar
programando com C Sharp. Você pode ver que estamos fazendo
isso em duas linhas e a saída é exatamente
a mesma de antes, que era de se esperar. Uma última coisa: se declararmos
uma variável aqui e
tentarmos gerá-la sem
inicializá-la ou atribuí-la
, isso
gerará um erro Podemos ver essa linha
ondulada vermelha. Quando passamos o mouse
sobre a linha vermelha, temos uma pequena ideia de qual é
o problema E está apenas dizendo uso de variável
não atribuída,
olá mundo. Está nos dizendo qual é
o problema. Sempre que temos um erro, não
podemos executar o programa porque sempre
precisamos
corrigir esses erros Essa é uma visão muito básica de como as variáveis funcionam em C sharp.
6. 1-3. Tipos de dados: Ok, vamos falar sobre
os tipos de dados, o que são, como podem nos ajudar, por que podemos usá-los e tudo mais. Então, eu tenho um
aplicativo de amostra aqui. Realmente não faz muita coisa. Declaramos e inicializamos
duas variáveis de string aqui e as enviamos
para nossa janela preta Quando executo o aplicativo aqui, ele diz apenas calças quadradas do
Bob Esponja Pensei em um exemplo de como explicar os
tipos de dados com muito mais facilidade. Eu inventei um exemplo. Você já jogou cartas ou equipamentos de
Top Trumps ou Pokémon
ou algo parecido, onde você tem o
nome do personagem, talvez alguns atributos como idade,
peso, altura, raridade Acho que isso representaria muito bem
os tipos de dados. E me ajude a explicá-los para que você
os entenda muito mais facilmente. Imagine um cartão que tenha um nome
e possa ter uma idade. Por exemplo, essa é a
idade do personagem. Agora Bob Esponja é um
daqueles personagens que transcende todas as idades Vou colocar 21. Essa é uma variável do tipo string, é um tipo de dados. Outro tipo de dados que podemos usar
é o que chamamos de número inteiro. Agora, o que
é um número inteiro, é um número. Na verdade, podemos passar o mouse sobre ele e o Visual Studio realmente nos
dá mais
informações sobre isso Ele representa um inteiro assinado de 32
bits 32 bits significa apenas o tamanho Quanta informação
você pode colocar aqui. Acho que está em qualquer lugar
entre
2 bilhões negativos e 2 bilhões positivos. Acho que usar a idade
se encaixa muito bem
nisso, serão apenas 23 dígitos Quando usamos variáveis do
tipo inteiro, não
precisamos dessas
aspas duplas, como nas strings Só precisamos de um
número aqui. Outro, talvez o peso, e isso será em libras. Talvez essa esponja pese
cerca de 120 libras, algo assim.
Outra altura. Agora, altura, vamos
colocá-la em pés e polegadas. Vou colocá-lo
em pés e polegadas para que eu possa mostrar um novo tipo de dados. Isso é chamado de duplo. Agora, o que é um duplo, ele representa números decimais Vamos colocar a altura aqui. Digamos que nossa esponja
tenha três pés, 4 “, por exemplo.
Algo parecido. Então essa é a altura
da nossa esponja. Se tivermos um overdouble aqui, ele representa um ponto flutuante
de precisão dupla. Muito complicado, não é? E é por isso que as pessoas
aprendem com os tutoriais um duplo representa um decimal Isso é qualquer coisa com um ponto
decimal. Agora, decimais Vamos falar sobre
decimais rapidamente. Em C nítido, podemos representar um número decimal de
uma das três maneiras Outro é chamado de flutuador. Vamos colocar números depois disso. Quando você usa uma variável, todas
elas precisam
ter nomes exclusivos. Vamos fazer decimal. Essa é outra forma de
calcularmos números decimais. Essas são as três maneiras pelas quais podemos representar decimais em C A principal diferença
é a precisão. Agora, o float é, eu acredito, 32 bits. São apenas sete dígitos. Você pode fornecer
mais de sete dígitos, mas será cortado. Trunque-o às sete. Você perde tudo
depois de sete dígitos, o que é toda essa precisão aqui Agora um 64 bits. Um pouco mais, eu acho. 15 dígitos, 15 a 16 dígitos.
Portanto, é mais preciso. Então, podemos colocar até 15 aqui. Por padrão, um duplo é usado quando você usa
números decimais em C nítido Quando eu disser padrão,
explicarei isso em um segundo. O último é decimal. Acho que esse é de 128 bits, muitos e muitos dígitos Acho que 28 dígitos, bem longos. Usamos decimais quando falamos sobre coisas relacionadas a dinheiro Talvez, se você escrever um
formulário para lidar com impostos como uma agência governamental, por exemplo, queiramos
garantir que todos paguem seus impostos até o
ponto decimal Quando você lida com dinheiro, ele precisa ser muito, muito preciso e é
aí que usaríamos um decimal Você pode ver aqui que
quando eu inicializo essa
variável do tipo de dados flutuante de altura um, eu coloco um pouco de F
no final Isso diz C sharp. Ei, eu quero inicializar
um valor flutuante. Isso ocorre porque ele usa
double como padrão. Você pode ver que quando eu
inicializo um duplo, não preciso colocar
uma letra no final Sempre que eu colocar um valor
decimal aqui, C sharp assumirá que
é um duplo Se eu quiser inicializar
um float aqui, devo dizer, a propósito, esse é um tipo de dados float Porque se eu não fizer isso, você pode ver que há uma linha vermelha. Eu passo o mouse sobre ele. Diz que o tipo duplo
literal não pode ser implicitamente
complicado, não é? Basicamente, diz: use um sufixo para criar um
literal desse tipo É basicamente dizer, ei, você tem um tipo de dados flutuante, coloque um F no final
e então ficaremos felizes mesmo com decimal, não
sei se você não usa um D ou algo
mais descritivo, provavelmente
é usado Este quer um M. E, da
mesma forma, se não colocarmos um M, ele está dizendo para você
colocar um M. É
por isso que o IDEs é chamado de IDE, como o Visual Studio, muito bom. Na verdade, está dizendo o que
você está perdendo e
o que precisa fazer. Se você usa algo
como o Bloco de Notas, ele não vai te dizer isso Isso ajuda você a
programar muito mais rápido. Então, essas são as três
maneiras pelas quais podemos representar números
decimais e vamos usar
apenas um
duplo para a altura A altura da nossa
esponja é de três pontos, não
sei, três pés, 4 “, algo assim Eu acho que isso seria
bom. Agora, o próximo que eu quero apresentar é um
Bolen representado por bool Isso é o que poderia ser a booling? Se nosso
cartão comercial é a primeira adição? Então, vou colocar
sua primeira adição. Eu vou dizer que é verdade. Bob Esponja é uma carta colecionável muito
rara e é a primeira adição,
então será verdade Agora, os tipos de dados de booling podem ter o valor verdadeiro ou falso Apenas um desses
dois valores é verdadeiro. Se for sim ou falso. Não. É assim que usamos
boolings em C sharp É verdadeiro ou falso.
Apenas dois objetos de valor Se você quiser uma variável que possa ter três ou quatro valores, não
use um booling As reservas são para apenas dois valores. O último sobre o qual vou
falar agora, há muitos
tipos de dados em C Sharp Podemos fazer datas, horários, várias coisas complicadas, como listas e coisas assim. Mas, para ser honesto com
cadeias de caracteres, números inteiros e valores
decimais, como os
números duplos e os caracteres,
aqui podemos escrever
praticamente qualquer coisa,
muitos e muitos softwares
com apenas aqui podemos escrever
praticamente qualquer coisa, esses tipos de dados Talvez abordemos
mais no futuro. O último sobre o qual vou
falar são os personagens representados
por Shah, aqui mesmo Por isso, vou
chamá-lo de nota. A nota do nosso cartão
é excelente? Então isso pode ser ou
é ruim? Isso poderia ser um. Então, um cartão comum pode ser
como quando você faz um exame. Então, nossa nota pode ser
algo assim. E esse é um cartão muito bom. Sua primeira edição tem
qualidade menta, atribuindo-lhe uma nota A.
Quando você inicializa variáveis de caracteres, usamos aspas simples,
não aspas duplas aqui O Visual Studio faz
um bom trabalho aqui. Se você esquecer as aspas
, provavelmente
dirá que você precisa
delas ou apresentará um
erro enigmático como este Sim, agora
declaramos e inicializamos
todas as nossas várias variáveis com todos os seus tipos diferentes Agora eu só quero
enviá-los para a tela. Você pode ver que eles têm a
linha verde abaixo de cada um
agora , quando eu uso a idade aqui embaixo. Veja a linha verde
desaparecer com menos de idade, e isso é porque agora a
estamos usando. Vou colocar um para cada variável diferente aqui por meio do poder da edição. Podemos ver aqui agora
que estamos enviando tudo isso para a tela se
executarmos esse aplicativo Agora podemos ver todos os nossos vários valores para
todas as nossas diferentes variáveis. Vemos o primeiro
nome, o sobrenome, a idade, o peso, a altura. É verdade porque é a
primeira edição e também é uma carta
colecionável muito boa.
7. 1-4. C# - uma linguagem fortemente tipada por estáticas: Quero falar sobre duas
coisas agora relacionadas ao C Sharp, agora que entendemos
quais são os tipos de dados. Agora, C Sharp é o que é chamado de linguagem fortemente digitada
e também de linguagem de
digitação estática Vamos falar sobre quais são
esses dois termos. Uma linguagem fortemente digitada,
isso significa que, depois de
definirmos uma variável chamada primeiro nome e fornecermos a
ela o tipo de dados string, ela deverá ser uma string durante toda
a vida útil
do aplicativo Não podemos, por exemplo, pegar o primeiro nome e depois atribuir a ele um valor inteiro porque
ele não vai gostar disso Isso porque é uma linguagem
fortemente digitada. No entanto, se você usa uma
linguagem como Python, por exemplo, você pode fazer
isso, não tem problema algum Isso porque não é uma linguagem
fortemente digitada. Nesse caso, isso é o que é uma linguagem
fortemente digitada. Depois de definir uma string, você deu a ela um nome exclusivo. Você não pode então inserir um tipo de dados
diferente aqui. Você não pode dizer, oh, agora eu quero dizer que é verdade, por exemplo,
não vai funcionar. Isso
lhe dirá que é linguagem
fortemente tipada,
como C Sharp, a última é chamada
de linguagem de digitação estática Se cometermos um erro relacionado
a um desses tipos de dados, por exemplo, temos o primeiro nome. Portanto, ele espera uma
string entre aspas duplas, como aqui, se dermos um número inteiro, ele
reclamará Vai dar uma
linha vermelha abaixo de quando. Sempre que temos uma linha
vermelha abaixo,
algo como esse erro aqui, algo como esse erro aqui, não
podemos compilar Não vai para letras, não vai para letras. Por exemplo, se
você estiver usando o Windows, compile seu código em um arquivo EXC e entregue-o a
um amigo para executá-lo.
Não vai funcionar. Isso porque esses erros
são detectados em tempo de compilação. E isso é o que é uma linguagem
digitada estaticamente. Se cometermos um erro
como esse, não
o
descobriremos posteriormente quando um usuário
estiver usando o software. Essa é uma
vantagem muito boa do C Sharp e também de linguagens como C
plus plus, muito semelhantes. Quando temos uma string de tipo de dados, ela precisa de um valor de string. Esses erros serão
detectados em tempo de compilação. E é aí que pressionamos esse pequeno botão
verde Play aqui. Isso é o que é uma linguagem fortemente
digitada. E também uma linguagem de
digitação estática, C Sharp é ambas
8. 1-5. Trabalhando com cordas e substrings: Ok, vamos ver
como podemos trabalhar com algumas
variáveis do tipo string em C sharp. Aqui temos um
exemplo de aplicativo. Só temos o
nome e o sobrenome e estamos exibindo
os dois na janela do console Agora, como podemos realmente
unir duas cordas? Eu tenho o primeiro nome de
uma variável, o sobrenome de uma variável. No momento, ele os coloca separadamente
em duas linhas diferentes. Mas como faço para
juntá-los? O que podemos fazer aqui, o que é
chamado de concatenar
duas cordas, é apenas uma maneira
elegante de dizer junte-as Concatenação, pode
ser como concat, para abreviar. Essas são palavras que você
ouvirá talvez
no futuro se continuar
sua jornada com C sharp. Vamos ver como unir essas
duas cordas. O que eu vou
fazer é usar o que é chamado de operador. Então você pode ver essa vantagem aqui. E o que
isso faz é pegar
essa corda e juntá-la. Muito simples, não é? Então, agora executamos o aplicativo. Podemos ver que temos Bob Esponja, calças
quadradas em uma linha Mas você pode ver que não há espaço em
branco no meio aqui. Então, vamos ver como adicionar isso. O que podemos fazer aqui é adicionar outra string e
usar o símbolo de adição. Novamente, o que estamos fazendo aqui é pegar a primeira
variável, o primeiro nome. Estamos concatenando-a,
juntando-a a esse espaço y vazio, que também é uma string E depois juntando-o
ao sobrenome, que é uma variável aqui. Agora, isso não é uma variável, não
precisamos de variáveis aqui. Poderíamos fazer isso facilmente, e é exatamente o mesmo. Dessa forma, nem estamos
usando essa variável, mas a saída
será exatamente a mesma. É assim que podemos unir
duas cordas. Só para que você entenda completamente, podemos até criar
uma variável aqui e podemos fazer o nome
mais o sobrenome. Então, podemos colocar o nome completo aqui e teremos
exatamente o mesmo resultado. Não vamos esquecer nosso espaço em
branco aqui. Parece apresentável e vamos executar
o aplicativo Você pode ver aqui que temos
exatamente o mesmo resultado. Estamos apenas usando uma variável
aqui chamada nome completo. E isso é apenas somar
essas coisas, concatiná-las, É assim que podemos unir
duas cordas,
muito simplesmente, substrings muito simplesmente, substrings O que é uma substring? Agora, uma substring é apenas uma das muitas coisas diferentes que você pode
fazer com strings em C sharp Aqui está um exemplo. Aqui
temos uma variável chamada nome. Tem esponja Bob. A
libra quadrada define o valor. E estamos colocando isso
na tela agora, por exemplo, digamos que eu queira extrair uma
certa parte dessa string. Eu quero extrair a
palavra esponja disso. Eu não quero o
resto dessas coisas, eu só quero essa
parte aqui. Agora, o que podemos fazer é usar algo chamado método substring para extrair
uma parte da nossa string E isso é o que é uma substring. É parte de uma corda. Eu aguentaria isso,
eu aguentaria isso. Eu poderia pegar o que eu quisesse. Eu poderia até pegar uma
carta, se quisesse. Vamos ver como podemos
realmente usar uma substring. O que eu vou fazer é
extrair a esponja, a variável Podemos chamá-la do que quisermos, vamos chamá-la de esponja. Por que não? Queremos inicializar a esponja,
então usamos nosso sinal de igual. Quando trabalhamos com uma variável, o que podemos fazer é colocar o
nome da variável aqui, que é nome,
nesse caso, quando usamos um ponto ou um dardo, como
você quiser chamá-lo Depois, temos todas essas
coisas diferentes que podemos fazer com ele. Algumas das mais
comuns estão sempre
no topo com essa
estrela negra ao lado delas. Um deles é substring. Podemos fazer muitas
coisas que podemos substituir. Podemos diminuir os caracteres. Podemos dividi-lo, muitas coisas
diferentes que podemos fazer. Substring é o que
queremos usar. Podemos clicar duas vezes aqui quando
abrimos parênteses aqui, temos algumas opções que
podemos fazer Agora, vou falar
sobre essas coisas
muito mais tarde, quando
falar sobre métodos. Mas, na maioria das vezes,
vou colocar duas coisas aqui. E é isso que eu
quero fazer aqui. Agora, em C sharp, tudo começa do zero. O índice está em zero. Essa string aqui,
esse caractere aqui, essa é a posição zero. O P está na posição 123. Tudo começa do zero. Lembre-se de que avançar é posição zero do
personagem de nossa calça quadrada
Bob Sponge Então, o primeiro valor aqui é zero porque queremos
começar na posição zero. Então, o próximo valor é quantas letras você
deseja extrair
da esponja 12345.
Na verdade, são seis. Agora, queremos extrair
a
esponja dos seis primeiros caracteres aqui Esses são os valores
que colocamos aqui. Agora, se isso é confuso para você, vamos voltar para onde falamos sobre a linha direita do console Tínhamos a linha direita do console e
abrimos os parênteses aqui. Queremos colocar nossa variável
na janela preta. Agora, substring, neste exemplo, queremos dar a ela dois valores E quando atribuímos dois valores, os separamos com uma
vírgula, assim queremos
o primeiro
caractere e queremos contar
seis caracteres para frente, os quais
devemos extrair a esponja Agora, queremos colocar uma esponja na janela do console para que possamos
realmente ver o resultado Vamos compilar nosso aplicativo. Podemos ver com a
esponja de saída aqui. É assim que a substring funciona de
forma muito simplista. Se quisermos extrair, digamos, Bob, por exemplo, começamos na posição seis e contamos três
caracteres para frente. Então, podemos ver que
extraímos Bob É assim
que uma substring Outra coisa que podemos fazer é
o que chamamos de substituição. Temos calças
quadradas do Bob Esponja aqui. Digamos que queremos substituir
Bob Esponja por outra coisa, digamos Patrick ou
algo parecido Vamos criar uma nova variável. Vamos chamá-lo de Pat for Patrick. Não importa como
chamamos isso. Estamos trabalhando com nossa cadeia de nomes aqui.
Vamos deixar isso. Quando pressionamos o ponto novamente, obtemos todas essas coisas
que podemos fazer com ele e vamos clicar
duas vezes, substituir por
, substituir. Podemos substituir qualquer coisa
por qualquer outra coisa. O que eu quero fazer é
substituir Bob Esponja. Quero dar a ela um
novo valor, Patrick. Sempre termine com ponto e vírgula. O que isso vai
fazer é pegar o nome, tudo dentro do nome, pegar tudo
isso,
queremos substituir
todas as ocorrências queremos substituir
todas as ocorrências tipo
Bob Esponja e queremos
substituí-las por Patrick Em seguida, o resultado dessa
operação é armazenado em Pat. Então podemos colocar Pat aqui. Se executarmos o aplicativo, podemos ver agora que diz
Patrick square pants. Isso porque estamos substituindo todas as ocorrências de Bob
Esponja por Patrick E quando eu digo cada ocorrência, vamos tentar isso, executar
o aplicativo. Substituiu todas as ocorrências de Bob Esponja por Patrick É assim que a substituição
funciona em C Sharp. E, novamente, você
não precisa armazenar o resultado desse cálculo
em uma variável totalmente nova. Podemos encurtar isso, basta colocá-lo lá, e isso também
funcionará muito bem Você pode ver Patrick em libras
quadradas Patrick. Patrick Patrick. Você pode ver que é assim que a substituição funciona ao lidar com cordas. Outra coisa que podemos fazer com cordas é calcular o
comprimento da corda Essa é muito simples. Aqui eu tenho uma variável
chamada exemplo. Isso é tudo dentro
dessa variável para trabalhar. Por exemplo, eu coloco um pequeno
dardo depois e digito comprimento para
tornar isso mais rápido Você pode clicar duas vezes nele
ou pressionar a tecla tab
no teclado. Talvez seja muito mais rápido inserir esses valores no futuro quando eu
compilar o aplicativo Agora podemos ver que essa frase aqui tem
44 caracteres. Isso é muito útil
quando você usa substrings para extrair certas
coisas de uma substring Vamos falar sobre outro
método chamado índice de. Agora, o índice de faz é que, se você especificar uma palavra
como Bob Esponja, ela realmente dirá o índice de onde
ela está na string Em vez de contar
1-234-567-8910, posição
22 do
caractere, por exemplo, não
precisamos contar.
Na verdade, podemos usar Se eu colocar índice
, quero colocar,
por exemplo, Bob Esponja Isso estará entre aspas duplas, porque Bob Esponja é uma corda, queremos armazenar
o resultado disso Agora, se passarmos o mouse sobre o índice de, você pode ver aqui ao
lado desse cubo rosa, diz t. Isso significa que
o resultado disso
será um inteiro s
definindo um novo inteiro Vou chamá-lo apenas de índice. Em seguida, vou enviar
o índice para a janela. Vamos fazer isso bem rápido. Você pode ver que aparentemente
Bob Esponja é um personagem na posição 22 aqui São 22 caracteres no índice de outro método que é bastante útil para obter o índice de
qualquer palavra que você queira. Você poderia colocar, por exemplo, algo
assim. Se executarmos isso, ele obtém a primeira ocorrência,
que é esta aqui, 012, essa é a
primeira ocorrência Novamente, há muitas coisas
diferentes que você pode fazer com o índice de,
mas isso é um exemplo.
9. 1-6. Trabalhando com números: Ok, vamos ver
alguns exemplos de como trabalhar com
números em C nítido. Vamos analisar
multiplicação, adição,
subtração, divisão,
todas essas coisas Então, vamos embora. Vamos dar uma olhada em
um exemplo de adição. Então, como adicionamos números em nitidez. Temos um exemplo de
aplicativo aqui. Estamos apenas definindo uma variável, configurando-a como zero e
enviando-a para a tela Então, na verdade, não
está acontecendo muita coisa aqui. Vamos usar nossa variável. Eu só vou
fazer cinco mais quatro, que sabemos que é igual Vou apenas
executar o programa e obtemos nove como saída. A adição é muito simples, você pode continuar com isso, etc. Muito fácil. mesmo com a subtração, podemos praticamente
fazer a mesma coisa Cinco menos seis é menos um. Você pode ver que a subtração
também é muito fácil. Novamente, você pode fazer
isso, misturar os dois. Isso realmente não importa. Isso vai resolver isso
para você. Multiplicação. Vamos fazer três multiplicado por
quatro para multiplicar números em C Use esse asterisco aqui, a pequena estrela, e obteremos
12 como resultado Novamente, podemos combinar multiplicação com
adição e subtração, assim como você faz em
matemática, Agora, é aqui há algumas
pegadinhas. Com a divisão,
o sinal de divisão é um avanço, vamos fazer um 13/3 fácil. Vamos
executar o aplicativo Porque há um, há
13,3 O resultado é um. No entanto, é assim que dividimos
os números. Está bem? Entendi você. O número
um é dividido por zero. Na verdade, não podemos
dividir por zero. Você pode realmente ver agora. De qualquer forma,
há alguns anos, se você fizesse três por zero, poderia executar o aplicativo
e obteria um erro. Como não é um cálculo realista
, não dá para funcionar. Agora temos uma
linha vermelha abaixo, e quando passamos o mouse sobre
ela, ela diz divisão
por Na verdade, não
nos permitirá executar nosso programa, mas como o
resultado da variável é zero, vamos inserir isso
lá e executar o programa. E, novamente, ele
erra exatamente como deveria. O primeiro erro que detectamos em tempo de
compilação quando
tentamos executar o aplicativo, porque estamos usando zero aqui, está nos dizendo que não conseguimos
executar o aplicativo Mas quando eu dei a ele uma
variável que é resultado, que também é igual a zero, podemos enganá-la
para executar o programa, mas ainda recebemos o erro tentar dividir por
zero, o que não podemos Então, isso é algo que
você deve sempre ter em mente ao trabalhar
com divisão. Você nunca deve dividir por zero. Quando falarmos sobre
declarações if no futuro, mostrarei como
você pode proteger seu programa para evitar a
divisão por zero e a outra pegadinha
com relação à divisão é usar
números decimais Vamos dar uma olhada em um exemplo de
número decimal. Vamos usar um tipo de dados
duplo aqui e vamos
inicializá-lo com zero Agora vamos dar um exemplo. Vamos fazer 3,45 0,6, o que
deve funcionar bem. Você pode ver aqui,
aqui está o resultado que está em formato decimal No entanto, se dissermos 200/3, esse não é um número
inteiro inteiro, ele terá uma
casa decimal nele No entanto, quando executamos
o aplicativo, você pode ver que ele está realmente
fazendo alguns arredondamentos aqui Acho que é até
o número inteiro mais próximo,
que é 66 No entanto, se adicionarmos 0,0 ao final deles
e executarmos o aplicativo, você pode ver que essa é
a verdadeira resposta aqui, 66,666 Em seguida, está arredondando para sete. Isso é algo que você deve prestar atenção ao trabalhar
com números decimais C sharp fará uma suposição porque se você tiver
dois números aqui, esse 200 é um inteiro, três é um Nenhum
desses decimais, é apenas o resultado
que é um O que C sharp está
fazendo é dizer, oh, ei, há
um número inteiro aqui Oh, ei, há um número inteiro aqui. Eu vou te dar o
resultado como um número inteiro. Isso é um pouco chato. O que você precisa fazer é alterar pelo
menos um deles
para um número decimal Quando você faz isso, você pode ver que obtemos o verdadeiro resultado aqui. Isso é algo que você realmente
deve ter em mente ao trabalhar com a
divisão de números decimais O próximo operador que vou
mostrar é o operador de
módulo Vamos colocar isso de
volta como um número inteiro. Agora, o que o
operador de módulo faz é fornecer o restante
de um cálculo Deixe-me dar um exemplo bem rápido. O módulo é representado
por uma marca percentual. Aqui, o que isso faz, diz, quantas vezes três
se transforma em seis? Bem, três entra em seis duas vezes e depois não
resta mais O resultado disso será zero porque é o
restante disso Novamente, se eu fizer 22
em 63 vezes, perfeitamente novamente, não
há mais nada No entanto, se eu colocar quatro aqui, quatro vai para seis uma vez. No entanto, há um
restante de dois, então esse será o resultado dois O que o módulo faz é fornecer o restante de um cálculo Depois de dividir este
por este, 14 vai para seis uma vez
com o restante de dois Se eu executar o
aplicativo, obtemos dois, assim como no
primeiro exemplo, três entra em seis duas vezes
e não há mais nada, o resultado deve ser zero O módulo é bastante útil
quando queremos saber se um número vai exatamente
para outro número Se o resultado for zero, sabemos que é perfeitamente
divisível por esse número Isso é o que é módulo, ou módulo, como
você quiser chamá-lo E é representado por uma única porcentagem,
exatamente assim. Agora eu quero falar
sobre a ordem das operações ao trabalhar
com multiplicação,
adição, subtração,
todas essas coisas Deixe-me mostrar um exemplo. Eu tenho o resultado, que é nossa variável cinco multiplicada por quatro -2/7. Quero
adicionar o resultado
de cinco Vamos dar uma
olhada nesse exemplo. Se você já fez muita
matemática no passado, talvez possa
pular esta seção Pode ser bastante
óbvio para você, mas C sharp funciona
exatamente da mesma forma que a matemática
no mundo real. Se você já viu essas coisas no Facebook ou no Instagram e eles dizem, oh, qual
é a resposta disso? E as pessoas estão dando todas
as respostas erradas
porque não entendem
a ordem das operações. Aqui temos essa coisa em matemática chamada massa de
oferta ou massa corporal Deixe-me te mostrar isso agora. Ofereça missa, algumas pessoas a
chamam de Bodmass. Isso realmente não importa.
A única diferença é o I aqui e o o o aqui. Mas eles significam a mesma coisa. Então, a primeira coisa são colchetes. Se tivermos um
cálculo como esse, qualquer coisa dentro dos
colchetes acontece primeiro Cinco mais um. Isso acontece
primeiro, que é seis. E então podemos remover isso e ele é substituído por seis. A próxima coisa que
acontece é o I ou o que está na potência de, ou a raiz quadrada de. Não temos nada
disso aqui , então podemos pular isso O próximo passo é a divisão. A divisão acontece a seguir, e isso é 2/7 Agora, não
tenho certeza do que é 2/7,
é um número decimal, mas isso acontecerá Esse cálculo aqui. A próxima coisa que
acontece é a multiplicação. Isso aqui,
isso será
resolvido nos próximos cinco multiplicados
por quatro, que é 20 Então, qualquer adição depois disso, então o resultado disso será adicionado
a seis seguido pela subtração até
a última coisa que acontece é esta aqui Essa é a ordem em que
isso é calculado. Isso não acontece
da esquerda para a direita. Cinco vezes quatro menos dois. Isso sempre acontece
na ordem
dos símbolos, assim
como a matemática. Por exemplo, se
executarmos o programa, bem, tudo pode ser resolvido. Para nós, o resultado é 26. Essa é a ordem das operações. Algo que você deve ter em mente ao trabalhar com
isso em C sharp. A última coisa que vou falar sobre
trabalhar com números é dois elevado a
dois, que é quatro. Se você não está muito
familiarizado com matemática, o poder de significa apenas
quantas vezes ele é
multiplicado por si mesmo Dois elevado a
dois é a
mesma coisa que dizer dois multiplicado
por 22 elevado a três significa basicamente duas vezes
22 multiplicado por dois multiplicado por dois Novamente, esse é o poder do. A razão pela qual estou
mostrando o poder de é porque o
poder de não tem um símbolo como
multiplicação ou subtração, temos que utilizar o que é
chamado de Agora vamos dar uma olhada nisso.
Agora, se eu disser resultado, que é a variável que
definimos aqui, então eu digo matemática MAT H com M maiúsculo. Quando
pressiono o símbolo do ponto final aqui, há muitas
coisas diferentes que podemos fazer. Tudo isso está incorporado em
nossa biblioteca C sharp aqui, e podemos usar qualquer um deles. Olha, o sinal, carros, bronzeado,
truncado, logaritmo,
todas Mas o que eu
vou usar é o poder,
que é representado pelo prisioneiro Se abrirmos colchetes aqui, ele está pedindo nosso
primeiro número aqui embaixo, diz
que um número
de ponto
flutuante de precisão dupla deve ser elevado a uma potência Digamos que queremos ver dois elevado
à potência de dois. Está pedindo um duplo, que é um decimal Vou colocar 2.0 porque ele quer
em formato decimal Quero aumentar para
a potência de dois novamente, terminar com ponto e vírgula Dois elevado a
dois é dizer dois, multiplique por dois. A
resposta deve ser quatro. Você pode ver aqui
que a resposta é quatro. Se quisermos fazer dois elevado a três,
deve ser oito. Você pode ver para onde isso está indo, 163264128. Aí está. É assim que se faz o poder do, mas não só o poder do. Na verdade, você pode
utilizar muitas coisas nesta aula de matemática aqui, todas coisas diferentes aqui. Mas esse é um exemplo de
como usar o poder e trabalhar com
números na loja.
10. 1-7. Como obter informações do usuário: Vamos dar uma olhada na
interação com nosso software. Na maioria das vezes, quando
executamos nosso aplicativo, até
agora só podemos ver
os resultados na tela. Mas agora eu quero que você
interaja com seu software. Você pode fornecer
algumas informações. Por exemplo, vamos dar uma olhada em como fazer isso
com um aplicativo de console. No momento, temos um aplicativo de
amostra, que está apenas imprimindo qual é o
seu nome na tela. Quando eu executo isso, é só
dizer qual é o seu nome? Quero poder digitar meu nome aqui, por
exemplo, Robert. E então, quando eu pressiono Enter, quero que ele diga oi Robert, por exemplo.
Algo parecido. Podemos utilizar a
linha de leitura aqui. Até agora,
usamos essa linha
apenas para interromper o aplicativo, que nossa janela
não feche para nós Porque lembre-se, sem isso, a janela desaparece
instantaneamente No entanto, ele
tem uma função, o que a linha de leitura faz. Na verdade, ele captura
algumas informações nossas. O que acontece se passarmos o
mouse sobre isso? Na verdade, ele diz que
lê a próxima linha de caracteres do fluxo de entrada
padrão. Muito complicado não é.
O que isso basicamente faz é capturar nossa entrada quando
pressionamos a tecla Enter
no teclado O resultado disso
podemos armazenar em uma string. Se discutirmos isso,
você pode ver a string aqui. Isso é o que volta para nós. Podemos definir uma nova variável. Chamaremos isso de resultado.
Poderíamos chamar isso de entrada do usuário. Podemos chamá-lo do que
quisermos. O que estamos fazendo
agora é obter
o resultado dessa operação, que é uma linha de leitura que pega tudo o que
digitamos lá depois de
pressionarmos enter e o armazena
nessa variável aqui Então o que eu quero fazer é dizer olá para qualquer
nome que você colocar aqui. Lembre-se de como
concateinar cordas. Temos nossa primeira
sequência aqui, olá. As cadeias de caracteres são delimitadas
por aspas duplas. Em seguida, queremos
unir uma string com o resultado dessa operação, que também é uma string. Nós
vamos fazer isso lá. Queremos parecer
muito entusiasmados. Também vamos fazer um ponto de
exclamação. Estamos unindo três
cordas. Olá, o ponto de
exclamação e o resultado, que é uma variável
de string do resultado da entrada
do usuário Vamos executar esse aplicativo. Agora está dizendo
qual é o seu nome? Eu vou colocar Robert. Quando eu pressiono Enter, não
temos nada porque
não mandamos ele manter
a janela do console aberta. Vamos colocar isso de volta
lá novamente. Aperte o botão play,
digite nosso nome, Hit, e agora ele está
dizendo olá Robert. É bem fácil, não é? E é assim que se captura a entrada
do usuário em um aplicativo de
console.
11. 1-8. EXERCÍCIO: o jogo de multiplicador de números: Ok, vamos dar
uma olhada em um exemplo rápido agora. Um pequeno
aplicativo prático para testar seus conhecimentos sobre como trabalhar
com números em C Sharp. Também vou testar alguns dos conhecimentos que
você aprendeu até agora. E vou apresentar o conceito de
conversão de tipos de dados, converter uma string em um número
inteiro Vamos dar uma olhada nisso agora. Então, o que vamos
fazer é
construir uma calculadora de amostra, mas nossa calculadora só vai multiplicar dois
números juntos Não é uma
calculadora muito sofisticada. Vamos começar aqui. Vamos dar as boas-vindas
ao nosso alicate numérico. Queremos dizer ao
usuário o que é isso. Vamos dizer, oh, ei, bem-vindo ao nosso multiplicador
de números Em seguida, vamos
pedir o primeiro número deles. Esse é o primeiro
número, eles vão se
multiplicar por outro número Qual é o seu primeiro número? Estamos perguntando ao usuário qual é
o primeiro número. Para obter a entrada do usuário, usamos a linha de leitura do console. Então, o resultado disso,
precisamos armazenar em uma variável, chamaremos esse primeiro número. Agora, o primeiro número conterá
o primeiro número do usuário. Agora, imediatamente, você vê essa linha vermelha abaixo da linha de leitura
do console Se passarmos o mouse sobre
isso, podemos ver que aqui não é possível converter
implicitamente o
tipo string O que está dizendo é, ok, look read line fornece uma string porque estamos
solicitando a entrada do usuário. E eles poderiam colocar uma frase, eles poderiam colocar muitas cartas. Não sabemos o que o usuário
vai colocar aqui,
basicamente, mas na verdade
queremos um número inteiro a partir disso O usuário pode digitar hello e estamos tentando colocar
hello em um número inteiro, então
haverá um problema O que queremos fazer é
usar a biblioteca de conversão. Ou seja, se você digitar
converter para C maiúsculo, pressione ponto final aqui, temos muitas opções
que podemos fazer aqui. O que a conversão faz?
Ele nos fornece vários métodos
diferentes de
conversão de tipos de dados O que queremos fazer é converter uma string porque essa é
a entrada do usuário. Queremos o resultado
como um número inteiro, que será nosso primeiro número Quando eu pressiono aqui, o que eu quero é dois int int 32. Talvez eu não tenha
explicado isso ainda, mas um INT padrão
também é considerado int 32. É um número inteiro de 32 bits. Você pode ter um
número inteiro mais longo que suporte mais dígitos ou até mesmo
um número inteiro menor Int 32 é um
número inteiro padrão em C Sharp. Quando abro parênteses sobre isso, ele está solicitando um valor de string Essa é a string
que será convertida em um número inteiro e
nosso valor de string,
bem, esse é o resultado
da entrada do usuário Essa é a linha vermelha do console. Vamos colocar isso
lá. Fecharemos nossos colchetes e
colocaremos dois pontos em Sami Agora você pode ver que a linha
vermelha desapareceu. Da mesma forma, você pode simplesmente armazenar o resultado disso
em uma nova variável, uma variável de string,
e colocá-la aqui. Realmente não importa, mas estamos fazendo tudo em uma linha. Agora, o que queremos
fazer a seguir é pegar o segundo número do
usuário, o segundo número. Essa será uma nova variável
chamada segundo número. Queremos perguntar ao usuário qual é
o segundo número. Agora temos o primeiro número do
usuário nessa variável inteira aqui
e o segundo número do usuário aqui Agora queremos o resultado disso,
que será o resultado do cálculo do primeiro número,
lembre-se de que
a multiplicação é o ponto e vírgula do segundo
número do asterisco Em seguida, queremos dizer ao usuário qual
é o resultado. Vamos fazer isso. Vamos dizer que
o resultado é, então vamos concatenar as strings,
que é
o Então queremos isso para que a
janela não feche. Vamos executar o aplicativo aqui. Olha, bem-vindo ao nosso multiplicador
de números. Qual é o seu primeiro número? Por que não o número quatro? Qual
é o seu segundo número? Que tal o número cinco?
E isso deve ser igual a 20. Diz que o resultado é 20. Muito legal, não é? Novamente, podemos usar
números diferentes lá, mas essa é uma visão muito
simplista de como podemos obter a entrada do usuário
usando a linha de leitura do console, como podemos converter tipos de dados Então, estamos convertendo uma string
que é a entrada do usuário, um inteiro que é
nossa variável Então, quando multiplicamos
nossos números inteiros, obtemos o resultado e estamos apenas informando
o resultado ao usuário Essa é uma maneira muito simplista de trabalhar com
números em C. Sharp.
12. 2-1. Métodos: Agora eu quero falar
sobre métodos em Sharp. Na verdade, usamos
muitos métodos até agora. Por exemplo, a
linha direita é um método, linha de
leitura é um método em que o
auxiliar matemático era um método Agora vamos
criar nosso próprio método. Ao criar
métodos em C Sharp, todos
eles têm um propósito. Se você tem um trabalho
que geralmente é feito mais de uma vez ou
um trabalho complicado, você pode colocá-lo em
um método separado. Quando eu digo método, aqui está
um exemplo de um método aqui. Esse é o método principal. Tudo dentro desse método aqui está dentro
desses colchetes encaracolados. Aqui, o método principal é um método especial quando nosso software é
executado por padrão. O.NET Framework, que
é tudo em torno do qual o C Sharp é construído, procura um
método especial chamado main, e tem que ter esse nome E todos os nomes dos métodos são exclusivos, então eles não podem ter o mesmo
nome, assim como as variáveis. Depois de encontrar o método principal, ele executa todo o código dentro
dessas duas chaves Aqui, o único código que temos
são duas linhas aqui. Quando executamos o aplicativo, podemos ver o Hello World. E a próxima linha mantém
essa janela aberta para nós. Agora, vamos criar
um método totalmente novo em que diz vazio estático Eu abordarei isso em
um tutorial posterior. Por enquanto, vamos
simplificar as coisas. Depois de escrevermos static void. Nesse caso, queremos
dar um nome ao método. Agora, lembre-se de que eu disse que os métodos devem ter o propósito de manter
as coisas organizadas. Geralmente, eles devem
ter um propósito. Nosso novo método, o que
eu quero que ele faça, seu propósito, seu trabalho é
dizer olá mundo ao usuário. Essa é a única coisa
que ele vai fazer. Agora eu sei que é função, o que pretende fazer Posso chamar meu método com um nome que faça
sentido para as palavras. Vou ligar para
ele, dizer olá, mundo. Esse será o nome do
nosso método. Agora, a próxima seção
é chamada de parâmetros. Eu vou falar
sobre eles mais tarde. Vou manter
as coisas simples por enquanto. Faça um parêntese aberto
e um parêntese fechado. Em seguida, abra a calçada
e feche a calçada. Assim, você pode
ver que ele pode imitar isso. Todo o nosso código para o nosso
método estará aqui
nesta seção destacada
entre esta e esta. Todas as nossas funcionalidades
desse método estão aqui. Queremos dizer olá
mundo para o usuário. Bem, sabemos como fazer isso, já
abordamos isso antes. Essa é essa linha
de código aqui. Nosso método diga olá mundo. Seu trabalho é dizer olá, mundo. Então, isso vai
imprimir isso facilmente na janela preta. No momento, quando
executamos nosso software, na verdade, ele não
vai fazer nada. Por que isso? Isso porque o método principal é
executado por padrão. Então, esta seção aqui, e esta é a única
coisa que será executada
a partir do nosso método principal. Não sabemos nada sobre isso. O que precisamos fazer
aqui é dizer, oh, ei, você
pode executar nosso método para executar nosso método?
Nós simplesmente fazemos isso. Quando iniciamos o aplicativo, o método principal é executado. Ela desce, essa
linha é executada. Quando essa linha é executada, o código entra aqui. Esta linha está funcionando. O método
terminou seu trabalho. Ele volta para aqui
e termina
com esta seção aqui Quando você tem um
método, ele sai
, volta para dentro
e continua. Se executarmos o aplicativo, agora podemos ver o Hello world. Isso porque
agora estamos chamando nosso método. Só para recapitular,
se eu for rápido demais ou for complicado
sem essa linha, nosso método
nunca será executado Quando executamos nosso software, podemos criar muitos deles. 3.000 5.000 1.000 Novamente, todos
eles devem ter
um nome exclusivo Mas quando executamos o software, nada disso será executado. E isso é porque na verdade
não estamos dizendo ao computador que os
execute para executar um método. Novamente, fazemos isso novamente se
quisermos executar esse método, muito semelhante, etc É assim que se executa o método, é
assim que se
define o método. E essa é uma
visão muito simplista de como podemos configurar um
método muito simples em C sharp
13. 2-2. Parâmetros de método: Agora eu quero falar sobre os parâmetros do
método. Um parâmetro é apenas
uma maneira sofisticada de fornecer algumas
informações a um método. Aqui está. Aqui estão algumas informações.
Trabalhe com isso. Vamos usar um exemplo. Aqui está um exemplo. Estamos apenas dizendo olá mundo
para o usuário. Muito simples. Mas e se quisermos que esse
método diga olá John, olá Harry ou olá Roberto Esses nomes são algo que
o usuário pode nos fornecer. Aqui está um exemplo. fazer uma pergunta ao usuário. Nós vamos dizer,
qual é o seu nome? Qual é o seu nome. E então queremos
obter a entrada do usuário que é a linha de leitura de pontos do console. É assim que obtemos
a opinião do usuário. E nós armazenamos isso em uma string. Vou apenas chamá-lo de nome, perguntando o nome do usuário. O usuário digita algumas
informações e nós as inserimos em
uma variável chamada nome Agora, nosso método aqui, eu quero dizer olá, e então eu quero que ele diga
o resultado dessa variável, que
será o nome do usuário. Não sabemos o que é isso. O usuário pode digitar o que
quiser. Agora, o trabalho desse
método foi alterado. Eu não quero que ele
diga olá, mundo. Quero que ele diga
olá ao usuário. Agora vou dizer olá usuário. Seu trabalho mudou quando
chamei o método. Novamente, precisamos ter certeza de
que combina aqui. Não está mais
dizendo olá, mundo. Quero que ele diga olá
ao nome do usuário. Essa é nossa variável chamada nome. No entanto, veja, você pode ver que
há uma linha vermelha aqui embaixo. E isso porque nosso método aqui é
isolado desse método. Ele não
conhece essa variável porque ela foi
definida dentro desse método, esse método,
na verdade não a conhece. É assim que podemos usar parâmetros
para resolver esse problema. O que é um parâmetro, podemos defini-lo
dentro desses colchetes. Aqui, vamos
digitar o nome da string. Agora você pode ver que essa linha
vermelha desapareceu. Cada parâmetro que você
coloca em um método aqui está dentro
desses colchetes abertos, você pode ver esse método principal Agora, esta seção aqui, bem, tem um parâmetro
, sempre teve um
parâmetro. Novamente, quando definimos
um método aqui, podemos adicionar nossos próprios parâmetros. Eu adicionei o que é chamado um parâmetro e
é chamado de nome, é uma string de tipo. Agora, dentro desse método, estamos usando essa variável, esse parâmetro, quando
chamamos nosso método
a partir do método principal. Agora você pode ver que há
uma linha vermelha aqui. Quando passamos o mouse sobre
isso, você pode ver que não
há discussão Agora, argumento é
sinônimo de parâmetro. É
a mesma coisa. Não há nenhum parâmetro fornecido que corresponda ao nome do parâmetro
necessário. Basicamente, está dizendo que agora
esse método precisa de uma string. Não podemos mais chamá-lo
assim. O que fazemos é pegar
nossa variável de nome, que é o resultado
da entrada do usuário, e a colocamos nela. E agora você pode ver que estamos coletando as informações do
usuário. Estamos fornecendo as informações desse
usuário ao nosso novo método chamado
say, hello user. Então, estamos dando
a ele o nome do usuário. Em seguida, o código entra aqui. O nome agora é igual ao valor
que está sendo passado para ele. E esse é o nosso parâmetro. Agora estamos usando nosso parâmetro enviando-o para
a janela preta Em seguida, a execução do código
volta. E então estamos mantendo
a janela aberta novamente, só para que isso não seja confuso Podemos chamar isso do
que quisermos. Poderíamos dizer o nome do usuário. Poderíamos chamá-lo de sanduíche de presunto. Isso não importa. Você pode
ver a linha vermelha aqui, porque ela precisa ser a mesma. Mas você pode ver aqui, isso
não tem uma linha vermelha. E isso é porque,
na verdade, estamos definindo isso aqui. Mesmo que o valor
entre no método aqui, quando chegamos aqui, podemos chamá-lo do que
quisermos. Ele ainda terá esse valor, mas não precisa ser
o mesmo nome, assim. Não precisa ser assim com
o mesmo nome exato. Pode ser, mas
não precisa ser. Isso é algo que você
deve ter em mente. Quando o parâmetro é passado, o valor é passado, está redefinindo uma variável totalmente
nova aqui Mas com esse valor, espero que isso faça sentido quando
executamos o aplicativo. Agora estamos dizendo,
qual é o seu nome? Roberto. Agora você pode ver
que diz olá Roberto Podemos executar isso novamente. Podemos dizer olá Henry. É assim que os parâmetros funcionam
em uma visão muito simples. Uma última coisa, não precisamos
ter um parâmetro.
Podemos ter muito. Poderíamos ter outro de
um tipo diferente, como
idade, que é um número inteiro Agora eu quero perguntar
a idade do usuário. Qual a sua idade? Lembre-se de que a idade é um número inteiro
porque é um número Vou chamar isso de idade. Agora temos a
linha vermelha porque isso dá uma string e queremos
colocá-la em um número inteiro, que não vai funcionar, mas já abordamos isso antes Vamos usar,
queremos convertê-lo em um número inteiro
de 32 bits e depois colocar os parênteses Agora, convertemos a string do usuário em um número inteiro Estamos colocando isso em uma variável
inteira chamada idade. Agora temos nossa linha vermelha novamente, porque temos dois
parâmetros em nosso método. Agora, diga uma idade. Quando passamos o mouse sobre
essa linha vermelha, você pode ver que agora ela requer
uma string e um número inteiro Quando chamamos esse método, precisamos adicionar
essas informações aqui e podemos usar uma vírgula Agora está até perguntando, está até
nos dizendo o que precisamos. Idade, pegamos nossa
idade, colocamos aqui. Agora temos um método
com dois parâmetros. E estamos passando dois
parâmetros para ele. Não estamos fazendo
nada com isso agora. Vamos fazer algo com isso. Vamos dizer que idade
é idade agora quando
executamos o software. Vamos fazer isso.
Qual é o seu nome? Harry. Qual a sua idade? Tenho 67 anos. Olá Harry. Sua idade é 67. Novamente, podemos ter dez
parâmetros, se quisermos. Poderíamos ter diferentes tipos de
dados em B, todos os tipos diferentes de coisas. Novamente, se você quiser adicionar mais, é só outra e
como você as distribui. Novamente, você usa A aqui. É assim que os parâmetros geralmente
funcionam com
métodos em C. Sharp.
14. 2-3. Retornos de método: Vamos falar sobre como recuperar informações de um método. Para fazer isso,
usamos a palavra-chave return. Vamos analisar o retorno de
informações de um método. Temos um exemplo de
aplicativo aqui. Está pedindo o nome do usuário. Ele armazena o
nome do usuário em uma variável e depois diz
olá ao usuário. O que eu quero fazer agora é
criar um método cujo trabalho
é pedir o nome do usuário, obter o nome do usuário e
devolvê-lo para nós. Isso é o que queremos fazer.
Agora, para fazer isso, vamos
criar um novo método. A maneira mais
fácil é copiar essa, excluir tudo e dar a ela um nome exclusivo. Seu trabalho é
pedir o nome de um usuário. Nós sabemos como fazer isso.
Nós o temos aqui. Estamos solicitando
o nome do usuário e armazenando em
uma variável aqui. Quando falamos sobre
parâmetros antes, isso é como inserir
informações em um método. Nós os definimos aqui e
passamos informações do principal. No entanto,
recuperar informações do principal, é
isso que estamos
vendo agora, e isso é chamado
de palavra-chave return. Estamos retornando informações
de um método, então podemos usá-las aqui. Quando lançarmos nosso aplicativo, solicitaremos o nome
de um usuário. Pegamos o nome do usuário e o
colocamos na variável. Agora precisamos retirar o nome do
usuário daqui e depois
dizer olá para ele. No momento, não podemos
fazer isso porque ele não entende o que
essa variável significa, porque ela está definida
em nosso método. Então, precisamos tirar isso
daqui e defini-lo aqui. Para fazer isso,
configuramos o que é
chamado de tipo de dados de retorno por padrão. Aqui você pode ver que há um
no evento principal e outro aqui. É chamado de vazio. O vazio
é como um buraco negro É como o nada. Não é nada Mas
o que queremos fazer é retornar nossa variável de
string aqui, volta para fora do método. Substituímos nosso
vazio vazio por uma corda. Agora, configuramos um
tipo de dados de retorno aqui para esse método, uma string, e queremos
retornar essa variável aqui. O que fazemos,
pegamos nossa variável, usamos a palavra-chave return. Entramos em um espaço em branco, colocamos nossa variável e, em seguida,
todas as linhas com ponto e vírgula O que está acontecendo aqui? Estamos
pedindo o nome do usuário, colocando-o em uma variável
e, em seguida, retornando a
variável desse método Você pode ver que quando
retornamos a variável aqui, essa variável é do tipo de dados string que precisa corresponder
ao cabeçalho do nosso método, que é toda essa
linha aqui. Então, você pode ver que estamos
retornando uma string de tipo de dados, que é nossa variável aqui. Agora, de volta aqui, vamos
voltar ao nosso método principal. Estamos chamando isso,
mas
na verdade não estamos obtendo nenhuma
informação disso. Na verdade, já fizemos isso antes. Você pode ver a linha de leitura de
pontos do console. Esse é um método e,
na verdade, estamos obtendo
informações dele. E é exatamente
assim que fazemos isso. Podemos simplesmente fazer isso e
tudo funcionará novamente. Lembra antes quando eu disse que isso não precisa
ser o mesmo que isso, poderíamos apenas dizer o
nome, por exemplo. Você pode ver que
ainda funciona porque principal só sabe sobre
qualquer coisa definida no Maine. Peça o nome de um usuário, só conhece as coisas
definidas aqui, a menos que você passe um parâmetro ou
retorne algo. Vamos repassar isso mais
uma vez. Na verdade, vamos executar
o aplicativo. Então, podemos ver que estamos
executando o aplicativo. Qual é o seu nome? Bob.
E olá Bob. Muito fácil? Bem, parece fácil até que sim. Vamos ver o que
está acontecendo mais uma vez para que faça todo o sentido. Estamos executando o aplicativo, solicitando
o nome do usuário. Então, a execução do código acontece aqui, não
há nenhum parâmetro, então
continuamos. Qual é o seu nome? O usuário digita seu nome, aqui, estamos armazenando-o em uma variável
chamada nome do usuário. Estamos retornando essas informações
do método, que é então armazenada no nome. Esse é o resultado
desse método. Nome do usuário,
estamos retornando,
é o resultado
desse método agora que está armazenado nessa
variável chamada nome. Em seguida, estamos
apenas enviando o nome para a janela preta e
mantendo a janela preta aberta É assim que os retornos funcionam
com métodos em C Sharp, lembre-se de que os parâmetros
recebem informações e o retorno retorna
as informações.
15. 2-4. Sobrecarga de método: Agora vamos
dar uma olhada em algo chamado sobrecarga de
métodos O que isso significa? Vamos
dar uma olhada nesse exemplo. Aqui, estamos definindo
duas variáveis aqui, ambas do tipo de dados inteiro chamado número um
e número dois O que estamos fazendo é
chamar um método chamado ad, que criamos aqui. Ele usa dois parâmetros
inteiros
e está apenas somando
os números Ele está retornando o resultado, que é um número inteiro
aqui E então estamos enviando
o resultado para a tela. Muito simples. A resposta
deve ser 20 2022. Nós temos a resposta correta. O que eu quero dizer agora é se eu quiser somar
duas duplas? Vamos transformar esses
números inteiros em duplos. Agora eu tenho duas duplas aqui. Isso pode ser 6,4 e isso
pode ser 16,2, por exemplo. Você pode ver agora que temos
uma linha vermelha aqui embaixo. Porque nossos parâmetros
são números inteiros. Está esperando números inteiros aqui. Mas ainda queremos esse método, ainda
queremos poder
somar números inteiros. Acho que o que poderíamos
fazer é chamar um método
e, em seguida, talvez outro método chamado duplo, por exemplo. E então isso
precisaria de duas duplas. Então, o outro pegaria
dois números inteiros, por exemplo. É assim que podemos
contornar esse problema. Então, obviamente, isso
teria um tipo de retorno duplo. Você pode ver para onde isso está indo, mas e se quisermos somar, por exemplo, dois decimais
juntos ou dois números flutuantes juntos Então você pode ver que
teremos que ter um método para cada um deles. Isso é muito entediante e
pode realmente sobrecarregar nosso programa
. Mas o que podemos fazer é usar algo chamado sobrecarga de
métodos O que isso faz é que nos
permite ter um método, mas fornecer parâmetros
diferentes
, mas com o mesmo nome. Agora, um método só pode ter
o mesmo nome se os tipos de dados do parâmetro
ou o número de parâmetros, por exemplo, forem diferentes. Vamos voltar ao nosso exemplo
anterior, em que estávamos somando dois números inteiros
aqui O que podemos fazer então
é copiar esse método. Mantemos o mesmo
nome, por exemplo, mas aqui na
verdade estamos somando duas duplas em
vez de dois números inteiros Você pode ver que o que eu
tenho aqui agora são dois métodos com
exatamente o mesmo nome, exceto que este recebe dois
números inteiros e retorna um inteiro. E este pega duas
duplas e retorna uma dupla. Agora, quando
chamamos nosso método aqui, se eu abrir esses
parênteses aqui, agora temos essas
pequenas Não tínhamos isso
antes porque
tínhamos apenas um método com
um conjunto de parâmetros. E eu vou te mostrar isso agora. Se eu abrir os parênteses aqui, você verá que
não há seta Só temos uma definição
para o método add. Mas assim que eu adiciono o
segundo aqui, agora temos mais
opções disponíveis. Agora podemos somar dois números inteiros e também podemos
somar duas duplas Este é um exemplo de
sobrecarga de métodos em C Sharp. Ele apenas permite que você tenha opções
diferentes para um
método com o mesmo nome. Você pode ver que a C Sharp já tem métodos integrados que já tiram
proveito disso. Por exemplo, quando escrevemos
algo no console, você pode ver se eu faço exatamente
a mesma coisa, esse método já está
sobrecarregado 18 vezes Então, você pode ver que é
um princípio bastante popular na programação de lojas, então espero que isso tenha ajudado você, e este é um exemplo de sobrecarga de
métodos na loja C.
16. 3. Comentários e tags de resumo em XML: Agora eu quero falar sobre
algo muito importante. Se você quiser tornar
sua vida muito mais fácil ou levar a
programação mais a sério, então você precisa
usar comentários. Então, o que são comentários? Se você tem uma aplicação muito
complexa ou uma linha de código muito complexa, ela é muito longa e talvez você soubesse o
que significava na época. Mas se você voltar a
isso um ou dois anos depois, pode ter
esquecido totalmente o que
significava ou a loucura que
estava digitando na época É por isso que
os comentários são muito úteis. É um lembrete
principalmente para você, mas se você estiver trabalhando
com uma equipe de pessoas, ele também diz a elas o que
o código faz sem elas precisem ler e
entender toda a complexidade Podemos fazer comentários de
três maneiras em C Sharp. O primeiro é um
comentário de uma linha. Nós poderíamos fazer isso. Por exemplo, você pode ver que
quando eu deixo um
comentário, ele está verde. Agora, este comentário aqui, ele não é executado
pelo software quando você
produz seu software, como um EXC para Windows Ele não é compilado,
então você não perde espaço ou
megabytes com os comentários Eles são muito úteis. Novamente, se você tem
algo realmente complexo, ele apenas diz o que
a próxima linha faz. Assim, podemos colocar comentários em
praticamente qualquer linha que quisermos. Podemos colocá-los depois de uma linha. Novamente, eles não são atropelados, então não há uma
linha vermelha embaixo E isso realmente mostra
o que a próxima linha faz. Geralmente, as pessoas
colocam o comentário acima do código e
não ao lado dele, mas você pode colocá-lo
ao lado dele, se desejar. Vamos colocar alguns
comentários aqui. Você pode ver mais ou menos
como funciona aqui. Eu vou dizer que
sabemos que essa linha mantém
a janela preta aberta. Então, posso colocar um comentário que
diz que mantém a janela aberta. Este diz “
diga olá ao usuário”. Eu poderia colocar um comentário
que diz olá. Quando volto a
isso, um ano depois, esqueci
tudo sobre loja, porque isso sempre
acontece com idiomas. Você pode abrir isso e
saber instantaneamente o que cada uma
dessas linhas faz. Você não quer
enlouquecer com comentários. Você não quer que cada
linha tenha um comentário. Mas, definitivamente, se você não
entendeu alguma coisa, definitivamente
coloque um comentário
lá, pois ele o
lembrará novamente e você poderá voltar a
falar muito mais rápido Esse é um comentário de uma única linha. A próxima coisa que você pode fazer
é um comentário de várias linhas que é uma barra invertida
seguida por um Então, se eu pressionar Enter, você pode ver que o
Asterix está em todas as linhas até eu terminar com
mais uma barra. Agora, tudo o que eu digito aqui
está dentro do comentário. Isso é útil quando você quer
introduzir talvez um método
ou o que é chamado de classe. É com isso que estamos
trabalhando agora. Digamos que você esteja trabalhando em uma equipe de dez pessoas no
topo do arquivo. Você quer dizer quem fez isso, porque se houver um problema, eles podem dizer, ok, Bob escreveu toda essa
seção do software. Sabemos porque o
autor é Bob, então Bob, quando ele faz essa
parte do programa, ele pode dizer, eu fiz
isso, não me odeie. Então ele pode resumir
o que é. É um tocador de música, é ótimo, qualquer coisa
que ele queira lá. Então, realmente depende de você. Mas é assim que se faz
um comentário de várias linhas. Eles são úteis para
identificar quem escreveu o arquivo e talvez
aproximadamente o que ele faz. Dessa forma, as pessoas
não precisam ler todos os métodos e tentar
descobrir o que esse arquivo faz. Geralmente, comentários de várias linhas ficam no topo dos
arquivos, podem estar aqui, então a primeira coisa que
as pessoas podem ver ou pode ir além de
algo muito complicado, como um método ou
algo
parecido, geralmente é onde as pessoas usam um comentário de várias linhas Quando você quer escrever muitas linhas simples, por exemplo, o último comentário
sobre o qual quero falar é o que chamamos
de tag de resumo XML Agora, não é realmente como um
comentário como esse em si, mas fornece um feedback
importante. Ele fornece um feedback em
inglês simples sobre o que talvez a próxima
linha de código faça. Mas podemos usá-los
talvez para métodos ou
coisas assim. Se você tem um método
complicado, talvez tenha cerca de 100 linhas, ele faz todas essas coisas sofisticadas. Talvez o nome do método realmente
não faça justiça a ele. Pode dizer pergunte
pelo nome do usuário, mas faz muitas
outras coisas lá. Talvez ele retorne algo que possa ser um pouco complicado ou
tenha muitos parâmetros e você talvez não saiba necessariamente
o que eles significam. Podemos usar o que é chamado
de tag de resumo XML para expandir isso, onde eu chamo meu método. Aqui eu passo o mouse sobre
ele, você pode ver que realmente não
diz muito. Diz string. Programa, peça o nome do usuário. No entanto, se eu ouvir mais de
uma linha de leitura de pontos do console, veja todas essas
informações lá. Está dizendo que lê a
próxima linha de personagens, está me dizendo o que ela retorna. São muitas
informações diferentes. Estou pensando, oh, bem,
onde está isso na minha? Como faço para configurar isso? E isso é chamado de tag
de resumo XML. Acima do nosso método aqui, faça três barras para frente 12 E quando você faz o terceiro, ele cria esse
pequeno modelo agradável para nós. Está no formato XML. Aqui está a tag de resumo aberto, aqui está a tag de encerramento que representa a informação
aqui, que diz : lê a próxima linha de caracteres da entrada
padrão. Aqui eu
defino aproximadamente o que esse método faz. Se alguém passar
o mouse aqui, poderá ver rapidamente
o que ele faz sem precisar ler 100 linhas
de código. Por exemplo. Ele está fornecendo aos outros desenvolvedores informações sobre o que
esse método faz. Por exemplo, você quer dar uma coisa muito descritiva Agora, quando eu passo
o mouse sobre isso, oh, ok. Ele pede o nome de um usuário. Ah, sim, esqueci que construí um minerador
secreto de Bitcoin aqui. Então, por exemplo, você pode colocar
o que quiser aqui, mas é para seu benefício. Imagine que você
guardou seu software por dez anos. Você volta dez anos depois. Você esqueceu tudo. Mas agora você pode
simplesmente passar o
mouse aqui e, oh, isso, sim, claro,
eu esqueci disso Portanto, é bom para seu benefício, mas também é bom para outros desenvolvedores,
talvez da sua equipe. Por exemplo, aqui dentro
temos duas tags de retorno. E isso é aproximadamente
o que está sendo devolvido. Então, estamos retornando
o nome do usuário. Lembre-se de que você pode colocar uma pequena dica aqui quando obtemos o nome
do usuário,
estamos dizendo, oh, lembre-se de que é apenas o primeiro nome
dele Quando passamos o mouse aqui, podemos ver que ele retorna
o nome do usuário, mas estamos nos lembrando que é apenas o primeiro nome dele É por isso que essas tags de
resumo XML são úteis, porque quando você
passa o
mouse aqui em um instante, sabe exatamente o que ele
faz em inglês simples Então, eles são realmente úteis. E você pode ver que esse método
tem um parâmetro aqui. Quando eu faço a mesma coisa aqui, temos uma coisa extra aqui. Novamente, podemos usar nosso resumo. Diz olá, diga
olá para o usuário. O parâmetro define o que
nosso parâmetro faz, como as informações que
fornecemos a
ele . Será o primeiro nome do
usuário. Isso é dizer olá para nós. Quando eu tiver superado
isso, podemos ver aqui, dizer olá para o usuário. Quando abro o colchete aqui, ele está me dizendo o que
espera, ou seja , qual
é esse nome completo É o primeiro nome? Último nome? Apelido. Mas quando eu
olho aqui embaixo Oh, é o primeiro nome,
claro, Sim. Como estamos nos
lembrando, estamos dizendo ao usuário, quando chamamos nosso método, exatamente o que nosso método faz, o que ele espera como parâmetro e também o que ele retorna Então, eles são os
três tipos diferentes de comentários que você pode
usar em C sharp.
17. 4-1. Afirmações if e else: Vamos dar uma olhada em algumas condições
novas em C sharp. Vamos dar uma olhada
na declaração if e
também na declaração el. E L S E para L. O que é uma condição é algo que é
avaliado como verdadeiro ou falso. Dê uma olhada nisso.
Você é Bob? Seu nome é Bob? Bem, a resposta é sim
ou não. Você tem um? Ou você tem um cachorro ou não tem um cachorro. Você tem seis pés de altura? Ou eu sou ou não sou. Então, eles sempre têm
uma resposta sim ou não. A condição neste caso é um Bob, essa é a condição. Você poderia expandir essa condição. É Bob, você tem um cachorro? Em qual caso? Tudo
isso é a condição. Se seu nome é Bob, mas
você não tem um cachorro
, a resposta é não. Caso contrário, é sim se você
tiver os dois, por exemplo, porque há um fim
aqui, isso é uma condição. Essa é a nossa condição. Lidamos com isso todos os
dias, várias vezes. E podemos representá-los em C nítido usando o que é
chamado de declaração if. Vamos dar uma olhada.
Uma muito simples. Vamos criar
um pequeno software chamado Are you, Bob? O que ele faz, ele
pede o nome do usuário. Nós pegamos o nome do usuário. Se o nome do usuário for Bob, nós lhe daremos saudação
incrível porque
gostamos muito de Bob Se o nome deles não for Bob, então
vamos dar a eles talvez um Olá,
Roberto padrão ou algo parecido Dê uma olhada no formato
da declaração if. Começa com If,
essa é a palavra-chave, os parênteses abertos, assim
como fazemos em Por exemplo, abra parênteses
dentro dos parênteses. Aqui colocamos a condição. Nossa condição é,
bem, você é, Bob? Sabemos que a variável name contém tudo
o que o usuário inseriu, então vamos colocar o nome. Então, queremos o operador
de
igualdade representado
por dois sinais de igual. Quando você atribui
algo em C nítido, usamos um sinal de igual. Mas quando queremos comparar
algo, usamos dois. Estamos dizendo que se o
nome do usuário for igual ao Bob, então precisamos fazer
algo em C Sharp. A Sharp adora esses aparelhos ondulados. Quando temos uma cinta encaracolada
metodológica,
quando temos uma cinta encaracolada if
statement,
quando abrimos uma cinta encaracolada, sempre fechamos uma cinta encaracolada . Você pode ver esses aqui
coincidirem com esses aqui. É assim que a linguagem é. Esta é a nossa declaração if aqui. Este é o conteúdo
da nossa declaração if. Tudo entre
os colchetes encaracolados. Agora, como eu disse, se o nome do usuário for Bob, queremos dar a ele
uma saudação incrível Vamos tentar digitar em inglês. Sabemos que o nome deles é Bob. Podemos muito bem colocar Bob. Olá, Bob. Esses, aqueles que se chamam Bob, estão lhes dando
uma saudação incrível Olha. No entanto, se o nome
deles não for Bob, talvez seja Roberto ou Henry
, precisamos dar a eles
uma mensagem diferente Se executarmos este programa agora, você pode dizer,
qual é o seu nome? Vamos digitar Henry. Está nos dando um
padrão Hello Henry. Na verdade, está ignorando isso completamente porque
o nome não é Bob No entanto, se eu executar o aplicativo
agora, qual é o seu nome? Bem, meu nome é Bob. E lembre-se de C sharp sensível a
maiúsculas e minúsculas. Portanto, verificamos apenas a presença de uma farpa minúscula em
nossa declaração if,
portanto, certifique-se de que corresponda a
essa. Então clique em Responder. Agora temos nosso
incrível visual de saudação, mas temos um problema. Olha Também diz olá Bob. Então ele está recebendo duas saudações. E isso porque a condição da declaração
if, que é esta seção,
está sendo satisfeita. É avaliado como verdadeiro. Portanto, essa linha de
código está sendo executada. Quando a instrução if terminar, ainda
estamos executando essa parte Mas talvez queiramos reservar essa saudação para
Henry, por exemplo Portanto, apresentamos
o que é chamado de declaração L. E LSE, novamente, colchetes encaracolados. Esta seção é
reservada para Bob. Esta seção é reservada
para qualquer coisa que não seja Bob. Isso é avaliado como verdadeiro quando
o nome do usuário é Bob. É avaliado como falso
se for outra coisa. Caso contrário, todo
o resto entra aqui. Queremos dar a saudação
padrão
a qualquer pessoa além de Bob E é assim que a declaração
else funciona. Então, se isso for
avaliado como verdadeiro tudo aqui, se for avaliado
como falso tudo aqui, por exemplo, se eu
executar o programa, agora qual é o seu nome? Meu nome é Bob. Agora recebo
a saudação padrão, e esta seção é
completamente ignorada porque
meu nome é Bob Mas quando eu executo o programa, agora eu digito qualquer coisa, recebemos a saudação padrão porque essa parte é ignorada, ela cai na seção
else aqui Não pode existir sem
e, se não pudermos fazer
isso, isso não fará sentido. Caso contrário, sempre precisa de um
se para acompanhar. Quando tentarmos executá-lo,
haverá um erro. Você não pode ter outra coisa por si só. Sempre precisa de um
acompanhamento, se estiver acima dele. É uma visão
muito simplista de uma condição de exemplo, que é a condição if
em C.
Quero dar uma olhada em um exemplo
rápido para que você entenda
completamente como
essas condições funcionam Agora, quando você tem
uma declaração if, ela tem uma condição
e uma ação. Se isso for avaliado como verdadeiro, ele executa esta seção aqui Se for avaliado como falso, esta seção será executada aqui. Quando falamos sobre variáveis, tínhamos uma variável bolen As variáveis de Bolen são
avaliadas como verdadeiras ou falsas. O que podemos fazer é
usar parênteses. Os parênteses são opcionais, mas acho que melhoram a legibilidade. Agora estamos armazenando o resultado disso em uma variável
chamada é Bob. Então podemos colocar Bob,
aqui está o nome dado
pelo usuário Bob. E quando digo é, quero dizer, é igual ao operador de
igualdade, sim ou não, verdadeiro ou falso? Então, verdadeiro ou falso
será armazenado nessa variável
chamada é Bob. Se a declaração for então executada, ela dirá que é verdadeira
falsa. Se não for falso. Se eu executar o software aqui, eu digito Bob, ei
Bob, você é incrível. É exatamente a mesma coisa. Isso lhe dá mais clareza sobre o que está acontecendo, se
isso faz sentido. Eu não falei muito sobre
booleanos, mas basicamente estou dizendo: isso é igual
a verdadeiro ou falso E isso vai
ser verdadeiro ou falso,
porque é assim que você o
representa como uma booling E então, quando executarmos
a declaração if , Bob será
verdadeira ou falsa. E vai funcionar
da forma apropriada. Se não somos Bob, somos Henry. Então vai dizer,
ei, pessoa aleatória.
18. 4-2. Afirmações Else If: Agora vamos expandir nosso exemplo de condição
if em nosso último tutorial e falar
sobre a cláusula el if Aqui temos nossa
saudação padrão para Bob. Mas e se quiséssemos uma saudação
especial para Henry? Bob recebe sua própria mensagem personalizada. Henry pode ter
seu próprio personalizado, então todo mundo
recebe um padrão. Por exemplo, aqui apresentamos
a declaração else if. Vamos descer até aqui.
Isso é indicado pelo fato de que queremos mudar Bob, porque já
temos essa condição Essas condições realmente precisam ser únicas. Caso contrário, não fará sentido. Na verdade, será redundante. Agora estamos dizendo,
você é Bob ou Henry? Lembre-se, vamos fazer com que nossos
comentários façam sentido. Então, seu nome é Bob? Olá, Bob. Seu nome é Henry? Oh, olá Henry. Mas ele recebe mais pontos de
exclamação porque é o chamador. Então, se você não é Bob, você não é Henry, então você é
todo mundo na parte inferior. Então, vamos digitar
Henry, por exemplo. Agora vamos comprar o
Henry porque nosso nome é Henry. Muito simples. Depois de entender como
o se e o else funcionam, caso
contrário, o if é apenas outra coisa. Novamente, podemos até mesmo expandir isso e ter outro
nome aqui, talvez Scott ou
algo parecido. Você pode modificá-lo adequadamente
para o que quiser. É assim que a
declaração elif funciona. Novamente, você não precisa de
el, você não precisa de mais. Se eu ficar feliz com
isso, por exemplo, se eu digitar qualquer outra coisa, eles não
receberão nenhuma mensagem porque não mandamos
ele fazer nada Esse é o poder da instrução el if ao usar
a condição if. Agora vou te dar
um pequeno conselho. Agora, abordamos a declaração
if el if. Ou seja, quando você
tem uma condição, por exemplo, com apenas uma
linha de código abaixo Então, temos essa condição,
uma linha de código. Então essa condição,
uma linha de código. Quando temos uma linha de código
, essas chaves
aqui são opcionais O que isso faz ao
removê-los aumenta a legibilidade Isso causa menos inchaço
ao seu software. Isso é exatamente o
mesmo que tínhamos antes. No entanto, por exemplo, se
tivermos duas linhas de código ou mais em cada condição
, haverá um problema. E isso é porque ele
precisa desses colchetes encaracolados. Aqui você pode ver que há
uma pequena linha vermelha
e o erro não é
muito descritivo Isso porque ele está
tentando ler tudo isso em uma linha e vai
gerar um erro misterioso. Quando você tem uma linha de
código em cada condição
, as
chaves curvas são opcionais Mas você não pode fazer isso
com métodos, por exemplo. Somente coisas como if, else, if, else e algumas outras coisas que
ainda não discutimos. Mas essa é uma pequena
dica para
melhorar a
legibilidade do código no futuro
19. 4-3. Operadores de igualdade e desigualdade: Igualdade e desigualdade.
O que são essas? O que isso significa? Bem, essas são coisas que você pode ouvir agora. E, novamente, já abordamos um pouco a
igualdade quando eu estava
discutindo a declaração if. Mas igualdade é basicamente dizer que é algo
igual a outra coisa. E isso é representado
por dois sinais de igualdade aqui. Mas como dizemos desigualdade? Ok, e se o
nome não for Bob? Como representamos isso? O que podemos fazer lá é
usar o diferente de,
que é representado por
um ponto de exclamação
seguido por um sinal de igual que é representado por um ponto de exclamação
seguido por um Agora, toda
essa afirmação está praticamente invertida. Se o nome não for igual ao Bob, então bem, isso não vai
fazer sentido agora porque o nome
deles não é Bob. O que podemos fazer agora
é dizer, oi Bob. Se eu executar o software agora, qual é o seu nome, Bob? Nada vai
acontecer porque não
mandamos ele
fazer nada. Mas se eu executar o software
e colocar qualquer outra coisa, ele vai dizer,
ei, você não é Bob. Mas se eu simplesmente transformar
esse operador em um símbolo de igualdade ali mesmo, isso vai reverter
todo o significado de
toda a declaração Você pode ver agora que
não faz sentido porque, embora o nome seja Barb, ainda está
rodando isso Se você quiser dizer que algo é igual a alguma coisa,
dois sinais iguais. Se você quiser dizer que não
é igual a, então não precisamos de iguais, o
que é exclamação
e um sinal de igual que é exclamação
e
20. 4-4. Operadores de comparação: Ok, operadores de comparação. Eu tenho um
aplicativo muito simples aqui. Ele pede ao usuário um número 1 a 10. Ele pega a entrada do usuário, a
converte em um número inteiro e a coloca em uma
variável Essa é praticamente a
única coisa que isso faz. O que eu quero fazer é que, se o usuário digitar um número
menor que cinco, quero mandar uma mensagem para o usuário dizendo
que você escolheu um número baixo. Caso contrário, você escolheu
um número alto. Muito simples.
Para fazer isso, precisamos de uma condição que
vamos usar. A condição que vamos
dizer é o número
menor que cinco? Como representamos menos do que
é um colchete angular esquerdo, que se parece com
isso, e depois cinco Então, com a declaração,
usamos nossos colchetes. Então é isso que acontece quando nosso número é menor que cinco. Vamos dizer ao usuário, eu não sei, você
escolheu um número baixo. Algo parecido. No entanto, se o número não for
menor que cinco, então podemos usar L
praticamente invertendo isso. Você escolheu um número alto
se executarmos o aplicativo. Agora escolha um número de 1 a 10. Lembre-se de que
menos de cinco é baixo,
então vou fazer quatro Eu escolhi um número baixo
e pronto. Ótimo
software, não é? Então, se o número for cinco
ou maior, vamos fazer cinco. Deveria me dizer que eu
escolhi um número alto, eu escolhi um número alto. Da mesma forma, se eu colocar
1 milhão lá, vai dizer que
escolhi um número alto. Mas esse é um exemplo de um operador de comparação chamado operador menor que. Da mesma forma, poderíamos usar
o operador more than, que é representado por
um colchete angular reto Agora, isso não
vai fazer sentido. Teremos que reverter isso. Isso vai fazer
exatamente o mesmo. Mas você pode ver que está invertido. Se o número for maior que cinco
, escolhemos um número alto. Caso contrário, escolhemos
um número baixo, ele fará
exatamente a mesma coisa. Mas porque eu volto para isso, eu tenho que reverter esses dois. Só faz sentido que os outros dois sejam
maiores ou iguais e menores ou iguais a. Mais do que ou igual a é
representado dessa forma. Mais ou igual a, menor ou igual a, como você deve ter adivinhado, um colchete angular esquerdo
e um sinal de igual ao usar coisas como
não igual a, menor que, igual a, mais que igual a, Tente lembrar que o sinal de igual sempre fica no lado
direito, sempre em C Agora, se o usuário escolheu um número menor
ou igual a cinco
, aparentemente ele escolheu um número maior,
o que não é verdade. Nós os revertemos novamente. Está bem?
Menor ou igual a cinco, eles escolheram um número baixo, nós tínhamos menos de cinco antes. Se for qualquer coisa
até o número quatro, então é um número baixo. Se quisermos dizer
menos ou igual a isso, precisaríamos
fazer isso em vez disso. Como o número é
menor ou igual a quatro, então é um número baixo. Menor ou igual
a quatro é o mesmo que dizer menos de cinco. Novamente, podemos usar mais do que ou igual para reverter a lógica. Novamente, se o número for
maior que igual a cinco, novamente, podemos reverter
essas afirmações, obtemos exatamente a mesma
coisa que são
chamadas de operadores de comparação em C Sharp. Se colocarmos sete, você
escolheu um número alto.
21. 4-5. Operadores booleanos: Operadores de reserva. Parece um pouco complicado, mas garanto que não é. Um operador de booling é
basicamente uma forma de dizer e muito difícil de dizer O que vamos fazer
é criar uma amostra,
um aplicativo básico de loteria Estamos pedindo ao
usuário um número, 1-10. Se o usuário
digitar três ou sete
, ele ganhou,
ganhou na loteria Vamos dar uma olhada,
podemos implementar isso. Se você
disser a
frase em voz alta, está basicamente dizendo o que
você precisa fazer se o usuário escolher implicitamente um
número que é três, uma qualidade para três agora Ou é representado por dois tubos
verticais como este, 12. Eu não sei por quê.
É assim que as coisas são. O número é igual a três, o número é igual a
sete. É muito simples. Quando você diz em voz alta, está basicamente dizendo
o que você precisa escrever. Então eu quero dizer ao usuário que ele ganhou na loteria, escolheu o número da sorte, então vamos dar uma olhada nisso Escolha um número, 1-103, você ganhou, vamos provar que não é um
acaso, na caixa lateral número dois, nada acontece, é porque não
mandamos ele
fazer Esse é um exemplo muito básico
de uso do operador. Você pode usar mais de um. Você pode usar quatro,
se quiser. Então, se o usuário escolher 34 ou nove, por exemplo, funciona perfeitamente Agora você tem quatro números da sorte. Esse é o operador, o que é
chamado de operador Bolen. O outro operador Bolen
é o oposto. É o único e
isso é representado por, para uma pessoa, que
faz mais sentido. Pelo menos isso significa, mas
você precisa de dois deles. Com o operador final. O que podemos fazer é
dizer que se o número
não é igual a dois e não
é igual a sete, por exemplo, então eles ganharam. O que podemos fazer se o
número não for igual a dois, o número não for
igual a sete, porque 2,7 são números ruins. Se você escolher 2.7
, você perdeu tudo. Por exemplo,
desde que o número não seja dois e o número não seja
sete, então você tem um. É assim que você pode usar o
operador e ver a lógica reverter para
a que acabamos de usar
com o operador Or Agora usando não é igual a, mas a mesma lógica se aplica
quando executamos o aplicativo. Agora, desde que não
escolhamos dois ou sete com um, vamos escolher quatro. Você
pode ver com um. No entanto, se
escolhermos dois ou sete, ele não fará nada porque não mandamos
ele fazer nada. Esse é um exemplo muito básico do
uso de operadores de booling
como o R e o final. Novamente, com eles, você pode
expandi-lo e fazer quatro
números, se desejar. E o que podemos fazer
com operadores e operadores, também
podemos combiná-los. Vamos dar uma olhada em um exemplo rápido
de como podemos combinar. E vamos perguntar
o nome do usuário. Vamos
pedir o nome do usuário e inserir o nome do usuário. Agora vamos fingir que Bob só tem acesso ao
aplicativo de loteria que
estamos fazendo aqui Ele é o único com
autoridade para jogar na loteria. O que queremos fazer
é dizer que o nome do usuário é Bob, ele
tem o
número dois ou sete? E esse é um exemplo de como
podemos usar e juntos. Mas a questão é que a coisa
toda será avaliada
como verdadeira ou falsa. Esse é o ponto principal
da condição aqui. O nome é igual ao Bob e ele tem o
número dois ou sete? Então, vou colocar dois ou
sete entre parênteses aqui. Então, na verdade, é
muito mais legível e fará sentido E também será
calculado corretamente. Então, o nome do usuário é Bob? Sim Bob tem o
número dois ou sete? Sim Digamos que ele tenha
sete, então ele é um. Digamos que o
nome da pessoa seja Henry. Ok. O nome é Henry? O nome é Bob? Não, é Henry. Ok. Não, então
vai passar por aqui, então vamos testar a teoria Então, qual é o seu nome? Henry. Então vamos colocar um agora
vamos colocar o número da sorte. Acho que sete é um deles. Então nada acontece
porque não é Bob. Somente Bob tem permissão para potencialmente ganhar
na loteria aqui, vamos colocar Bob, vamos dar a ele um número da sorte e ele será um Exatamente desse jeito. Vamos fazer
Bob com um número azarado, que é definitivamente 44 Nada acontece. Você pode ver que é
assim que ele avalia toda
essa condição com um operador de booling
e também Também é bom usar parênteses
, para garantir que a calcule
corretamente e
, segundo, também melhore a
legibilidade
22. 4-6. EXERCÍCIO: crie um jogo de meditação.: Então, vamos fazer um
pequeno exercício agora e testar seus conhecimentos sobre algumas das coisas
que aprendemos até agora. O que vamos fazer é criar uma calculadora de amostra em C Sharp. No momento,
não há muita coisa acontecendo. Estamos apenas dizendo ao usuário bem-vindo à nossa calculadora de chamadas. E quando executamos o programa,
nada está acontecendo. Então, precisamos programar
essa habilidade, o
que o usuário vai fazer. Eles vão inserir
o primeiro número, que pode ser um decimal, e depois vão
inserir um operador mais menos multiplicação E então eles vão
inserir seu segundo número. Em seguida, ele executará
o cálculo e exibirá
na tela algumas
coisas a serem consideradas. Número um, o usuário
pode inserir decimais. Precisamos ter certeza de que convertemos nossos números em
duplas, por exemplo A próxima coisa é que precisamos
pegar o operador que
o usuário insere e
descobrir se é um sinal de mais,
menos, divisão ou multiplicação E então aja de acordo com isso de
forma adequada usando as condições. Vamos pedir ao usuário
o primeiro número. Nós
sabemos como fazer isso. Estamos pedindo ao usuário
o primeiro número. Para coletar essas informações, usamos a linha de leitura de pontos do console. Queremos colocar isso
em um duplo. Eu configurei uma variável chamada
first e que
armazenará o primeiro número, mas a
linha de leitura de pontos do console retorna uma string. Precisamos converter essa
string em uma dupla. Podemos usar a conversão para fazer isso, digitamos o período de conversão e
queremos abrir colchetes duplos Coloque a saída disso
dentro dos colchetes. E depois lembre-se de
fechar os colchetes. Agora capturamos o primeiro número do
usuário. A próxima coisa que queremos
fazer é incluir o operador do usuário, mas vamos primeiro inserir o segundo número do
usuário. Isso porque podemos
simplesmente copiar e colar isso. É muito mais fácil. Temos o
primeiro número do usuário e
o segundo número do usuário, fácil. Agora queremos o operador.
Vamos copiar isso. O operador será uma string porque a linha de leitura de pontos do console
já nos fornece uma string. Não precisamos converter
nada para que possamos remover isso. Vamos criar uma nova
variável chamada operador. Mas veja o que acontece
quando eu faço isso. Você vê que está destacado em azul. Está gerando um
erro. Por que isso? Isso porque operador
é uma palavra-chave em C nítido. Na verdade, já está sendo usado. Por exemplo, não podemos criar uma variável com o nome
de double, por exemplo. Ele faz exatamente a mesma coisa. Isso porque é
uma palavra reservada. Precisamos escolher um nome
que não seja operador, porque o operador já é
usado na linguagem C sharp. Vou chamá-lo apenas de OP. Você pode descobrir que
pensei em lhe contar
as informações agora. Agora queremos perguntar a
eles pela operadora. Talvez queiramos dizer a
eles o que eles podem fazer. Estamos dizendo que você
pode escolher mais,
menos, multiplicação
ou Estamos pegando o operador e armazenando-o em
uma variável chamada p. Agora temos todas as
informações do nosso usuário. Temos os números e
tudo o que precisamos. Agora, o que precisamos
fazer é descobrir qual operador eles estão usando e, em seguida, realizar
o cálculo. Como descobrimos o operador? Bem, podemos usar
declarações if para fazer isso. Nós dizemos se. Agora usamos
o operador de igualdade. É o operador. Como
o operador é uma string, usamos aspas duplas.
É uma vantagem? O código dentro disso, se colocarmos as chaves, se a operação for um sinal de mais, dizemos f mais Mas queremos colocar o resultado
disso em uma variável. Vamos definir uma variável
que armazena nosso resultado. Vou apenas
inicializá-lo para zero. Lembre-se de que o resultado do ponto e vírgula é igual ao resultado do
primeiro mais o segundo, porque estamos trabalhando
com No entanto, e se eles quiserem multiplicar dois números,
por exemplo
, precisaremos de um. Se o usuário inserir a
multiplicação, por exemplo
, isso não é verdade,
é avaliado como falso
, a execução do código
diminuirá Precisamos pegar isso
aqui em outro lugar. Se, se o usuário quiser fazer uma multiplicação,
verificamos isso E depois basta multiplicar
os números. É muito fácil, não é? Você pode ver para onde
isso está indo agora. Meu takeaway e divisão, a divisão aqui e
o takeaway É assim que realmente
detectamos o operador aqui. Em todos os casos, estamos fazendo o cálculo apropriado,
dependendo da condição
, e sempre colocando o resultado na variável de resultado aqui. A última coisa que queremos fazer é dizer ao usuário qual é
o resultado. Você pode ver aqui que um
estúdio visual está me oferecendo isso. Vou pegar, pressionar
Tab no teclado, e agora está escrito para mim. Agora eu quero dizer ao
usuário qual é o resultado. Resultado, algo parecido. Vamos executar o programa
e ver se ele funciona. Bem-vindo à nossa calculadora bacana. Qual é o seu primeiro número? Três, qual é a sua operadora? Você pode escolher mais, menos,
multiplicação ou divisão. Eu vou escolher a multiplicação. Qual é o seu segundo número? Porque sabemos que três
vezes quatro é 12. Eu não preciso pensar nisso. O resultado é 12. Bem, isso
funciona. Vamos tentar mais um. Vamos tentar 200/3 porque sabemos que três não se
encaixa perfeitamente em Então, podemos testar isso. Nosso resultado está, na verdade, nos
dando um decimal. Você pode ver que o
resultado é 66,6 6667. Portanto, temos um bom grau
de precisão aqui. Ao usar duplas
em vez de números inteiros, podemos lidar com
valores decimais e números
que não são números inteiros que não são números
inteiros Este é um
exemplo muito rápido de como criar uma calculadora preigual em C Sharp usando tudo o
que aprendemos até agora
23. 4-7. Afirmações no switch: Então, vou
apresentar algo agora chamado de instrução switch. É um novo tipo de declaração sobre a qual aprenderemos. E é muito semelhante
à instrução if e else if na
medida em que,
quando a instrução if é executada, ela avalia uma condição Se for verdade, ele
executará a ação abaixo. Se for falso, ele irá para
a próxima declaração Els if
e tentará novamente. Se isso for verdade, ele executará
essa ação, etc. O Switch é muito parecido com isso. É apenas outra forma de representar as
mesmas informações. O que vou fazer é reescrever isso como uma declaração switch para que eu possa mostrar exatamente como isso funciona Com uma declaração switch, usamos a palavra-chave switch. Ele tem uma entrada, que é o que o usuário
digita no programa. A propósito, antes de começarmos, mostrarei o que
esse aplicativo faz. Ele solicita que o usuário
insira um dia da semana
e, em seguida, fornece uma mensagem
personalizada sobre o dia em que ele inseriu. Se eu executar esse programa, insira um dia da semana. Eu digito segunda-feira, eu não gosto de segunda-feira. É um aplicativo muito simples. O que vou fazer é reescrever isso como uma instrução switch Ele pega a entrada do usuário, que colocamos em uma
variável chamada entrada. Assim como a maioria das
coisas em C Sharp, abrimos e fechamos chaves e colocamos todo o
código no meio Agora, uma instrução switch,
por exemplo, instrução
if, para verificar condições
diferentes. No entanto, com a
instrução switch, há casos. Eles representam, por exemplo, uma declaração L if. Nosso primeiro caso pode ser
a entrada na segunda-feira. Nós representamos isso assim. Em seguida, colocamos
o código no meio aqui. Em uma declaração switch. Essas três linhas
aqui são praticamente as mesmas que essas três
linhas aqui. É apenas formulado de forma diferente porque a entrada é uma string do tipo de
dados, nosso caso precisa ser uma string Se, por exemplo, a
entrada for um número, então isso precisa ser um
número. É assim que isso funciona. Uma instrução switch pode
ter um ou vários casos. Vamos fazer um
para cada um deles. Cada caso dentro de uma
instrução switch deve terminar com dois pontos e terminar
com a palavra-chave break E todas as linhas terminam
com ponto e vírgula. Cada cabeçalho de caso termina com dois pontos e termina com uma pausa É assim que acontece nas instruções
do switch. Chaves encaracoladas são opcionais. Você pode colocá-los, você
não precisa colocá-los. Você pode colocar o freio
dentro dos colchetes encaracolados. É muito flexível
na forma como funciona. Eu costumo deixá-los de fora , desde que toda a
sua lógica esteja aqui, e você pode ter várias
linhas de código dentro de uma pausa. E os dois pontos do cabeçalho,
você está bem aí. Esse é nosso primeiro caso, segunda-feira. Eu não gosto de segundas-feiras
novamente por terça, o próximo caso seria Novamente, não podemos ter
exatamente o mesmo caso porque
é redundante O próximo caso seria terça-feira, e adotamos essa linha
para terça, etc Você pode ver um padrão
emergindo aqui. A instrução switch tem
muitas condições dentro dela. Com o poder da edição, reescrevi todas essas instruções
e l if em uma instrução switch
e ela fará exatamente a mesma coisa.
Deixe-me demonstrar isso. Agora, vamos
eliminar temporariamente essa lógica. Agora vou executar o
aplicativo que eu digito na segunda-feira. Você pode ver que estou obtendo
exatamente o mesmo resultado. Essa instrução switch
aqui é exatamente a mesma que todas essas
declarações ifs e L if aqui Uma coisa que você nota
é a legibilidade. Ele lê muito melhor. Você pode ver que, na verdade,
é muito mais mínimo. Você pode ver claramente o que está
acontecendo e parece muito
mais organizado Essa é uma vantagem de
usar uma instrução switch. Uma desvantagem são os operadores de
booling. Por exemplo, se a entrada for segunda ou terça,
mas não quarta-feira, temos uma
coisa complicada aqui. Isso é muito difícil de
conseguir com as instruções
switch e
fica muito confuso rapidamente Nesse exemplo, eu
preferiria uma declaração F, nesse caso, para trabalhar com operadores bolen
complexos Outra vantagem de usar declarações
switch é que quando você
realmente tem muitas condições, aqui temos sete,
é bastante. Quando chegarmos a cinco ou mais, uma instrução switch
será, na verdade executada muito mais rápido
pelo sistema. Isso se deve apenas ao design. O que está acontecendo em
segundo plano. Quando você tem cinco casos, por exemplo, ou mais
, eu preferiria
uma instrução switch vez disso, só porque ela é
executada mais rapidamente. Se você representar sete casos em declarações if e else if
, o computador precisará
avaliar cada uma delas. Diz, oh,
esse, é esse? É esse? Mas isso não funciona em declarações
switch. Na verdade, ele é executado
de forma um pouco diferente. É mais eficiente
ao decidir entre as instruções switch
if e else if Então só depende de você. Você precisa dar
o exemplo e descobrir qual
funciona melhor para você. Uma coisa que vou mencionar
com as declarações switch, uma última coisa é o que acontece se nenhum
desses casos acontecer? E se houver um
oitavo dia mágico da semana, ou talvez o usuário tenha
escrito um desses incorretamente
, nenhum desses casos
realmente escrito um desses incorretamente
, nenhum desses casos Se fizéssemos esse exemplo com
if e, se tivéssemos um L final na parte inferior que
fosse algo como, seria algo assim
, informando ao
usuário que
ele inseriu
um dia inválido porque
talvez o tenha escrito errado informando ao
usuário que
ele inseriu um dia inválido porque .
Por exemplo. Como representamos isso
em uma declaração switch? Bem, usamos o que é chamado
de palavra-chave padrão. Se eu digitar default, sempre termine com uma pausa, assim como nos casos acima, então eu posso colocar o
mesmo código aqui. Se eu remover essa lógica
e testar o aplicativo e, em
seguida, escrever propositalmente um
dos dias incorretamente, você verá que está
informando ao usuário
que ele inseriu um dia da semana
inválido Portanto, isso é muito útil
quando você deseja que algum código executado sem que nenhum dos seus casos seja
realmente avaliado como verdadeiro. Então, é como um
catchall, por exemplo.
24. 4-8. Operadores condicionais: Vamos falar sobre
operadores condicionais em C Sharp. Os operadores condicionais
não estão limitados ao C Sharp. Na verdade, você pode
experimentá-los em C plus plus e outras linguagens, o que é um operador
condicional É uma maneira rápida de substituir
uma declaração F e uma L. Considere esse exemplo. Aqui estamos perguntando ao
usuário se ele gosta de café, pegando sua entrada e
armazenando-a em uma variável. Então, se eles digitarem
sim, por exemplo, estamos apenas configurando
uma variável chamada message e armazenando essa
string dentro dela. Eu sabia que podia
contar com você. Algo mais? Estamos dizendo que não somos mais amigos e estamos enviando
isso para a tela Se eu apenas executar o
software agora, você poderá
ver rapidamente como isso funciona. Sim, eu sabia que podia
contar com você. Muito simples. Mas você pode ver que temos uma declaração if aqui e
uma declaração L também. Ele ocupa quatro linhas de código com essa
lata extra de variável aqui. Há cinco linhas no total. Quando você desenvolve grandes
peças de software, às vezes é bom simplificar tudo
isso em uma única linha. Evita o inchaço e, novamente, pode melhorar a legibilidade Depende de como
posso representar isso em
uma linha de código? Como faço para minimizar isso? Bem, podemos usar o que é chamado
de operador condicional. O que vou
fazer é
reescrever toda essa seção aqui usando um novo conceito,
o operador condicional Agora, às vezes é chamado
de operador ternário, significa apenas
que
consiste em três partes E você verá por que é
chamado assim também. Vou apenas escrever isso como um operador condicional e depois
explicarei Como eu disse antes, ele
consiste em três partes. A primeira parte é a condição, separada
pela segunda parte com um ponto de
interrogação. Então, a segunda parte é se a condição for
avaliada como verdadeira A terceira parte é se a
condição for avaliada como falsa. Agora, essa linha de código aqui faz exatamente o
mesmo que tudo isso aqui. Deixe-me provar isso para você. Se fizermos isso, executaremos o programa. Você gosta de café? Sim, eu
sabia que podia contar com você. E vamos testar
a outra condição. Algo mais?
Não somos mais amigos. Você pode ver que está muito
mais simplificado agora. Colocamos tudo isso
em uma linha de código. Mas como isso funciona? O que acontece é que estamos armazenando o resultado disso em uma
variável chamada mensagem, semelhante ao que
estamos fazendo aqui. A primeira parte do operador
condicional é a condição é
a resposta do usuário Sim, estamos testando uma
string. Essa é a condição. A primeira parte do operador
condicional fica entre um
ponto de
interrogação e dois pontos Ou seja, se a condição for
avaliada como verdadeira. Se isso for verdade,
então esse segmento
do operador condicional é executado, então esta seção aqui, se você puder imaginar
essa pergunta, ou
seja, de outra pessoa, se for E essa é a condição, essa variável está apenas
tomando o resultado de toda
essa condição aqui,
um operador condicional É apenas uma maneira rápida de escrever uma declaração F e L
em uma linha de código. A legibilidade, sim, depende se você pode neutralizar operadores
condicionais Pode parecer um pouco confuso, mas quanto mais você pode usá-los, ele realmente condensa muito o
código Considere que, se você tiver
talvez 50 ou 100 deles, é bom simplificar em apenas uma linha de
código, por exemplo. Mas é assim que você
pode escrever operadores
condicionais de alavanca em C
25. 5. Arrays: Então, vou introduzir um novo tipo de objeto
em nosso aprendizado. E isso é chamado de
matriz. O que é uma matriz? Bem, em inglês simples, uma matriz é uma coleção
de algo. Por exemplo, digamos que
um de seus amigos tenha uma boa coleção
de videogames. Você pode dizer, oh, essa é uma boa variedade de
videogames que você tem. Significa apenas uma coleção de alguma coisa, muita coisa. Na programação,
é muito parecido. Vamos dar uma olhada nesse exemplo
muito básico aqui. O que eu tenho aqui são seis
variáveis do tipo inteiro. Integer é o tipo de dados. Estou apenas enviando o
primeiro para a tela. Muito simples. Digamos que, se emularmos um aplicativo de
loteria, o usuário escolhe seis números
e, em seguida, colocamos cada um de seus números em uma variável e todas as variáveis Mas e se o usuário
escolher 1.000 números? Então eu vou ter que
criar 1.000 variáveis. Vai ser muito entediante. Nosso aplicativo usará
mais memória, será
maior em tamanho de arquivo e também levará muito tempo para ser desenvolvido. Como podemos superar esse problema de ter todas essas variáveis com nomes exclusivos diferentes é usar o que é chamado de matriz. O que a matriz pode
fazer é agrupar todas essas informações
em apenas uma variável. Vamos dar uma olhada em como
podemos representar seis linhas de código aqui em apenas uma linha
simples usando matrizes Então, o que eu vou
fazer é
definir e inicializar
uma matriz aqui Queremos que todos os nossos itens dentro da matriz sejam números
inteiros, números Vamos usar o
tipo de dados int para nossa matriz aqui, depois vou usar colchetes abertos
e fechados Isso está dizendo ao sistema, ei, eu quero criar uma matriz. Vamos dar um nome
à matriz. Vamos chamá-lo de números. Declaramos a
matriz ali mesmo. E agora queremos
inicializar a matriz, o que significa que queremos
colocar alguns dados dentro dela E podemos fazer isso
na mesma linha. Para fazer isso,
vamos dizer não. Em seguida, vou colocar
o tipo de dados novamente, os colchetes novamente. Agora eu quero colocar valores
dentro dessa matriz. Eu uso coletes encaracolados abertos, coletes encaracolados
fechados e, em seguida, ponto
e vírgula Agora, dentro desses colchetes, vou colocar os
valores, para que eu possa colocar dois Quando coloco um próximo valor
, uso a e depois 12, e agora o próximo valor, 264.556,71 Agora, essa variável aqui chamada números é uma
matriz Esses são todos os
valores dentro dele. Agora, essa linha de código representa todas
essas seis linhas aqui. Agora não precisamos mais disso. Agora, como realmente
acessamos os números
dentro dessa matriz? Bem, pegamos o
nome da matriz, que é números, depois
usamos colchetes. Dentro dos colchetes, colocamos um índice para nossos valores Agora, quando falamos
sobre substrings antes, eu disse que o índice
geralmente está em C nítido Comece do zero, esse
é o slot zero do item. Este é o slot de item número 12345, embora tenhamos seis itens, esse é o índice cinco porque
é o índice zero, tenha isso em mente ao
trabalhar com matrizes e coleções e coisas
assim em Se eu quiser acessar esse
primeiro item, o número dois, basta colocar zero lá, porque está no índice zero. Se eu executar o programa, agora você pode ver que ele está gerando
o número dois aqui, que é nosso primeiro item Da mesma forma, se quisermos
acessar o número 12, basta colocar um e
posso executar o programa
e, em seguida, ele gera 12 Então, muito simples, é assim que você realmente acessa as
informações na matriz. Você usa os colchetes, mas coloca um
índice dentro deles. Se tentarmos acessar um
item fora de nossa matriz, por exemplo, índice 45, bem, teremos apenas seis
itens em nossa matriz. Se executarmos o programa, ele
gerará um erro. E, normalmente,
o erro diz
algo como se estivesse fora
dos limites da matriz Isso porque não
temos 46 itens em nossa matriz. Só está nos dizendo que a unidade não existe. Eu não
sei o que fazer. Outra coisa que você
pode querer fazer com uma matriz é definir a matriz. Mas ainda não sabemos
quais informações queremos colocar nela. Talvez queiramos
definir a matriz aqui e depois fazer
outras coisas legais. E mais tarde, mais adiante
no aplicativo, podemos finalmente saber quais números
queremos colocar aqui. Por exemplo, o que
fazemos nesse caso quando
definimos a matriz aqui, queremos colocar como
uma capacidade aqui. Diz aqui que, se realmente passarmos o
mouse sobre essa linha vermelha, criação da
matriz deve ter um tamanho ou identificador de
matriz Basicamente, está dizendo:
quantos itens você terá em sua matriz quando
quiser usá-la? Eu sei que vou ter seis
números porque é como um. Por exemplo, pode ser um aplicativo de loteria onde
há apenas seis números Nós o definimos com cinco aqui. Se o índice começar em zero, teremos 012345 Ao colocar um cinco aqui, estamos dizendo que vamos colocar seis números nessa matriz. Espero que isso faça sentido. Agora que definimos a matriz, agora ainda precisamos
inicializá-la porque
não temos valores aqui por padrão Se eu tentar acessar os
valores na matriz, mesmo que
não haja valores aqui, a saída será zero porque esse é o comportamento
padrão O que eu quero fazer agora é
colocar um valor na matriz. Então, vou colocar um valor
no primeiro slot que
é o índice zero. E eu vou colocar
o número 777 aqui. Agora, quando executo o
aplicativo, você pode ver, podemos ver o valor 777 e é assim
que você realmente
inicializa um item em sua matriz Da mesma forma, se eu for para a próxima linha e tentar
colocar um valor na próxima, o
Visual Studio está, na verdade prevendo o que
talvez queiramos fazer aqui Você vê esses
personagens cinzentos aqui. Basicamente, isso
significa que você pressiona Tab no teclado.
Então, vamos fazer isso. Ele vai inserir isso para nós, o que economiza muito
tempo na programação. Então podemos colocar isso
lá, por exemplo. Então, podemos acessar o índice um, que deve ser o
valor 456, que é Na verdade, isso é como
colocar valores em nossa matriz, porque definimos apenas uma matriz que pode
conter seis itens. Da mesma forma, se tentarmos
colocar um valor no slot 45, isso também gerará
um erro, porque estamos fora
dos limites A última coisa sobre a qual vou
falar sobre raios, a primeira coisa antes,
a última coisa, Rays, é um dos muitos
tipos de coleção que você pode usar em C Sharp. Há listas de matrizes,
listas, dicionários. Isso é algo para
você começar
a gerenciar muitos
dados, por exemplo. A última coisa que
vou abordar rapidamente é suas matrizes podem ter
praticamente qualquer tipo de dados Podemos ter uma matriz de
strings, por exemplo. Isso pode ser o nome das pessoas. Então, precisamos ter certeza de que,
ao
inicializá-lo, ele realmente
corresponda ao tipo de dados Vamos deletar isso agora. Podemos colocar alguns nomes aqui. Podemos colocar Henry. Podemos colocar nosso
amigo Bob, etc. Agora temos uma matriz de cordas. Ok, quando
acessamos nossa matriz, podemos fazer
exatamente como antes. E há o acesso Henry, que é o primeiro item lá. Quando executamos o aplicativo, você pode ver que ele gera Henry Lembre-se de que, ao definir uma matriz com um tipo de dados de
string, todos os valores
precisam ser strings. Da mesma forma, se você tiver
uma matriz de números inteiros, você tem números inteiros aqui
26. 6-1. While Loops: Agora, para algo
completamente diferente, vou apresentar o
loop em C Para introduzir o laço,
vou apresentar
o laço de arame Considere esse exemplo. Aqui eu tenho um contador de números. Assim que abrimos o software, ele diz ao usuário:
bem-vindo ao contador de números. Insira um número, 1-3 Vamos executar o aplicativo Quando eu insiro o número
três, por exemplo, ele conta para o
número, eu insiro 123. Se eu inserir o número dois
, ele contará até o número dois. Isso é representado
por essas séries de declarações if e else if. Se o usuário digitar dois, ele simplesmente exibirá 123123 Ele conta até o número
que o usuário insere. No entanto, considere se queremos
modificar esse aplicativo e solicitar ao usuário um número de 1 a
1 mil, por exemplo Agora, como
representaríamos isso com declarações
if para cada número, teríamos esse bloco inteiro. Se tivermos o número quatro, adicionaremos outra
afirmação else if aqui, coloque
o número quatro. Em seguida, adicione outra linha aqui
onde contamos até o número quatro. Mas se chegarmos a 1.000, isso
vai ser enorme. O tamanho do arquivo do nosso
software será enorme
, sua execução será muito lenta. Como resolvemos esse problema? Bem, podemos representar toda essa lógica aqui usando um loop. Vamos usar um loop temporal. Deixe-me escrever
o formato do loop y. Então você pode ver que, assim
como a declaração, ela é bem parecida. Considere a declaração if,
temos uma condição. Se a condição for
avaliada como verdadeira, essa linha de código será
executada uma vez Se a condição for falsa, ela vai para a próxima instrução if e verifica essa condição. Se isso for verdade, ele executa
esse bloco de código uma vez. No entanto, com um laço de arame, se essa condição for verdadeira, ele continuará repetindo
o conteúdo aqui Se eu colocar o console, a linha
certa é uma. Se isso for avaliado como verdadeiro, ele continuará
repetindo isso indefinidamente até que seja
avaliado É assim que um laço de arame
funciona em princípio. Vamos dar uma olhada em nosso
exemplo e como podemos modificar nosso aplicativo
para fazer tudo isso se for lógico aqui em um
único loop de fio. Vamos deletar tudo isso. O que eu quero fazer é esse laço de arame
continue girando, rodando,
fazendo um loop e produzindo
o número até o número que inserimos o número até o número Esse é o número do usuário
que ele vai inserir. E queremos que o
laço continue
girando até que esse
número seja Ok, como fazemos isso? Vou introduzir uma nova variável e
vou chamá-la de contadora. E eu vou
inicializá-lo em um. Qual contador será? Esse é o número que
continuará aumentando 123 até o
número que o usuário nos fornecer O que eu quero fazer é o
contador de saída para a tela. Toda vez que esse laço de arame faz um loop, eu quero emitir o
valor do contador Começa em um
e então eu quero incrementar o contador
em um cada vez que o que eu poderia fazer é igualar si mesmo mais um contador
com o valor de um, mas agora eu quero que ele se iguale
a si mesmo, que é um, e
então adicione um Agora, depois disso, o contador
será igual a dois. Se funcionar novamente, o contador
será igual a 34, etc. Agora, sempre que você adiciona
um a uma variável, pode fazer dessa maneira ou
dessa maneira Assim mesmo. Esse acréscimo adiciona um
ao valor atual. Essa é apenas uma
forma abreviada de digitar isso. É exatamente a mesma coisa. Não funciona
com dois, apenas um. Se você quiser
diminuí-lo em um, use negativo,
negativo e isso subtrairá um
de seu valor Mas só queremos adicionar um. Toda vez que esse laço de arame
faz um loop, ele emite um contador , adiciona um e depois
volta ao início, verifica a condição.
Se ainda for verdade, executará
essas duas linhas de código Novamente, é assim que
o laço de arame funciona. Vai continuar funcionando,
mas agora precisamos de uma condição A condição deve ser
avaliada como verdadeira
até chegar ao que
o usuário inseriu
e, em seguida, ela precisa escapar
do laço de arame e continuar
com o resto do software. Que condições podemos colocar
aqui para tornar isso realidade? Bem, queremos contar
até o número do usuário. Incluindo o número do usuário. O que queremos fazer é
dizer enquanto estamos no balcão. É menor que o número do usuário, então repita esse código. No entanto, queremos incluir também
o número do usuário. Quando terminar de contar
, será
menor ou igual a. Vamos executar esse aplicativo bem rápido para que possamos
dar uma olhada nisso. Agora, insira um número de
1 a 1 mil. Vamos digitar o número sete, por exemplo, e pressionar Enter. Você pode ver aqui que ele conta até sete
do número um. É basicamente assim que
um laço de arame funciona. Se executarmos o aplicativo
novamente e digitarmos 1.000, ele conta até 1.000 e depois pára
em 1.000. Você pode ver, sem muito código, podemos replicar todas essas instruções
if e else if Em um
circuito de fio muito simples como este,
só para deixar 100% claro,
o software é executado, ele pega o número do contador
do usuário que
é inicializado em um Agora é um, enquanto um é menor ou igual a qualquer número que
o usuário colocou aqui. Digamos que o usuário digitou 44, enquanto um é
menor ou igual a 44 Continue esse
contador de saída de
execução de código na tela,
que será um. E então aumente o
contador em um. Agora isso vai ser igual a dois. Agora, o contador é igual a dois. Sim, ainda é menor
ou igual a 44 novamente. Agora o contador é igual a três, ainda
é menor que 44 Continue com isso.
Uma vez que o contador é igual a 45, bem 45 não é
menor ou igual a O que acontece é que ele
sai daqui, pula até aqui e continua com o resto do programa É basicamente assim que o laço
de arame funciona em uma loja. Eu quero falar sobre
algo muito importante. Agora estamos introduzindo loops. Com laços de arame e
quaisquer outros laços sobre os quais
falaremos no futuro Existe um perigo real de os
loops se repetirem para sempre. São apenas ciclos infinitos. O que acontece quando você obtém
um loop infinito é
que ele lentamente consome a memória do seu sistema até que não
haja mais memória ou
algo transborde ou algo
catastrófico Esse é um perigo real aqui. Vamos dar uma olhada em
um exemplo muito pequeno. Lembre-se de que, com as declarações if, há uma condição aqui. Se isso for avaliado como verdadeiro, ele
executará esse código
aqui , que pode simplesmente
escrever verdadeiro aqui O que acontece é que isso
é sempre verdade, sempre será avaliado verdadeiro porque eu
escrevi verdadeiro lá, nada está mudando
isso neste código. Até mesmo o
Visual Studios avalia isso porque sabe que isso
vai continuar acontecendo para sempre. Esse é um exemplo muito básico. Obviamente, isso pode ser
alcançado usando variáveis que nunca atingem
o valor esperado. Por exemplo, isso
continuará sendo
executado para sempre se eu
executar o programa. Agora você pode ver que está
contando sem parar. E o que vai
acontecer é esse número vai ficar
muito grande para o contêiner, ou vamos ficar sem
memória em nosso sistema. Mas, essencialmente, esse loop nunca
terminará e algo fará com que
esse programa falhe. Então pode ser memória,
pode ser qualquer coisa. E geralmente é algo
muito inesperado. Portanto, este é um exemplo de onde um loop pode potencialmente se
repetir para sempre. Isso é bastante comum, e
é por isso que precisamos
testar o software para
garantir que isso não aconteça, mas agora estamos introduzindo loops Esse é um perigo real
que pode acontecer e é algo que você deve
estar ciente de seguir em frente.
27. 6-2. Faça enquanto os loops: Vou apresentar
uma variante do loop Wile
chamada loop Il Há uma
diferença muito sutil entre o loop Wile e o loop Il A diferença é
que em um loop Il, o código dentro do loop é executado pelo menos uma vez.
O que isso significa? Vamos considerar esse
exemplo de aplicativo aqui. Bem-vindo ao contador de números. Recebemos um número
do usuário, 1-1 mil. Então, a partir de um, produzimos
em incrementos de um, os números até
o valor do usuário Se o usuário digitar sete, ele conta até sete e depois continua com o
resto do programa. Podemos usar o que é
chamado de loop Wile para conseguir praticamente
a mesma coisa aqui Quando chegamos ao laço de arame, aqui temos uma condição. O código executa isso, isso, isso, então
chega a esse laço de arame Se essa condição for
falsa desde o início
, esse código
nunca será executado. Todo o loop de fio
será ignorado se essa condição for
falsa e o restante do software continuará funcionando
com um loop i. Agora, esse não é o caso, porque a condição
em um loop acontece uma vez. O loop já foi executado pelo menos
uma vez. Considere isso. Agora, isso faz exatamente
a
mesma coisa que a outra parte do código. O software é executado,
essa linha de código é executada. Assim, obtemos a entrada do usuário, inicializamos essa variável Agora que chegamos a essa
afirmação, bem, nada está
nos impedindo de entrar aqui. Isso é ex, isso
é executado isso. E então temos nossa condição. Essas duas linhas de
código já
foram executadas antes de
obtermos nossa condição. E a condição diz: o contador
é menor
ou igual ao número? Agora, se isso for falso
desde o início, eu poderia até digitar false aqui. Então essas duas linhas de código que eles já
executaram, eles já executaram. Mesmo que a condição seja
falsa, eles ainda funcionam. E depois continuamos com
o resto do software. Considere esse exemplo. Não importa
o que eu coloquei aqui. Agora você pode ver como saída
uma pelo menos uma vez. Isso porque essas duas linhas
de código já foram executadas. Mesmo que a
condição fosse falsa. Um loop wile é
útil quando você deseja que o código em seu loop seja
executado pelo menos uma vez Caso contrário, considere
usar um loop Wile. Mas ambos podem alcançar
praticamente o mesmo resultado. Mas essa é a
diferença entre o loop Wile e o Wile
28. 6-3. Para loops: Vou apresentar
um loop diferente agora chamado de quatro loops. Um circuito de quatro voltas é apenas outra
forma de alcançar um resultado. Ele tem vantagens e desvantagens,
dependendo da sua aplicação. Considere este exemplo aqui, onde pedimos ao usuário um número e ele
apenas conta
para esse
número usando um loop Wile e gera todos os números ao longo nosso caminho. Com um mínimo, quatro loops
são Você vê esse loop Y aqui, definimos uma variável
logo acima dela
e, em seguida, incrementamos
essa variável uma a cada vez que
esse loop inteiro itera Quando a condição é
falsa, ela se livra dela. Você pode ver aqui que
adicionamos algumas coisas extras
ao laço de arame para o laço de arame
alcance seu objetivo. Agora, um circuito de quatro voltas, ele tem um mecanismo embutido que inclui um
contador como este. Isso simplificará todo esse código em 14 instruções. Agora, o que tudo isso significa? Deixe-me explicar. Começamos um loop de quatro com a
palavra-chave four desse jeito. Em seguida, o cabeçalho está entre colchetes, assim como o laço de arame E então temos os
colchetes encaracolados. O cabeçalho de um loop de quatro, na
verdade, tem um
pouco mais de informação. O laço de arame aqui,
temos a condição, é a única coisa que
temos aqui. Mas o loop de quatro, na
verdade, requer a definição do contador e o incremento
do contador O cabeçalho exige
três coisas. Isso porque o
quatro loop gerencia nosso contador, pois ele precisa
saber sobre essas informações, mas também precisa
conhecer a condição. E é assim que entramos
e saímos do circuito quatro. Por exemplo, assim
como um loop contínuo, ele precisa
de três informações. Vou usar exatamente
os mesmos nomes aqui, talvez com o número
um depois Não consigo usar variáveis
com o mesmo nome. Vou copiar onde
inicializamos nosso contador aqui. Eu não posso ter o mesmo nome. Vou colocar o
número um depois disso. A próxima coisa que eu preciso
é a condição. Separamos esses três
itens usando ponto e vírgula. Então eu coloquei a condição novamente, não
posso ter o mesmo nome. Então, o último, eu
preciso do incremental, novamente, não posso ter o mesmo
nome do laço de arame acima Agora, isso é basicamente exatamente
a mesma coisa que acima, exceto esta linha aqui,
que vou colocar aqui. Agora, esse bloco aqui faz exatamente a mesma
coisa que tudo isso. Aqui você pode ver
a vantagem,
neste caso, de um laço de quatro
voltas sobre uma alça de arame. Isso porque ele monitora nossos contadores automaticamente
nos bastidores Toda vez que os quatro
loops são iterados, esse contador é
incrementado em um a cada vez Se quisermos, podemos
incrementá-lo em dois toda vez que contarmos é igual
a contador um mais E isso incrementará o
contador em dois a cada vez, por exemplo, poderíamos
incrementá-lo em oito a cada vez Na verdade, depende de nós o que queremos fazer com
o incremental Mas, normalmente, você verá as pessoas aumentarem em um
a cada vez Há alguns
casos em que você pode
querer diminuir o valor
em um a cada vez. Depende realmente de você,
esse é o nosso incremento. O terceiro item, o
item do meio, é nossa condição. Portanto, é exatamente o mesmo que
um laço de arame nesse caso. O primeiro item é onde
definimos nosso contador. Então, precisamos dizer, ei, estamos configurando uma nova variável e a inicializamos com uma Nesse caso, podemos
inicializá-lo para zero, se quisermos, mas precisamos inicializá-lo Não podemos deixá-lo em branco, nós o inicializamos com um Nesse caso, isso fará exatamente a
mesma coisa que esse trecho de código. Aqui, deixe-me
demonstrar isso. Agora, aqui está nosso loop. Vamos inserir
o número sete. Por que não? Você pode ver
que conta até sete. Agora vou remover completamente nosso loop
while e colocar nosso loop
dividido em quatro, muito menos linhas de código. Vou executar
o aplicativo, vou colocar o número sete,
e ele faz exatamente
a mesma
coisa que o laço de arame. É muito legal, não é?
29. 6-4. Para loops vs while loops: Você precisa se perguntar
a seguinte pergunta. Se um loop de quatro tem toda
essa simplificação, ele é embutido,
incremental Por que não usamos isso sempre? Por que se preocupar com um laço
de arame, por exemplo? Bem, geralmente, quatro
loops são usados quando sabemos quantas vezes
o loop será iterado Por exemplo, quando o
usuário insere esse número, estamos contando a partir de um, incrementando em um e escapando do loop quando
o contador é
menor que um Esta seção aqui
exibirá números de 1 a 10 toda vez que for
incrementada em E quando
finalmente não for mais menor ou igual a dez,
ela escapará. No entanto, com um
loop de arame, podemos fazer isso, mas os loops de arame são
melhores quando não
sabemos o número de
iterações de antemão Por exemplo, estou com fome? Vamos inicializar uma
variável de booling chamada estou com fome e defini-la como verdadeira
porque estou Agora, quando entramos no laço do fio, não precisamos saber quantas
vezes ele vai se enrolar. Não precisamos acompanhar um contador ou todas essas
coisas, na verdade não precisamos. A única condição que temos aqui, por exemplo, é estar com fome? Bem, sim, é verdade.
Ok, é verdade. Então, dentro do wow loop, podemos chamar um método
chamado comer comida E então podemos verificar
se estamos com fome novamente. E então podemos continuar rodando. Finalmente, uma vez que
comemos comida suficiente, eu não tenho mais fome, então eu posso escapar disso. Mas eu não sei quantas vezes esse loop vai se
repetir até que eu esteja cheio. Portanto, é uma incógnita. É por isso que
os circuitos de arame são bons para isso, porque
não sabemos quantas iterações
isso vai acontecer Mas descobrimos isso
dentro do próprio loop. É por isso que os laços de arame são bons. O número de
iterações é desconhecido e é por isso que quatro
loops são bons Quando realmente sabemos o
número de iterações, podemos simplificar isso muito
mais facilmente com quatro loops
30. 6-5. Para cada loops: Vou apresentar
um novo loop agora, chamado de
quatro cada loop. Agora, a vantagem de um loop de
quatro cada sobre, digamos, um loop de quatro, é que ele
melhora a legibilidade E funciona com coleções com
muito mais facilidade. Agora, o
que tudo isso significa? Bem, vamos dar uma olhada. Eu tenho um aplicativo de amostra aqui. Estou configurando uma matriz. É uma matriz de números inteiros e a matriz é chamada de números Estou inicializando a matriz com todos esses números aqui Todos esses números
estarão dentro dessa variável
chamada números. Agora estou usando um loop de quatro, que
percorrerá cada número
na matriz sucessivamente e depois os
enviará para a tela. Vamos executar o aplicativo aqui. Você pode ver aqui que o aplicativo contém cada um dos
números em nossa matriz. Estamos apenas
percorrendo nossa matriz e produzindo cada
número ao longo do caminho Usamos a propriedade de comprimento da matriz para configurar uma
condição para isso. O que vou fazer agora é
apresentar os quatro em cada loop. A primeira coisa que eu disse foi que os quatro ciclos de cada loop
oferecem legibilidade Vamos dar uma olhada nisso agora, ao configurar um
loop de quatro em cada, usamos a palavra-chave. Para cada um, temos
os parênteses, assim como uma declaração if normal Um
loop y de quatro declarações, por exemplo. Depois, temos os
conhecidos colchetes encaracolados. Vamos dar uma olhada na aparência
de quatro cada loop. Eu vou fazer exatamente
o mesmo que o loop de quatro. Então você pode vê-lo representado
como um loop de quatro em cada. No cabeçalho dos
quatro ciclos de cada, eu configuro uma variável, digo em números. Então, para cada iteração
dos quatro ciclos de cada, quero gerar
a variável num Agora, o que tudo isso significa? Bem, para começar, você pode ver a legibilidade é muito melhor Há muito menos código aqui. Parece muito mais arrumado, menor e tem menos inchaço Mas como isso funciona? O que
acontece aqui em quatro voltas? Você pode ver que
configuramos uma variável aqui. cada iteração, podemos usar essa variável aqui Isso é o mesmo em
um loop de quatro em cada. Para cada iteração, essa variável será igual ao
próximo valor em nossa matriz Na primeira vez que isso for executado
na primeira iteração, num será igual a um Na segunda vez que esse loop for repetido, um será igual a quatro Na terceira vez, nove. Por exemplo, em um loop de quatro, isso é igual ao índice Como estamos apenas
contando a partir de zero, estamos incrementando zero um e
terminando quando num é igual ou
maior que o comprimento dos
números na matriz No entanto, em um loop de quatro em cada, essa variável aqui
está, na verdade, igualando os valores na
matriz, não o índice O índice é 0123. Mas em um loop de quatro cada, Numb será igual ao
valor real, 14912, etc Estamos apenas enviando
isso para a tela. Veja aqui que estamos usando
um índice no loop quatro para acessar o número
por trás do índice 149 Mas em um loop de quatro, na verdade,
ele é definido como o valor
num é o valor. Estamos apenas enviando
o valor para a tela. Deixe-me provar isso para você
se eu executar o aplicativo. Agora você pode ver que está gerando todos os
números na matriz aqui A segunda coisa que eu disse foi que funciona
muito melhor com coleções. Agora usamos uma
matriz padrão como essa matriz de números inteiros, mas há muito
mais tipos
e coleções de matrizes em C
Sharp, por exemplo, como listas e várias coisas desse
tipo, pois cada
uma oferece uma melhor legibilidade
com elas e também oferece mais opções
para trabalhar com elas Essa é a vantagem
de um para cada loop. Você pode ver que é
muito mais legível. Não precisamos definir essa variável aqui e
acompanhar um contador. É muito simples
nesse aspecto. Ou seja, outro loop é nítido, e é o para cada loop.
31. 6-6. EXERCÍCIO: desenhe um cúbico: Vou testar
seus conhecimentos agora. Agora, abordamos alguns loops. E vamos desenhar um
cubo. O que isso significa? Bem, por exemplo, se o
usuário digitar o número cinco e pressionarmos Enter,
ele desenhará o cubo Você pode ver que há cinco Asterix
do outro lado e cinco abaixo. Se o usuário digitar seis
, serão seis para
frente e seis para baixo. Como podemos fazer isso? Vamos dar uma
olhada no código aqui. Agora, não está fazendo
muita coisa agora. Estamos pedindo
ao usuário que insira um número
e, em seguida,
armazenamos a resposta em uma variável chamada num. Não estamos fazendo nada. abordamos esse problema? Como desenhamos esses cubos? Bem, precisamos de um mecanismo para
continuar desenhando Asterixes
na tela até
chegarmos ao número do usuário Quando algo continua
fazendo alguma coisa, pensamos em um loop em nossa cabeça. Precisamos de algo para
continuar fazendo alguma coisa, precisamos de algo para continuar
girando em nossa cabeça Devemos pensar, ok,
precisamos de um loop aqui. Não tenho certeza de quantos loops
ou de que tipo de loop, mas sei que preciso de um loop, então esse é um bom começo Agora, quando falei sobre quatro
loops versus loops de arame, eu disse que um loop de quatro é bom quando você sabe quantas iterações
ele vai fazer Você pode usar um laço de arame, mas estou apenas dizendo que um
laço de quatro seria melhor. Nesse caso, sabemos quantas iterações porque
temos o número que
o usuário inseriu, que será o
tamanho do cubo Um quatro loop
seria um bom começo para não abordar esse problema Vamos começar a criar um loop de quatro usando a palavra-chave de quatro aqui. Agora, o formato dos quatro
loops. São necessárias três coisas. Precisamos inicializar
uma variável. Vou chamá-lo de y, vou
inicializá-lo em zero Agora precisamos da nossa condição. Quero que continue em
loop até que seja
menor do que o que
o usuário Então, eu só quero
incrementá-lo em um de cada vez. Agora eu quero imprimir um
Asterix na tela. Vamos deletar isso e
colocar um Asterix. Vamos executar nosso programa e
ver o que temos até agora. Vamos inserir o número cinco. Você pode ver que temos o
Asterix caindo. Temos cinco Asterix. Eles estão todos indo verticalmente. Estamos na metade do caminho
agora. Mas o que precisamos fazer é fazer com que as Astrixes também
atravessem Toda vez que esse loop de
quatro iterações se repete, ele está desenhando um Asterix e
indo para a próxima linha, desenhando um Asterix,
indo A cada iteração
, precisamos colocar um pouco. Asterix também está indo por
esse caminho. Toda vez que o loop é iterado, como podemos fazer com que algo continue fazendo alguma coisa?
Bem, isso é um loop. O que poderíamos fazer é colocar
um loop dentro de um loop. Vamos dar uma olhada nisso. Não podemos ter o mesmo nome de
variável duas vezes. Você pode ver que y é
usado por esse loop. Vamos precisar
renomear este. Vamos chamar isso de X sem
motivo real. Pode ser qualquer coisa. Pode ser cheeseburger se você
realmente quiser Agora temos dois loops. Temos o que é chamado
de loop aninhado. Um laço dentro de um laço. Toda vez que esse loop itera, ele está fazendo tudo
isso. Considere isso. Então, vamos executar o programa agora e ver com o que
estamos lidando. Eu insiro o número cinco e agora, uau, o que está acontecendo agora? Temos 25 estrelas caindo. Isso é um pouco errado, não é? Por que está fazendo
isso? Isso porque toda vez que esse loop é executado, ele executa esse loop. E toda vez que esse loop é executado, estamos na verdade escrevendo
o Asterix aqui, mas também uma nova linha E agora isso é um problema para nós. Não queremos escrever uma nova
linha toda vez que isso for executado. Caso contrário, obteremos
apenas Astrixes verticais. O que podemos fazer é introduzir um novo método chamado, certo. O que isso faz é escrever
tudo nessa string aqui, todas essas coisas aqui. Mas isso não coloca uma
nova linha depois. Isso o mantém na mesma linha. Essa é a diferença
entre a linha direita que escreve isso e
depois coloca uma nova linha. No entanto, a direita apenas escreve isso e não
coloca uma nova linha. Vamos dar uma olhada nisso. Agora vamos inserir o número cinco. Agora você pode ver,
oh, todos os Asterix estão atravessando o eixo X. Agora eles estão todos vendo
o que está acontecendo aqui. Bem, isso é porque não
estamos realmente escrevendo nenhuma linha agora. É basicamente
escrever de uma maneira. Preciso começar a colocar
essas novas linhas. Neste momento, temos 25 que
Asterix está atravessando. Eu quero uma nova linha
a cada cinco dessas. Agora sabemos que se o usuário
digitar o número cinco aqui, esse loop interno será
iterado cinco vezes Depois de concluir o quinto, o código terminará esse
loop e continuará executando o resto do código até que o primeiro loop comece
novamente. Aqui, preciso
inserir uma nova linha. Como faço para inserir uma nova linha? Há muitas maneiras, mas usando o conhecimento que já
conhecemos, podemos simplesmente fazer isso. Não estamos escrevendo nada. Mas depois adiciona essa linha
. Vamos executar isso. Agora vamos para o número seis, só para provar que não
é um acaso, na verdade
vai fazer crescer um cubo maior para um número
diferente Agora temos 123456
em 123456 para baixo. Nós praticamente fizemos isso. Vamos revisar
esse código bem rápido. Podemos pegar o número do usuário. Agora temos um loop aninhado. Na primeira vez que esse
loop itera, ele executa esse código aqui, que também é outro loop Agora ele entra aqui e envia um Asterix
para a tela Por exemplo, se o usuário
digitar o número cinco, vamos substituí-lo.
É mais legível. Vai rodar
isso cinco vezes. Agora temos cinco
Asterix na tela. Quando esse loop estiver concluído, agora o loop terminou. Agora vamos imprimir
uma nova linha na tela. Entramos em uma nova linha, vai ficar assim. Agora estamos iniciando nosso loop
pela segunda vez, o loop principal. Uma vez iniciado, ele executa esse loop
novamente cinco vezes. Agora vai
ficar assim. Quando o loop estiver concluído, ele imprime uma nova linha. Agora está assim, depois volta para o topo. É assim que funciona, para que você possa visualizar
o que está acontecendo aqui A resposta para o nosso problema. Se quisermos fazer um cubo
e desenhar Asterix está
descendo, então Mas se também quisermos que eles
desçam e cruzem, considere algo
como um loop aninhado É assim que podemos resolver esse problema usando
loops nítidos
32. 7-1. A declaração de break: Então, vou
apresentar um novo tipo de declaração chamada declaração
de interrupção. Agora, quando falamos
sobre as instruções switch aqui, abordamos brevemente
a declaração break, mas não com nenhum detalhe
significativo. Mas agora vou explicar
exatamente o que isso faz como funciona e como
pode realmente nos beneficiar. Pausa é fundamental. Ao usar uma instrução switch, o que acontece é que o usuário, por exemplo, insere
um dia da semana. Armazenamos a resposta
em uma variável. E então, se eles, por exemplo, entrarem na quarta-feira, essa
linha de código será executada aqui. Depois que essa linha de código é
executada,
essa instrução break escapa
dessa instrução switch e o fluxo de controle
do aplicativo continua O que quero dizer com fluxo de controle? Bem, quando lançamos
nosso software, o método principal é
executado automaticamente. E então a primeira linha de
código é executada, a segunda linha, e é sequencial, é
executada até o Esse é o fluxo de controle, é assim
que seu
aplicativo é executado. Mas o problema da instrução
switch é que quando o fluxo de controle atinge
uma palavra-chave break aqui, em vez de executar
a próxima linha, a próxima, a próxima, a próxima até o fim,
ele pressiona a palavra-chave break imediatamente pula tudo depois Esse é o poder
da instrução break quando usada em uma instrução switch. Vamos dar uma olhada em como
a instrução break pode ser usada em algo
como um loop de arame. Vamos dar uma
olhada em um exemplo simples que
estamos fazendo, solicitando que o usuário
insira um número. O que esse programa faz, o programa simples, estamos apenas contando até esse número. Se eu executar o programa aqui e o usuário
digitar o número oito, estamos apenas contando
até o número oito. Muito simples. Estamos usando
um loop Wile para fazer isso Temos uma condição aqui. Estamos dizendo que se nosso
contador for
menor ou igual à saída numérica do
usuário, o contador incrementará
o contador em um e
estamos apenas fazendo um loop É muito simples como funciona. Às vezes, ao criar um loop, como um loop de arame, por exemplo, ou até mesmo um loop de quatro, você
pode não ter uma condição. Nesse caso,
configuramos uma condição porque sabemos o que o
usuário vai inserir e estamos contando até isso. Mas, em alguns casos
, não temos uma condição. Não podemos ter uma condição. Talvez não saibamos qual é
o objetivo final e
podemos realmente
descobrir o objetivo final dentro de nossa alça de arame. Você sabe, algo pode ser
descoberto em uma data posterior. Por exemplo, se
baixarmos um arquivo
da Internet e
baixarmos o arquivo em partes por vez, talvez
não saibamos o tamanho
do arquivo que estamos baixando. Então, nesse caso, podemos
configurar um loop de arame e continuar loop para
sempre até que o arquivo
seja baixado Em casos como esse,
não temos uma condição. Então, o que podemos fazer aqui é estabelecer uma condição que
seja sempre verdadeira. O que isso vai fazer é repetir indefinidamente até, por exemplo, baixarmos todo
o arquivo e, em seguida,
podermos sair
do loop manualmente Isso
também pode ser bastante comum no
caso de não termos
uma condição e apenas termos esse laço
de arame ligado indefinidamente, o que podemos fazer é sair
desse laço de arame para evitar que
ele se enrole para sempre. Essa é uma boa maneira de
usar a palavra-chave break. Podemos usá-lo em declarações
switch, mas também podemos usá-lo quando temos uma condição
indefinida, que é sempre verdadeiro Por exemplo, vamos dar
uma olhada nesse exemplo. E o que vou
fazer reescrevê-lo usando uma palavra-chave
break em vez disso, e ele fará
exatamente a mesma coisa Digamos que não temos uma
condição para esse laço de arame. Vai se repetir indefinidamente. Precisamos de uma maneira de
sair daqui, para não ficarmos presos
em um ciclo infinito. O que vamos dizer
é que, se o contador em algum ponto for maior que
o número digitado pelo usuário, saia do loop. Você pode ver que, assim que eu
digitei a palavra-chave break,
essa palavra-chave wire
também foi destacada, e isso é o Visual
Studio nos ajudando Por exemplo, poderíamos ter um laço de arame dentro de
outro laço de arame. Dentro de quatro voltas, podemos ter voltas em cascata E pode ser bastante confuso
usar uma palavra-chave. Break O Visual Studio
está apenas dizendo, ok, você digitou a palavra-chave break, esse é o loop ao
qual ela está vinculada E esse é o loop do qual você
vai sair, assim como a instrução switch. Por exemplo, essa palavra-chave
break
evitará que esse loop
de arame se repita para sempre. Está literalmente dizendo, ok, essa condição é
avaliada como verdadeira, vamos
sair desse ciclo e continuar com o
resto do programa A palavra-chave do freio está controlando o fluxo de execução
do código Basicamente, está dizendo:
vamos sair
daqui e continuar com
o resto do programa. Isso é o que a
palavra-chave de freio faz essencialmente. Vamos executar o software e confirmar se ele faz exatamente
a mesma coisa. Vamos inserir o número
oito, por exemplo. Você pode ver que está contando
até o número oito. Usar a palavra-chave freio outra forma de atingir
a meta anterior, mas é comumente
usada, por exemplo, quando você realmente não
tem uma condição e quer
escapar de um loop Esse é o poder da declaração de
freio em C sharp.
33. 7-2. A declaração continue: A
declaração contínua, o que é? O que isso faz? Agora eu
expliquei a declaração de interrupção. E uma declaração de interrupção
, assim como uma atualização, interrompe completamente você completamente e continua com o
resto do programa As declarações de quebra podem
ser usadas em quatro loops. Enquanto loops, quatro loops cada, todos os tipos de
loops. Só para escapar do circuito, não
é um loop indefinido No entanto,
continuando a declaração, o que isso faz é simplesmente pular
uma iteração de um loop O que vou fazer é mostrar como
a declaração contínua
funciona em quatro ciclos. Considere esse exemplo. Aqui, estou pedindo
ao usuário que insira um número sobre o que
vou fazer, vou contar
até o número dez, mas vou pular qualquer
número que o usuário digitar Vamos dar uma
olhada nesse exemplo. Então, vou inserir
o número seis e você pode ver o resultado aqui. Estou contando de zero, vou até dez, mas estou pulando
o número do usuário O número seis. Vai
5-76 está sendo ignorado Estou usando quatro voltas
para fazer isso. Estou contando de 0 a 10, estou
usando uma variável chamada. Estou dizendo que se o contador
não for igual ao número do usuário, basta enviar o
contador para a janela. Um pouco de curiosidades para você, se você já ouviu falar da linguagem de programação
C. E mais, mais, já falamos
sobre os incrementos antes, que você adiciona um a uma
variável e coloca mais, mais Você pode ver agora que foi assim que surgiu o plus plus, a
linguagem de programação C plus, plus, é apenas
mais uma que sua antecessora Isso é muito legal, não é? Se você já
se perguntou sobre isso. De qualquer forma, como podemos fazer isso usando uma declaração
contínua? Vamos dar uma olhada nisso. Vou reescrever isso
usando uma declaração contínua. Vou dizer que se o contador atual for igual ao número do usuário,
continue. Isso vai fazer
exatamente a mesma coisa. Isso aqui,
deixe-me provar isso. Vamos inserir o número seis. Novamente, você pode ver
que ele realmente pulou o número seis.
Como isso funciona? Uma coisa que você notará ao digitar continuar ou
passar o mouse sobre ela, assim como a declaração do freio, é dizer a qual
loop
ela está Escrevemos para
continuar. Está dizendo, ok, estamos vinculados a
esses quatro ciclos aqui. Por exemplo, se o contador
atual for igual ao número do usuário, continue. O que
continua fazendo? Isso impede que o resto
do conteúdo dentro do
loop seja executado. Assim que for executado
esse continue aqui, ele voltará ao início
do circuito quatro e
continuará descendo. Esse código aqui nunca é executado. Mesmo que eu tenha muito código
aqui, tudo isso aqui, se essa instrução continue
for executada, tudo isso será ignorado e
o fluxo de controle voltará
ao início do loop. Continuamos descendo.
Novamente, está modificando o fluxo de execução da mesma
forma que a instrução break faz Mas a forma como a
instrução break sai completamente
do loop
e continua a instrução contínua
apenas impede que o resto da iteração atual
do loop seja executada E então ele
volta ao início e continua
rodando normalmente Essa é a diferença entre
a declaração contínua e a declaração de interrupção
que posso mostrar a você. Agora, se eu remover
essa
condição completamente, esses quatro loops
praticamente não farão nada. Porque esse código
aqui está inacessível. Até mesmo o Visual Studio
é avaliado, informando que isso
nunca
será executado porque não
temos uma condição aqui cada iteração
desse quatro ciclos, estamos apenas atingindo essa afirmação
contínua E vai
continuar voltando
ao início neste
pequeno loop aqui. Então esse é o poder
da
declaração contínua em C sharp.
34. 8-1. Manipulação de exceções (tente, pegue, finalmente): Agora eu quero falar sobre tratamento de erros ou tratamento de
exceções. Eles são sinônimos
no mundo do C sharp quando se lida
com exceções Esses são resultados
que você não espera Se você observar a exceção
no dicionário, é uma pessoa ou coisa
que foi excluída de uma declaração geral e, mais significativamente,
não segue uma regra. Dê uma olhada neste
exemplo aqui. Estamos
pedindo dois números ao usuário. Estamos colocando a entrada deles, que é uma string, em uma variável
inteira aqui E estamos usando o
método para int 32. Para atingir esse objetivo, estamos pegando uma string e
convertendo-a em um número inteiro A segunda coisa que estamos
fazendo aqui é dividir os dois números e colocá-los em uma
variável chamada resultado Agora, esse programa
é bastante instável. Alguns erros podem ocorrer se não tomarmos cuidado. Geralmente, erros podem ocorrer
quando lidamos com usuários porque eles fazem coisas
que simplesmente não esperamos. Às vezes, se eu executar
o aplicativo, insira seu primeiro número. Agora, e se o usuário
simplesmente digitar olá? E se eles lerem incorretamente e colocarem o endereço de e-mail Os usuários podem fazer qualquer coisa. E se eles acidentalmente clicarem Enter e não
colocarem nenhum número? Há muitas
coisas que um usuário pode fazer para potencialmente
quebrar seu software. Eles são chamados de coisas
inesperadas se eu digitar muitas
letras e pressionar Enter. Agora você pode ver aqui que temos essa pequena mensagem
de erro aqui. Diz exceção não tratada. Isso basicamente significa que, ok, ocorreu
um erro, ocorreu
uma exceção. E está sem tratamento, o que
significa que não estamos fazendo
nada a respeito O computador não pode fazer
nada sobre esse erro porque está tentando
convertê-lo em um número. Simplesmente não pode fazer isso. Ele
não sabe o que fazer. Portanto, precisamos dizer ao sistema como lidar com esse
tipo de erro. Se eu olhar este software aqui, esse erro acontece quando
pegamos a entrada do usuário tentamos
convertê-la em um número. Se eu passar o mouse sobre
esse método aqui, que estamos usando esse método, até 32, você pode ver
esse diálogo aparecer Isso nos diz o que
o método faz. Ele nos diz o que o método nos
devolve como retorno. Mas também há
essa informação
extra na parte
inferior que diz exceções. Agora, esses são os dois possíveis erros que podem ocorrer ao usar
esse método para 32. A primeira é a exceção de
formato. Esse é o erro que
acabamos de experimentar. Digitamos uma palavra, por exemplo
, e ela gera o que é
chamado de exceção de formato Isso porque o
formato não está correto. Está esperando um número, temos algumas letras,
o formato está errado. O outro erro é uma exceção de
estouro. Acho que é quando você insere um número muito
grande e ele não
pode caber fisicamente dentro do tipo de dados
que é um Agora, o número inteiro de 32 bits vai
para cerca de 2 bilhões. Se eu tentar colocar 5 trilhões, provavelmente
geraria aquele outro erro,
que é a exceção de estouro O que podemos fazer sobre isso é lidar com esses tipos de erros. Quando o computador diz, oh, você me deu uma palavra, eu queria um inteiro, não
consigo converter essas
palavras em um inteiro Podemos interceptar isso e dizer,
ok, os usuários
inseriram algumas palavras Agora eu vou
te dizer como lidar com isso, é
assim que você
lida com esse problema. O segundo erro que pode ocorrer
é ao dividir por zero, pegamos os dois
números do usuário Supondo que eles tenham inserido
dois números válidos, tentamos
dividi-los juntos. No entanto, se o segundo
número for zero, outro erro
ocorrerá. Se eu colocar zero, agora
temos outro erro. Agora está sem tratamento novamente
porque não estamos fazendo
nada a respeito E esse tipo de erro é uma exceção de
divisão por zero. A mensagem que estamos
tentando dividir por zero. O computador não pode fazer isso
fisicamente. Não sabe como
, matematicamente, não
pode dividir por zero Mas não estamos dizendo
a ele como contornar esse problema. Esse é o objetivo deste
tutorial. Agora vou mostrar como
podemos lidar com exceções Agora, esse assunto é bastante
aprofundado, mas vamos apenas
raspar a superfície O que usamos aqui é uma
palavra-chave chamada tri. É bem simples, seco,
como a maioria das palavras-chave. Temos nossos conhecidos colchetes
encaracolados. Terminamos uma cinta encaracolada aqui, o que Tri está fazendo é dizer: você
pode tentar fazer
algo por mim, por favor? Porque tenho a sensação de que um
erro vai ocorrer. Sabemos disso porque, quando
passamos o mouse sobre esse método, há dois
erros possíveis que podem ocorrer Como estamos solicitando
informações para o usuário, sabemos que há um sinal
de problema chegando. Basicamente, estamos dizendo,
por favor, tente isso. É assim que a
palavra-chave tri funciona. Estamos tentando algo. Agora, o que acontece se isso falhar? Uma tentativa será bem-sucedida e
o programa será executado normalmente, ou poderá ocorrer um erro. Essa parte é a palavra-chave catch. Novamente, colchetes encaracolados, como
antes. Agora, uma tentativa não pode
existir sem uma pegadinha. Se eu remover a palavra-chave
catch aqui
, obteremos uma linha vermelha. Se eu passar o mouse sobre
isso, diz captura esperada Ou, finalmente, vamos colocar isso de volta. A linha vermelha desapareceu. Está feliz que nesta seção de
captura aqui, esse código será executado se ocorrer
um erro aqui. Isso está dizendo ao sistema
como lidar com esse erro. Digamos que ocorreu um
erro. Vamos dizer ao usuário que ocorreu um
erro. Muito genérico. Acho que
se eu visse esse erro, ficaria irritado como usuário porque
não tenho ideia do que isso significa É muito genérico, mas
podemos expandir isso mais tarde. Vamos ver se funciona. Digite seu primeiro número, vamos colocar algumas palavras ou letras. Agora você pode ver que
temos um erro genérico. Ocorreu um erro agora. Nosso software não travou,
então isso é bom. Mas, na verdade, não está
fornecendo tantas informações. Acabamos de receber essa mensagem
genérica. Não sabemos por que ocorreu, não
sabemos o que deu errado. Não é muito útil para nós, mas pelo menos nosso
software não travou Então isso é um bom sinal. Agora vamos dar uma
olhada em como podemos dar um feedback melhor
ao usuário. Não queremos dizer a
eles que
ocorreu um erro porque não são informações
realmente úteis. O usuário não pode então
voltar e descobrir
o que fez de errado. O que podemos fazer aqui
ao lado de catch é abrir e fechar
parênteses, digitar
a exceção e depois dar um nome a ela Isso pode ser qualquer coisa
, pode ser EX, você pode chamá-lo do que quiser. Basicamente, é uma
variável que estamos
configurando . O tipo de dados é
do tipo exceção. Assim como temos
um tipo de dados int, esse é uma exceção. Agora, abordaremos o que é
chamado de aula mais tarde, mas não se
preocupe com isso por enquanto. Mas agora definimos
essa variável chamada E, que é uma exceção de tipo de dados. Podemos usar isso para obter algumas
informações sobre nosso erro. O que vou fazer aqui é que, quando juntamos
cordas, usamos um sinal de mais aqui Vou dizer que a mensagem de mensagem é uma propriedade de string dessa variável de
exceção aqui Ela
nos dará um feedback A mensagem de erro que explica o
motivo da exceção. Agora, se eu executar o aplicativo agora e inserir o primeiro número, que é um monte de letras, agora temos um pouco mais de
informação, ocorreu um erro. A string de entrada não estava
no formato crack. Agora, quando o usuário lê isso, ele pode pensar, oh, ok, sim, eu li a pergunta errado, pensei que estava pedindo meu endereço de e-mail ou
algo parecido. Então, agora estamos fornecendo informações
úteis para o usuário. Agora, e se
quisermos personalizar? O que vai acontecer? do tipo de erro ocorrido. Agora, lembre-se de que há alguns problemas com
esse aplicativo. Algumas coisas
que podem ocorrer. Número um, o usuário pode inserir algumas letras e não pode
convertê-las em um número inteiro Já analisamos isso. A outra é que
tentamos dividir por zero. Mas o que está acontecendo
aqui é que estamos apenas fazendo essa
linha de código. O que quer que aconteça aqui, o
erro está acontecendo. Como podemos personalizar isso? Talvez diga ao usuário que ele
fez algo errado. Se eles acidentalmente
digitarem algumas letras, talvez façam outra coisa. Se dividirmos por zero, o que podemos fazer aqui é capturar diferentes
tipos de exceções. Se eu copiar e colar isso, vou colocá-lo aqui duas vezes e explicarei o porquê em breve. A primeira exceção aqui que pode acontecer é
a exceção de formato. O que posso fazer aqui é capturar a
exceção de formato aqui. O que acontecerá aqui é que, se ocorrer
uma exceção de formato, qualquer erro relacionado à formatação, podemos dizer ao
usuário, não sei Poderíamos dar a eles uma mensagem
realmente sarcástica. Poderíamos dizer: aprenda
a ler corretamente porque eles descaradamente
não leram a pergunta Que consistia em inserir
um número e
depois inserir o
endereço de e-mail, por exemplo. O outro foi
dividido por zero, ok? Então, divida por zero, exceção e a mensagem que eu
gostaria de dar ao usuário,
ei, amigo, você não pode
dividir por zero O que você está fazendo então, se
não é um erro
possível e não é um erro possível, então esse é um erro genérico. Quando tínhamos essa
declaração if, tínhamos e,
finalmente, tínhamos
outra no final, semelhante à
declaração switch. Tivemos o caso. Então, no final, tivemos a inadimplência. Isso é o que
pretendemos fazer aqui. Então, se nenhum desses
erros ocorreu, sempre
temos nossa pequena rede de
segurança na parte inferior que apenas emite uma mensagem
aqui no mundo real, você provavelmente não terá
apenas uma mensagem aqui Você provavelmente faria com
que o sistema registrasse esses erros de forma diferente e
esses erros de forma diferente. Mas isso é só um exemplo. Então você pode ver agora
que se eu executo o aplicativo, eu coloquei uma palavra, agora ele está me
dizendo para aprender a ler corretamente.
Charmoso, não é? Agora, se eu inserir dois números, tento dividir por zero. Ei Bird, você não pode
dividir por zero. Agora você pode ver que são duas coisas diferentes,
dependendo do erro que ocorreu. A última coisa sobre a qual quero
falar é a palavra-chave finally. Agora, a palavra-chave final
vem com uma palavra-chave tri. É opcional, você
não precisa usar um, mas pode ser bastante útil. Vamos dar uma
olhada em como isso funciona. Finalmente, iremos atrás
ou depois de todas as
capturas após a tentativa Se ocorrer um erro, todo o código desse
bloco final será executado, mesmo que ocorra um erro. Se não ocorrer um erro
, isso
também será executado. Talvez seja muito útil se você trabalha com um banco de dados ou com o que é
chamado de threads e pode fechar
conexões ou finalizar qualquer coisa que
realmente sirva Mas em nosso pequeno exemplo aqui, podemos agradecer ao usuário
por usar o programa. Por exemplo, estou agradecendo ao
usuário por usar o programa. Vamos dar uma
olhada nisso bem rápido. Se eu usar o software,
insira algo inválido, estamos pedindo ao usuário que
aprenda a ler corretamente e, em
seguida, agradecemos
por usar nosso programa Isso é muito
sarcástico, não é? Agora, vamos inserir
alguns números válidos. Agora obtemos um resultado real. Aqui você pode ver que o bloco final
ainda está sendo executado. Obrigado por usar nosso programa. Você pode ver que finalmente está sendo executado , independentemente de um
erro ter ocorrido ou não. Como eu disse, é opcional,
você não precisa disso, mas pode ser bastante
útil, ou seja, como capturar e lidar com exceções ao
trabalhar com C sharp
35. 8-2. Arrays 2D, 3D e multidimensionais: Quero apresentar
o conceito de matrizes
bidimensionais em C Sharp O que vimos até agora é uma matriz
unidimensional padrão. Por padrão, uma matriz na loja
é considerada uma dimensão. No entanto, e se quisermos
simular talvez um
tabuleiro de xadrez, por exemplo, onde temos oito
quadrados
atravessando , mas oito
quadrados também Então, podemos nos referir a esses
quadrados no jogo de xadrez, como um sistema de grade com x
atravessando e y subindo. Podemos simular
isso usando o que é
chamado de matriz bidimensional na loja Vamos ver esse exemplo aqui. Acabamos de definir alguns
números aqui e os estamos armazenando em uma matriz de
números inteiros chamada Numb E estamos apenas enviando o primeiro número em nossa
matriz para a tela Se eu executar o aplicativo, o primeiro número
na matriz será um, que é correto porque
esse é o primeiro número. Vou mostrar um exemplo
de uma matriz bidimensional. Agora, esta é nossa matriz
unidimensional. Vou apenas
remover alguns números. O exemplo não é prolixo. Para transformar essa
matriz unidimensional
aqui em uma matriz bidimensional, eu uso uma vírgula dentro desses
colchetes Agora, isso é dizer a
C sharp,
ei, eu quero criar uma matriz
bidimensional agora. É assim que
visualizamos nossa matriz. Parece algo assim. Mas o que eu quero fazer é criar uma matriz de dois D que
ficará assim. Devido à natureza
das duas dimensões, você tem uma dimensão
atravessando e outra descendo. E então ele se preenche
como um papel milimetrado, um tabuleiro de xadrez,
algo parecido Isso é o que
queremos emular aqui. Agora que coloquei vírgulas aqui, obtemos imediatamente uma linha vermelha porque C sharp sabe que estamos
criando uma matriz de dois D. Mas esse formato está incorreto. O formato para uma
matriz de dois D se parece com isso. Os colchetes ondulados externos aqui são o recipiente
para tudo Então, dentro de cada conjunto de
chaves encaracoladas está cada linha aqui. Se eu copiar isso e colocar
aquilo lá, copie aquilo. Coloque isso aí.
E copie isso. E coloque isso aí.
Agora, essa inicialização aqui das duas matrizes se parece
muito com isso Isso é o mesmo que isso. É assim que você deve
visualizar isso. Agora, como realmente
acessamos esses números? Novamente, esse formato está errado. Se passarmos o mouse sobre ele, podemos ver aqui um
número errado de índices Isso porque
agora está esperando dois. Como criamos
uma matriz de duas aqui, o que podemos usar é
apenas o sistema de vírgulas, por exemplo, 00 Agora, isso realmente produzirá o primeiro número
no primeiro bloco. Aqui está o primeiro bloco, aqui está o segundo bloco. Aqui está o terceiro bloco. Novamente, todos os índices
começam em zero. Este é o primeiro representado pelo primeiro
número aqui, zero. O segundo número
aqui, é o número do
item dentro do primeiro bloco, que é o primeiro
lá, que deveria ser um. Isso deve gerar o
número um
aqui se executarmos o aplicativo
lá, número um Se alterarmos o segundo
dígito, por exemplo, dois,
depois 012, ele deve gerar número três, como
você pode ver Se aumentarmos isso para dois, então deve estar aqui, porque é dois para
frente e dois para baixo, devemos obter o número nove. Lá vamos nós.
É assim que se acessa informações de uma matriz de dois
D em C nítido. Agora você pode estar fazendo a
pergunta: que tal três? Que tal quatro matrizes? Nós consideramos isso dois. Agora, esse exemplo vai
ficar muito louco. Isso é minimizá-lo. Agora, isso ficará assim. Que tal uma matriz de três? Bem, sim, muito simples. Vamos pegar cada um deles e substituir cada número
por um conjunto extra. Agora, se passarmos o mouse aqui, número
errado de índices é
esperado três, vamos inserir um terceiro Agora você pode ver que o sistema de
coordenadas está em três dimensões Se eu executar o programa agora o primeiro número na
matriz será um, o que é. Este é o primeiro item. Então você pode ver que esse é o tipo
de conceito de duas matrizes. Três matrizes. E você sabe, isso pode continuar a partir daí. E você pode fazer a
pergunta, bem, quantas dimensões
podemos ir? Bem, a resposta 32, se
você está se perguntando. Portanto, podemos ter até 32
dimensões em uma matriz na loja.
36. 8-3. EXERCÍCIO: xadrez: encontre o jogo da rainha: Eu vou fazer um pequeno
desafio agora. Vou testar
seus conhecimentos sobre matrizes
bidimensionais
e também sobre resolução de problemas Considere este modelo aqui, ele emula um tabuleiro de xadrez Se você está familiarizado com
o xadrez, talvez já tenha
descoberto isso Se você não tiver, não
se preocupe com isso. Vamos criar um
software para encontrar
todas as rainhas, que é representado por
um Q neste tabuleiro de xadrez Agora, é assim que o tabuleiro de
xadrez se parece. Temos um castelo, uma torre, rainha bispo e
um
rei, todos os peões, alguns quadrados vazios
representados por zero e as
peças dos outros jogadores Se você não está
familiarizado com o xadrez, o que queremos fazer
é encontrar o taco. Essa é uma matriz de caracteres
representada por Shah. Em um caractere, todos eles estão entre aspas
simples e você
só pode ter uma letra dentro,
caso contrário, ocorrerá um erro O que queremos fazer
é encontrar as dicas
nessa matriz bidimensional e depois
enviá-las para a janela Então, como fazemos isso?
Como encontramos algo? Aqui estão nossas duas matrizes D. Como escolhemos essas rainhas? Bem, o que queremos fazer é testar cada um. Isso é uma sugestão, isso é um que, não, etc., etc Na sua cabeça, você
deveria estar pensando, ok, um loop. Precisamos de um loop. Mas como há
mais de uma dimensão, precisamos verificar a travessia. Também precisamos verificar, descer, verificar tudo isso. Desça um, verifique
tudo isso. Um, confira, tudo isso. Na sua cabeça, você deveria
estar pensando, ok, precisamos de um loop e
precisamos de dois deles. Já sabemos quantas
iterações precisamos, porque temos oito
cruzando e oito descendo. Você deve pensar,
ok, 24 voltas. Quatro, porque
sabemos o número de iterações e um loop, porque temos que verificar
algo repetidamente, vamos fazer 24 loops O primeiro loop que vou
fazer é o loop y, que se moverá para baixo.
Vamos começar com isso. Vamos começar com zero, porque todos os índices
começam em zero Isso é um pouco 00
lá, y é menos. Agora, queremos obter o comprimento
dessa dimensão aqui. Como fazemos isso?
Tomamos o nome de nossas duas matrizes aqui, ponto final. E então queremos usar
o método get length. Quando abrimos
parênteses sobre isso, ele me pede uma
dimensão, bem, essa é a primeira dimensão, vou colocar zero Isso obtém a primeira
dimensão e
depois o ponto e vírgula e
aumenta em um a cada vez Esse é o nosso primeiro loop. Agora estamos voltando para baixo. Também precisamos cruzar. Vamos precisar de
outro loop dentro do nosso loop que
representará o eixo x aqui. Queremos colocar a segunda
dimensão lá, que é representada por um. Agora, isso está atravessando a
primeira dimensão aqui embaixo. Isso está atravessando a
segunda dimensão aqui. Agora temos nossos
dois loops configurados. Precisamos realmente verificar
cada um desses valores. Podemos fazer isso usando
uma instrução if. Que podemos dizer que
o valor atual se é uma rainha. E então
vou dizer que a rainha
foi encontrada neste local. Só para que isso faça sentido. Se o item em X, que é representado
por esses quatro loops, e X, obviamente,
for incrementado em
um a cada vez que passa, ele vai para o
primeiro slot aqui Então o segundo é o
Y e isso se move para baixo. O que estamos fazendo é
verificar cada valor, vamos até o outro lado
e depois descendo um lado, descendo outro. É isso que o loop está fazendo. E cada vez verificamos se o slot é uma rainha. Se for, a condição é verdadeira, então estamos executando esta
linha de código
aqui que está apenas dizendo
rainha encontrada no local. E estamos produzindo X e Y. Vamos ver se isso funciona Vamos executar o aplicativo. Rainha encontrada no local 03 e Rainha encontrada
no local 73. Se estivermos certos,
03, isso é zero. Isso tudo é zero aqui. 0123. Isso está correto. Acredito que o próximo foi 701-23-4567 Você pode ver que encontrou
com sucesso as duas rainhas neste tabuleiro de xadrez Se você quiser modificar isso, podemos encontrar os reis
e, em vez disso, podemos
encontrar um K, e isso encontrará os
reis no tabuleiro. Foi um desafio muito divertido. Se alguma dessas coisas for confusa,
repita novamente. Você pode não conseguir na primeira vez, não se preocupe com isso. Mas você
entenderá isso lentamente quanto mais
puder assistir a este vídeo e
entender o problema. Mas isso é como
um exemplo do mundo real que simulamos um tabuleiro de xadrez, por exemplo, ao trabalhar
com duas matrizes D em C
37. 8-4. Listas: Agora vou apresentar uma nova coleção em C Sharp
, chamada lista. Agora, uma lista é bastante
poderosa internamente; na verdade, ela é
construída com base em uma matriz padrão, mas inclui muito
mais opções e muitas maneiras pelas quais você pode realmente trabalhar com as informações
dentro da matriz Por exemplo, vamos falar sobre
esse exemplo aqui. Estamos definindo uma
matriz de números inteiros em C Sharp. Estamos apenas fornecendo alguns valores
numéricos aleatórios. Estamos usando um
loop de quatro para percorrer cada item da coleção e enviá-lo para a tela Se eu executar o aplicativo agora você poderá ver todos esses
números ali mesmo. Muito simples, o que vou
fazer é criar uma nova lista. Vou imitar
essa funcionalidade. Você pode ver a
diferença entre uma matriz e uma
lista, por exemplo. Agora é um assunto um pouco
complicado. Considerando nosso aprendizado até agora, não
vou
explicar tudo, mas abordarei algumas
coisas relacionadas às listas. Agora, como criamos uma lista? Bem, o tipo de dados é lista. Agora, há uma nova notação ainda não falamos Isso é chamado de genéricos. Agora, não vou falar muito
sobre genéricos porque acho que é um
assunto
bastante complicado no momento Mas o que eu quero fazer é definir uma lista que contém números inteiros, por exemplo, você pode ver que o Visual Studio está
tentando me ajudar aqui Na verdade, está sugerindo o que
eu quero fazer. Está correto. Vamos pressionar a tecla tab
no teclado. E está escrito nesta
notação para nós. Eu só vou
completar isso como. Por isso, imitamos a
funcionalidade acima. Agora, essa linha aqui é exatamente a mesma que
essa linha aqui. Esse é um tipo de coleção. Esse é um tipo de coleção. É uma matriz de números inteiros. Aqui, é uma lista de números inteiros e todas contêm
as mesmas informações Vou provar isso para você. Se eu percorrer
essa lista
aqui e enviar todos os
números para a tela, ela fará exatamente a mesma coisa. Como definimos e
inicializamos uma lista em C Sharp? Bem, usamos a
palavra-chave list com
L maiúsculo nesses colchetes angulares Aqui, colocamos o tipo de dados que
queremos armazenar na lista. Da mesma forma, se quiséssemos uma lista de strings,
faríamos isso Por exemplo, colocamos o tipo de dados nesses colchetes
angulares, damos um nome a ele e
usamos um sinal de igual E então queremos
dizer ao sistema:
Ok, agora queremos
inicializar a lista Agora, queremos criar a lista e colocar algumas
informações nela. Usamos essa nova palavra-chave, repita o tipo de dados novamente. Então, nesses parênteses, podemos deixá-los em branco ou podemos atribuir a eles uma capacidade
semelhante a uma matriz Podemos até mesmo passar uma coleção
existente para ela, por exemplo. O que eu poderia fazer é fazer isso. Isso criará uma lista com
base na minha matriz aqui. Você pode ver como ele já está começando a ser bastante poderoso. Novamente, posso provar que isso
também funciona executando o aplicativo e
percorrendo os números que
passamos para ele. Você pode ver que é muito
poderoso nesse aspecto. Mas o problema com matrizes
padrão em C Sharp, por exemplo, vamos trabalhar com nossa matriz
padrão aqui Se eu observar os
métodos nativos relacionados a uma matriz, não
podemos realmente fazer muita coisa com ela. Temos vários
métodos que podemos usar, como obter o comprimento das matrizes ou o número
de itens na matriz, mas não há muito mais
a ver com métodos nativos E se quisermos
classificar essas informações? Talvez coloque o menor número
no início e depois o
maior no final? Como invertemos a
ordem desses números? Várias coisas desse tipo. Bem, esse é um
dos muitos benefícios de usar listas na loja. O que podemos fazer. Vamos dar uma olhada em alguns exemplos de como
trabalhar com listas. Aqui estou definindo uma nova lista. Posso definir uma nova lista
e deixá-la vazia. E mais tarde
no aplicativo, quando descobrirmos o que realmente queremos colocar em nossa lista, podemos dinamicamente, em tempo real, adicionar itens a ela Então, eu poderia adicionar esse
número aqui. E depois outro. Talvez, se quisermos
criar um aplicativo em que coletemos
números de um usuário, possamos definir a lista. E, mais tarde, podemos adicionar os números do usuário quando
executamos o software. Agora podemos ver que
a lista agora contém esses dois números que
adicionamos a ela usando
o método add aqui. Mas não só podemos adicionar coisas, também
podemos remover coisas. Podemos fazer várias
coisas de forma nativa. Mas uma das mais
poderosas podemos realmente classificar os dados. Podemos classificá-lo em ordem. Podemos até mesmo reverter os números. Por exemplo, definimos uma lista com esses
números aqui. E usaremos o método de classificação. E o que isso fará
é pegar todos os números inteiros e
classificá-los em ordem Essa é a única coisa que você
precisa fazer para fazer isso se executarmos o software. Agora você pode ver que todos os nossos números estão em ordem
sequencial Isso é muito fácil de fazer, só que esse trecho de código muito curto de
uma linha. Aqui você pode fazer várias
coisas com a classe list e ela oferece uma maneira
mais poderosa de trabalhar com seus dados. Isso não quer dizer necessariamente que
um levantador seja inútil. Você pode fazer essas
coisas com um aumento usando extensões como link
e coisas assim, mas não vou entrar nisso agora. Não quero complicar muito
esse tutorial, mas estou apenas apresentando
algumas das vantagens de usar listas ao
programar em C sharp Resumindo, se você tem
uma coleção de dados, sejam números inteiros, cadeias ou outro tipo de dados, e não
conhece necessariamente a capacidade, talvez queira
adicionar valores durante
a adicionar valores durante Talvez o usuário
precise adicionar itens ou você queira controlar os
dados de uma maneira melhor. Então talvez a lista seja
algo para você. Talvez seja um tipo de dados
que você queira explorar. Mas é um tipo de dados poderoso, e eu recomendo que você use listas em suas
aventuras na loja C.
38. 9-1. O-O, classes e objetos: Classes e objetos em C Sharp. O que é uma aula?
O que é um objeto? O que tudo isso significa? Bem, deixe-me explicar. Agora, classes e objetos em C Sharp suportam o que é chamado
de paradigma de programação.
O que tudo isso significa? Programação é a
abreviação do que é chamado programação orientada a
objetos
e é um paradigma Um paradigma é apenas
uma palavra elegante dizer uma maneira de fazer
algo como um Se você continuar com seus
esforços em programação, talvez veja muito essa palavra, então
pensei em mencioná-la Agora, um paradigma é um
estilo de programação. Imagine um chef na cozinha
com um pouco de frango cru. Ele poderia assar o frango. Ele poderia ferver o frango, ele poderia fritar o frango. Mas cada um
deles é um paradigma, uma forma diferente de chegar
ao resultado final Então isso é o que é um paradigma. Agora, ao lidar com programas
básicos, como construir uma calculadora ou
algo muito simples assim, paradigmas não são realmente
importantes para iniciantes Não é nenhuma surpresa, você
provavelmente nunca usou nenhum antes quando o software tem
apenas 2030, 40, talvez até 50 linhas de código. A forma de estruturar seu
software não é realmente tão importante porque é uma programação
muito pequena, o estilo de programação
é muito importante. Quando você tem grandes
peças de software, você pode ter de 2030 100 pessoas trabalhando em
uma peça de software. A organização do código
é muito importante. Então, considere isso, por exemplo. Se você tem muitas linhas de
código parecidas com essa, como você mantém isso? Pode ter 50
páginas, 1.000 páginas. Precisamos de uma estrutura, precisamos de alguma organização. E esse é um dos muitos
elementos da programação 00. Agora, programação 00,
é um assunto muito grande e
complicado
que tem
muitas vantagens e
muitos benefícios, mas esse é um deles. Agora, sobre programação, ela
remonta às décadas de 1950, 1960, mas definitivamente
ganhou popularidade, pelo que me
lembro ,
no início Foi quando tudo
realmente começou. O que realmente temos
feito até agora é o que chamamos de programação
procedural, onde o programa começa e nós
meio que executamos cada linha em Talvez tenhamos um método ou dois. E, você sabe, as coisas
são muito simples. Mas, novamente, em aplicativos de
software muito grandes, isso é muito difícil de manter. Por exemplo, programação 00, assunto
muito grande e muito
complicado. Eu posso te entediar com
todos os meandros
disso agora, mas não acho
que seja uma boa maneira de aprender programação 00 Acho que a melhor maneira de
aprender é lidar com alguns
exemplos do mundo real e, na verdade , analisá-los com exemplos
práticos. Então você se lembra
do filme Karate Kid, onde Daniel Larusso
está pintando a casa, pintando a cerca
e lixando o E secretamente, ele estava
aprendendo todo esse karatê, mas não sabia realmente E então, no
final, o Sr. Magi disse, oh, ok, agora teste suas habilidades Então, para os benefícios
de me manter engajado, é exatamente assim
que eu
quero ensinar programação O, e acho que é
uma maneira fantástica de aprender programação 00 aprendendo
pelo exemplo voltando em um
ciclo indireto logo no final Então, quando falo sobre palavras
complicadas
como instanciação, abstração de
polimorfismo,
coesão, acoplamento, todas essas Mas o problema é que, na realidade, eles matam
a motivação E para preservar a motivação e
manter você engajado, vou fazer
isso dessa maneira e acho que será
uma maneira fantástica de aprender essas classes
e objetos em C Sharp O que é uma aula?
O que é um objeto e como ele me beneficia, e por que eu deveria usá-lo? Até agora, se você
está acompanhando alguns dos tutoriais que
fizemos até agora, criamos alguns exemplos
básicos como multiplicar dois
números Onde pegamos dois números de um usuário e os multiplicamos
juntos, por exemplo E quando pegamos um
número de um usuário, podemos representá-lo como um tipo de dado inteiro,
o que é bem fácil E isso é tudo o que precisamos fazer. Não precisamos saber mais
informações sobre esses números para
multiplicá-los. Da mesma forma, se
pegarmos o nome do usuário, podemos armazená-lo em um tipo de
dados simples , que é uma string, e apenas armazenamos
o nome do usuário. Então, muito fácil. Mas como representamos um tipo de dados
complexo, como um usuário ou talvez uma conta, como uma
conta social,
ou uma conta bancária, ou
até mesmo uma bicicleta, como
um objeto do mundo real, ou um sanduíche, ou até mesmo um planeta inteiro como planeta Terra ou
algo parecido Bem, até agora, com nosso estilo de programação
procedural cano, talvez para representar um usuário, possamos ter uma string que pode ser o primeiro nome do
usuário
e, em seguida, outra string
para seu sobrenome Talvez um número inteiro para sua idade
e, em seguida, talvez uma string
para seu nome de usuário Se eles tiverem um nome de usuário, poderíamos ter talvez um decimal ou um duplo
para sua altura A lista continua.
Há muitas coisas que você pode armazenar sobre um usuário. Você pode ver que eu já tenho cinco linhas de código para
todas essas variáveis. Esta página de lata aqui vai preenchê-la muito rapidamente
com muitas informações. Talvez eu possa usar esses
cinco tipos de dados aqui. Esses
tipos de dados simples, string, int e double, representam um objeto
complexo, como um usuário. Da mesma forma, se eu tiver uma bicicleta, talvez
eu queira a
cor da bicicleta, a marca da bicicleta, talvez as medidas,
coisas assim. E é assim que eu
representaria um objeto de bicicleta. Mas como faço para colocar tudo
isso em seu próprio objeto? Por exemplo, em vez para cada usuário em
nosso aplicativo, posso simplesmente digitar usuário e
podemos ter nosso próprio tipo de dados,
como um tipo de dados de usuário. Isso seria muito
legal, não é? Esse é um dos benefícios de usar classes e
objetos em C Sharp. Vamos dar uma olhada em
como podemos realmente criar nosso próprio
tipo de dados em C Sharp. O que vou fazer agora é
criar uma classe totalmente nova, basicamente um
novo tipo de dados personalizado que podemos usar
em qualquer lugar do nosso software. Se formos para o lado
direito aqui, esse é o nome do nosso projeto
aqui, programação. E tem um pequeno
ícone em C nítido com um quadrado ao redor. Então, vou clicar com o botão
direito do mouse aqui. Eu vou para Add e depois vou
para a aula. Uma vez que estamos aqui, podemos
ver as classes sendo selecionadas. Aqui embaixo, podemos dar um nome
à classe. Agora você pode ligar para a turma do jeito que
quiser. Mas é uma prática comum
iniciá-lo com uma letra maiúscula para
ver com seu propósito. Qual é o propósito dessa
aula? O que isso faz? Quais informações ele contém? Ou qual é sua função principal? Dessa forma, quando você tem
um aplicativo muito grande com talvez 1.000 classes, você sabe exatamente pelo nome, o que ele alcança,
o que ele pretende fazer O que vou fazer é criar um tipo de dados personalizado chamado Usuário. Isso vai fazer é
armazenar informações sobre um usuário em potencial que possa
estar usando nosso software. Vou chamá-lo de usuário e, em
seguida, clico no
botão de anúncio aqui. O que isso faz é criar uma nova classe
em nosso projeto. Este é o nosso projeto aqui. Até agora, se você assistiu nossos tutoriais
anteriores com a classe padrão chamada programa, e estamos trabalhando
com o método principal Você pode ver aqui que há uma classe chamada programa e o método principal está dentro dela. Essa é uma classe padrão de
um tipo de aplicativo de console. Mas se formos até aqui, agora temos uma
nova classe chamada Usuário. E agora podemos colocar
algumas informações dentro dessa classe aqui. Então você pode ver que o Visual Studio está sugerindo o que eu poderia
querer colocar aqui Sim, pode ser uma
forma preferível de fazer isso, mas falarei sobre o get and set em um tutorial futuro Então, eu vou fazer isso de forma
um pouco diferente. O que queremos fazer
aqui em nossa nova classe
, chamada de usuário, é colocar tudo
sobre nosso usuário. Então, talvez o nome do usuário, o sobrenome do usuário,
a idade do usuário. Qualquer coisa a ver com um usuário. O que eu vou fazer é definir algumas variáveis simples aqui. Então,
o que vou fazer é chamá-lo talvez de
primeiro nome, por exemplo, e depois talvez de sobrenome, e então talvez de idade,
algo assim. Antes de cada uma
delas, eu só quero colocar essa palavra-chave interna. Não se preocupe com o
que isso significa agora. Vamos abordar isso
novamente em um tutorial posterior. Mas o que eu fiz foi definir três tipos de dados simples aqui, duas cadeias de caracteres e um número inteiro E todos os três estão
dentro da classe de usuário. Essa é a nova classe que acabamos criar. O que
tudo isso significa? Esse é o nosso tipo de
dados personalizado aqui Assim como um número inteiro
é um tipo de dados, uma string é um tipo de dados Agora, o usuário é nosso próprio tipo de dados
personalizado e tem todas essas
coisas dentro dele. Vejamos um exemplo
do que isso significa. Se voltarmos à nossa classe principal aqui com o método main, podemos realmente configurar o que é chamado
de instância da nossa nova classe. Assim como quando
criamos uma string, podemos fazer algo assim. Mas quando temos um tipo de dados
personalizado, como uma nova classe, por exemplo, o formato é um
pouco diferente. Seria nosso tipo de dados
personalizado, que é o nome da nossa classe, que é usuário, porque
criamos uma classe
com o nome usuário. Você pode ver agora que
isso é verde e , na verdade, tem algumas
informações sobre nossa classe. Se eu digitar Bacon, por exemplo
, você pode ver que é
preto, há uma linha vermelha. Isso porque não
temos uma turma chamada Bacon. Agora temos uma classe
chamada Usuário, é verde. E podemos realmente
fazer uso disso. Agora vamos dar um
nome a ela, assim como fazemos aqui, por exemplo, com
uma variável simples. Vou chamá-lo apenas de EUA. R, abreviação de usuário. Então eu vou ser igual. E o Visual Studio está me
dando uma dica sobre
o que eu quero fazer Isso é
exatamente o que eu quero fazer. Quero criar uma nova instância
da nossa classe chamada user. E eu estou dando a ele o nome de USR. Eu posso dar o nome que eu quiser, isso
realmente não importa. Agora eu tenho uma variável totalmente nova, assim como uma variável
aqui do tipo string. Agora tenho uma nova variável
aqui chamada usuário dos EUA. Se eu começar a usar minha variável USR e depois
colocar um dardo, você verá que posso
realmente acessar essas variáveis que acabei de
criar em nossa classe Você pode ver aqui o sobrenome, o primeiro nome e a idade. Vamos configurar uma amostra de variável de
usuário. Se eu disser o primeiro nome do usuário, sabemos que isso é uma string. Vamos ligar para ele, eu não sei. Vamos chamá-lo de Bob. Por que não? Vamos configurar um
sobrenome para nosso usuário. Vamos chamá-lo de Bob Smith. Por fim, Bob Visual
Studio quer que eu coloque 30. Por que não? Não sei por que Visual Studio está indicando
30, mas aí está. Agora, o que eu fiz
aqui, eu criei um novo
objeto de usuário aqui. E então eu dei
algumas informações. Esses campos aqui. Esses são exatamente os mesmos
campos que definimos em nosso novo usuário, que
são como nosso tipo de dados, e atribuímos a eles
alguns valores aqui. O que eu posso fazer agora é realmente
usar essas informações. Se eu usar o console na linha direita, posso realmente enviar algumas dessas informações
para a tela. Digamos que eu mostre
o nome,
sobrenome e idade do usuário . Vamos manter a janela do console aberta para que ela não feche para nós. Agora vamos executar o aplicativo
para ver o que temos aqui. executar o aplicativo, podemos ver que, na verdade, estamos enviando todos os valores do nosso tipo de dados
personalizado para a tela Estamos definindo os
valores dessa forma. Estamos enviando os valores do nosso tipo
de dados personalizado, da
mesma forma, para a tela Ao criar
classes em C Sharp, como nossa classe de
usuário personalizada aqui, imagine essa classe sendo um
modelo, uma especificação Tudo dentro da nossa classe
aqui tem a ver com um usuário, não com uma bicicleta
, um sanduíche ou
algo aleatório Tudo aqui está envolvido na criação
de um novo usuário. Temos o nome do usuário, a idade do usuário, tudo a ver com um usuário. Imagine isso como
um modelo para isso, ou como eu disse, uma especificação O processo aqui, o que
estamos fazendo, é criar um objeto exatamente como
quando criamos uma variável de string simples
chamada name, por exemplo. Ao lidar com
classes personalizadas e coisas assim, elas são chamadas de objetos. Agora você pode ver de onde
veio
o termo programação
orientada a objetos veio
o termo programação
orientada Porque representamos coisas
do mundo real, como usuários, carros, bicicletas, como objetos
como classes, Aqui está o objeto, esse é o tipo de dados
que é uma classe. Esse processo aqui é
chamado de instanciação. E isso é chamado de
instanciação porque você está criando uma nova
instância de uma classe O que também podemos fazer é criar uma segunda instância
da mesma classe. Essa é a primeira instância. Essa é a segunda instância. Podemos criar 50. Poderíamos criar 100, por exemplo. O que podemos fazer aqui
é outro usuário e talvez ele se chame Darren
Smith e tenha 75 anos Da mesma forma, podemos enviar suas
informações para a janela. Como você pode ver lá, você começa a ver o verdadeiro poder da programação orientada a objetos. Poderíamos criar milhares
desses objetos de usuário e replicar milhares de usuários em nosso software,
se quiséssemos Não estamos limitados a
ter apenas objetos de usuário. Poderíamos ter objetos de conta, muitas coisas diferentes para
unir nosso software. O que podemos fazer com
esses objetos aqui passá-los para métodos, colocá-los em matrizes, percorrê-los em loops Os limites são infinitos. Mas isso é apenas uma pequena amostra da
programação orientada a objetos E isso começa com a criação de
classes e novos objetos. Então, espero que isso tenha ajudado
você a começar sua
jornada orientada a objetos na C shop
39. 9-2. Construtores: Eu vou falar sobre
construtores agora em C Sharp. O que é um construtor?
Como eles funcionam? Bem, vamos dar uma
olhada aqui, temos um exemplo
muito simples. Temos uma
classe personalizada chamada user. Temos três variáveis
dentro da classe, que são informações sobre o usuário e a
idade do usuário. Então, estamos apenas
configurando um novo objeto, que é uma instância
da classe. Estamos fornecendo alguns
valores, nome, sobrenome e idade, e os
exibindo na tela Um software muito simples. Vou introduzir um
construtor neste exemplo. Agora, o que um construtor faz é nos ajudar a construir
nossos objetos Aqui estamos criando uma nova
instância da nossa classe. Aqui está nosso objetivo. O que um construtor faz é nos ajudar a
configurar esse objeto Vamos aprender pelo exemplo. Acho que
seria mais fácil aqui. Aqui estamos configurando
um novo objeto de usuário. Vou apenas copiar
e colar este. E vamos criar um
novo objeto, outro objeto. Ok, aqui estou criando
um novo usuário chamado Tony, Tony Smith e sua idade é 41. Quando eu configurei esse usuário, você pode ver que ele usa
quatro linhas de código. Talvez, se quisermos
montar 100 deles
, não
pareçam muito elegantes
, pareçam
muito inchados Essa é uma das vantagens
de usar construtores. O que posso fazer ao criar uma
nova instância dessa classe realmente passar esses
valores como parâmetros. Ao criar uma nova instância, o que posso fazer é
passar, digamos, Tony, posso passar Smith e depois
passar a idade aqui. Então eu posso deletar todas
essas linhas de código. E então, essencialmente, essa linha fará exatamente a mesma coisa, essas quatro linhas aqui. Essa é uma vantagem dos construtores: a
minimização do código É representado
somente em uma linha. Mas como configuramos isso? Porque agora
temos uma linha vermelha. E se eu passar o mouse sobre
isso, diz que o usuário não contém um construtor que receba três
argumentos Bem, vamos adicionar um. Vou entrar na classe de
usuário aqui, preciso configurar um construtor Como eu faço isso? Tudo começa
com a palavra-chave interna. Agora, não se preocupe com o que é
interno no momento. Eu discutirei isso em
um tutorial posterior. Todos os construtores usam
o nome da classe. O nome da classe é user. Vou colocar o
nome da turma lá. Depois disso, coloquei parênteses e depois os
familiares colchetes encaracolados Este é um construtor básico
em sua forma mínima. Podemos ter
mais de um construtor por classe, se quisermos O que eu quero fazer é
pegar esses valores aqui e inicializá-los
em nossas variáveis aqui Eu quero colocar esses
valores aqui. O que eu preciso fazer, quando
trabalhamos com métodos, funciona de forma muito semelhante a isso. Quero passá-los essencialmente
como parâmetros que
vou fazer primeiro. Por exemplo,
nome, sobrenome, idade. Ao dar um nome aos
parâmetros, dê a eles nomes significativos como nome,
sobrenome e idade. E certifique-se de que elas
não sejam exatamente
iguais às
variáveis locais aqui. Dê a eles uma caixa ligeiramente
diferente, por exemplo, ou um nome completamente
diferente Eu discutirei isso
em um tutorial posterior quando eu falar sobre essa palavra-chave. Por enquanto, nossos parâmetros estão entrando em nosso
construtor aqui Agora eu quero inicializar essas variáveis locais com
esses valores aqui É muito fácil fazer isso. Eu pego a variável local aqui, eu a defino como o valor
do parâmetro. Essa já está pronta e continuaremos com
as outras duas. O Visual Studio nos
ajudou muito bem. Vamos apenas revisar o que
está acontecendo aqui agora. A linha vermelha desapareceu. Se eu passar o mouse sobre
isso, está funcionando.
Não há linha vermelha. Estou passando uma string, uma string e um inteiro para o construtor da Ao criar nosso objeto, esses valores são passados como parâmetros para o construtor,
que é tudo isso Então, o valor dos
parâmetros atribuídos, bem, foi inicializado em
nossas variáveis locais aqui Agora, essas variáveis locais
aqui manterão
esses valores para sempre ,
desde que essa instância permaneça
ativa em nosso sistema. Isso é muito legal, não é? Deixe-me executar o software bem rápido para que você possa
ver o que está acontecendo. Vou comentar isso e voltarei
a isso em um segundo. Agora, vamos colocar isso
aí, sem problemas. Nós executamos o software. Agora, você pode ver isso,
diz Tony Smith, 41 anos. Parece que está
funcionando corretamente. Deixe-me desfazer esses comentários e falar sobre mais uma coisa Você pode ver algo
interessante. Agora, há uma linha vermelha
embaixo dessa parte aqui. Quando tentamos
configurar um novo objeto, ele não está mais
funcionando. Por que isso? Isso porque em nossa
classe aqui, por padrão, não
temos nenhum construtor.
Parece que é assim. No entanto,
uma vez que definimos um construtor com
parâmetros como esse, não
podemos mais configurar uma instância da nossa
classe dessa forma Há uma maneira fácil
de contornar isso. Definimos apenas um construtor muito
básico sem parâmetros Agora você pode ver essa linha vermelha desapareceu
e tudo está feliz. Como isso está funcionando? Bem, quando chamamos
esse construtor aqui, quando criamos esse objeto, estamos passando
três parâmetros Quando essa linha é
executada pelo software, a execução do código
entra aqui E tudo está configurado aqui. Quando criamos uma nova instância
usando essa linha aqui, não
há parâmetros, esse
construtor é chamado Em vez disso, isso nunca é executado, apenas esta seção aqui, não
há nada acontecendo aqui. Agora essa é a diferença
entre os dois. Na verdade, existem dois construtores
agora dentro dessa classe. Isso está usando o
primeiro construtor, isso está usando o segundo E podemos ter 50
construtores se quisermos, mas é
assim que as coisas acontecem internamente
em nossa classe internamente
em nossa Então, você pode ver
que os construtores nos permitiram
minimizar o código, você sabe, em apenas uma
linha, por exemplo Mas o que mais
eles podem fazer? Você sabe, qual é o outro benefício? Bem, construtores como nós
dizem que podem ajudá-lo a construir seu objeto e isso meio
que acontece nos bastidores Então, a partir desse arquivo aqui, não
precisamos realmente saber
como esse usuário está configurado. Estamos apenas passando algumas informações e
podemos recuperá-las quando quisermos. Então, todo esse tipo de lógica está escondido de nós,
o que é muito legal. Os construtores podem fazer internamente algumas coisas com as quais não precisamos nos preocupar nos bastidores Por exemplo, se eu chamar esse construtor passando
os dois nomes na idade, eu poderia enviar algo para
a janela, por exemplo Eu poderia dizer ao usuário que estamos configurando um novo usuário. Por exemplo, quando eu
executo o software. Agora você pode ver que recebo uma
pequena mensagem dizendo, ok, por favor, espere, estou apenas
configurando um novo usuário. E então ele gera
as informações. Construtores, façam
algumas coisas extras, eles não precisam
apenas configurar variáveis Eles poderiam se conectar a um banco de dados, eles poderiam falar com um site. Eles poderiam abrir uma conexão com o
banco de dados. Eles podem fazer muitas
coisas internas nos bastidores. É assim que eles podem ajudar a
construir um objeto, e é por isso que são
chamados de construtores Os construtores são elementos muito
poderosos
da programação orientada
a objetos E você pode ver, usando este
exemplo neste tutorial, como isso simplifica as coisas Talvez não na aula em si , mas definitivamente trabalhando
daqui. Você pode ver como
tudo parece simples usando apenas uma linha de
código para configurar um objeto. E não precisamos nos preocupar
com as coisas internas que estão
acontecendo aqui. Esse é um exemplo de
construtores na loja C, e espero que você o ache
bastante útil
40. 9-3. Métodos de objeto: Vamos falar sobre métodos de objetos. Agora, aqui eu tenho um aplicativo
de exemplo. O que estou fazendo é
criar uma nova lista aqui. Então, estou criando três usuários. Todos eles têm
informações exclusivas aqui. Por exemplo, Tony
Smith tem 70 anos, Bob Holmes e Tyrone Jones Então, cada um desses objetos aqui, eu estou adicionando cada um à nossa lista. Agora, nossa lista de usuários
conterá todos esses três
objetos. Estou usando um loop de quatro
para
percorrer todos os
usuários e, por sua vez, enviar todas essas informações
para a janela do console. Vamos dar uma olhada nisso. Agora você pode ver que esse
é o resultado que obtemos. Está apenas exibindo todas essas informações do objeto
na tela Agora, o que
eu quero fazer é descobrir quais desses
usuários se aposentaram. Eles atingiram a
idade de aposentadoria ou são aposentados? Dependendo do país em que você
mora agora. No Reino Unido, não
tenho certeza sobre a América, mas a idade de aposentadoria é,
acho, 66 para homens. Usaremos apenas 66 como um número arbitrário.
Pode ser qualquer coisa. Tony Smith
se aposentaria nesse caso, mas Bob Holmes e Tyrone Jones ainda
têm um longo caminho a percorrer
antes de se aposentarem O que eu quero fazer
é
enviar uma
informação extra para dizer se o usuário se aposentou? forma como normalmente faríamos isso é configurar talvez uma declaração if. E dizemos que se a idade do usuário, idade for maior ou igual a, digamos que 66 é
a idade de aposentadoria, então diríamos, ok,
eles estão aposentados. Nós diríamos aposentado. Vamos inicializá-lo como falso. Se forem maiores do que isso, direi que se aposentar é verdade, mas, por exemplo,
algo parecido. É assim que
normalmente configuraríamos um caso em que, se eles se aposentassem, usaríamos uma condição. E então enviamos essas
informações para a tela. Seria
algo parecido com isso. Você pode ver que temos nossa
boa história aqui com nossa idade, sobrenome e idade. Mas quando se trata de se aposentar, temos todas essas informações. Parece um pouco inchado. Talvez possamos mover
isso para outro lugar. Talvez dentro da nossa classe aqui. E depois, basta colocar
outro forro aqui. Isso é o que podemos conseguir
com métodos de objetos. Nesse caso, o que queremos
fazer é colocar essa lógica aqui, essa condição dentro da nossa classe. Não precisamos nos preocupar com isso. Não sabemos como é
calculado, realmente não nos importamos. Só queremos uma pequena
variável aqui, foi retirada e podemos
exibir essa informação. Vamos dar uma olhada em
como podemos criar um método de objeto movendo essa lógica para dentro da nossa classe. Pouco antes de fazer isso, vou executar o aplicativo
bem rápido. Só para que possamos ver
o resultado aqui. Você pode ver abaixo cada usuário que diz que
se aposentar é verdadeiro porque essa idade tem mais de 66 anos e o resto é falso só porque
eles não
têm 66 anos ou Isso vai mover
essa lógica para o que é chamado de método de objeto. E nós definimos isso dentro da
nossa classe aqui.
Aqui está nossa aula. Aqui temos nossas variáveis, aqui temos dois construtores O que queremos fazer é apenas
criar um método aqui, vamos usar a palavra-chave
interna novamente se
preocupe com o
que isso significa agora. Nós vamos apenas
colocá-lo aqui. Quando definimos um método, precisamos de um tipo de retorno. Vai ser uma garantia porque queremos dizer se verdadeira ou
se eles se aposentaram de forma
falsa, por exemplo Agora, o nome do
método que vou
chamá-lo foi retirado. Não usa nenhum
parâmetro porque temos acesso à idade por meio
da própria classe aqui em cima. Use na idade,
vamos apenas criar nosso método aqui e, em seguida, o que queremos
fazer é retornar
algo assim. Agora, o Visual Studio
já sugeriu o que talvez
queiramos fazer, mas vamos ver isso aqui O que estamos dizendo aqui
é que se a idade do usuário for maior ou igual a 66 anos,
aposentado é igual a verdadeira, também
podemos dizer isso, o
que é exatamente a mesma coisa, porque essa condição será
avaliada como verdadeira ou falsa E então o resultado é armazenado em um bolen. Muito simples, na verdade. O que eu quero fazer é
pegar a condição aqui, ir para nossa classe e queremos devolvê-la desse método aqui. Simples assim, porque
estamos dentro da nossa turma aqui. Temos acesso à idade do usuário aqui. Vamos pegar isso e
colocar aquilo lá. Criamos um método, ele não tem parâmetros, mas tem um
tipo de retorno de booling Estamos retornando verdadeiro ou falso se a idade do usuário aqui for
maior ou igual a 66. Voltando aqui, podemos
remover isso completamente. Agora, o que podemos fazer é
pegar nosso objeto aqui, que é o usuário, porque estamos passando por
isso em um loop frontal. E então podemos acessar um método
totalmente novo que
acabamos de criar aqui,
chamado é retirado. E você pode ver que
retorna um bolen. Então, clico duas vezes nos parênteses
abertos e fechados porque não usa E agora você pode ver que o código parece muito mais simplificado Não temos esse tipo
de condição aqui. Temos apenas quatro tipos
de códigos legais. Um recebendo o nome, outro obtendo a idade e outro
recebendo se está aposentado. Acabei de perceber que
escrevi aposentado de forma errada
no método,
ninguém é perfeito Mas você pode ver que parece
muito mais simples agora. Mas um dos benefícios e
vantagens do 00, de qualquer forma, é que sua lógica está meio que
escondida aqui. Digamos, por exemplo, que um
membro da sua equipe, se você estiver trabalhando em uma grande equipe, trabalhe nessa aula aqui e
você trabalhe nessa aula aqui. Você não precisa se preocupar com a forma como a aposentadoria é calculada. Você não sabe, talvez
você nem se importe. Você nem sabe qual é
a idade da aposentadoria. Tudo bem, porque
a única coisa que precisamos chamar é esse
método aqui. Então, talvez nosso amigo da nossa equipe de
software possa, você sabe, lidar com as complexidades de descobrir, talvez
, qual seja
a idade de aposentadoria Então, o princípio é que está meio que escondendo as
informações de você, está abstraindo-as. E esse é um dos pontos-chave
da abstração da programação orientada a
objetos Você não precisa
saber como isso funciona. Por exemplo, se você
possui uma cafeteira, não precisa
saber como está indo. Você sabe como funciona dentro,
internamente, de todos os componentes eletrônicos A única coisa que você
precisa fazer é
enchê-lo com água e
pressionar o botão. Então é isso que eu meio que estou
tentando explicar aqui. Não precisamos
saber como isso funciona, basta chamar
o método e
ele será obtido como um valor verdadeiro ou falso. Então essa é uma das
vantagens de usar a programação orientada a
objetos e
é assim que os métodos de objetos
funcionam no Sea Shop.
41. 9-4. Modificadores de acesso (público, privado, etc): Agora vou falar sobre modificadores de
acesso na loja. Parece um pouco complicado, mas vou detalhar. Portanto, é muito simples e
você entenderá
tudo o que tem a ver com modificadores de
acesso na loja Então, o que é um modificador de acesso? Agora, antes de falarmos sobre o tipo de trabalho que uma
classe teria, ela meio que modela um
objeto do mundo real. Neste exemplo. Aqui eu tenho uma aula de videogame. Quando eu crio um novo
videogame, por exemplo, ele quer o nome do videogame, seu editor e uma
classificação para o jogo. Então, você pode ver que uma classe aqui representa um objeto de videogame. É como um objeto do mundo real. E quando criamos classes, queremos tudo
dentro da classe. Por exemplo, essa aula de
videogame aqui é apenas sobre
videogame. Então, não queremos falar sobre nada
além do videogame aqui. Talvez como a comida que comemos enquanto
jogamos o videogame. Ou talvez alguma informação sobre o usuário jogando o jogo. Porque talvez essas informações
do usuário possam estar em uma classe de usuário. Ou talvez a comida
que o usuário esteja comendo enquanto joga o videogame
esteja em uma aula de culinária. Isso é muito importante
com a programação 00, você mantém as classes chamadas de altamente coesas E isso significa que
tudo dentro da classe de videogame tem
a ver diretamente com um videogame. Esse é o princípio geral. De qualquer forma, isso não só
beneficia a organização do código, mas permite que pessoas
diferentes trabalhem nesse projeto. Por exemplo, talvez 100 pessoas. Assim, você pode delegar
uma ou duas pessoas para trabalhar, digamos, nessa aula Embora outra pessoa
possa se concentrar nessa aula principal aqui, ela tem vários benefícios. Mas como isso se relaciona modificadores de
acesso e
coisas assim Bem, considere
este exemplo aqui. O que estou fazendo é construir quatro objetos de videogame aqui Estou inserindo alguns dados de amostra O que está acontecendo nos
bastidores aqui quando estou construindo
esses quatro objetos Estou apenas configurando
algumas variáveis aqui. O nome, o editor
e a classificação. Você pode ver que os parâmetros estão chegando ao construtor e eu estou apenas definindo os valores No entanto, secretamente
dentro dessa classe, o que estou fazendo é gerar um novo ID exclusivo para cada
objeto que estamos criando O que está acontecendo aqui é
que eu tenho um método aqui. É só configurar essa variável
aqui para um ID exclusivo. Você não precisa
se preocupar com o que isso faz, mas o que isso faz gera uma ID exclusiva, que é única e nunca
deve haver uma duplicata Essa é uma função embutida que você pode usar para fazer isso E está apenas definindo essa
variável aqui para um ID exclusivo. Então, se criarmos um jogo aqui
usando esse construtor, ele sempre terá um ID exclusivo Desta parte
do programa aqui, não
temos ideia de que
isso está acontecendo. Estamos apenas
transmitindo três valores. Nem sabíamos
que tinha um ID exclusivo. Não temos ideia do que está
acontecendo nos bastidores. E essa é a beleza da programação orientada a
objetos. Não precisamos saber e não
precisamos nos importar. Por exemplo, acabei de criar esse objeto aqui
chamado Game One. Quando eu entro aqui, posso
reeditar a editora. Eu posso alterá-lo para
um valor diferente. Agora eu o construí. Digamos, por exemplo, World of Warcraft Blizzard tenha sido
dominado pela Então, talvez eu queira modificar a editora para criar jogos mais tarde no software,
por exemplo Eu posso fazer isso sem problemas. No entanto, e se alguém puder alterar
acidentalmente
esse valor de ID aqui? O que eu vou
fazer é ir até aqui, primeiro
jogo, e você pode
ver esse campo de identificação aqui. Eu poderia mudar isso
para o que eu quiser. O problema é que não quero que
ninguém altere esse campo de ID. Já é único. Não quero que nenhum outro
membro da equipe modifique esse valor. Isso pode corromper os dados
porque o ID é exclusivo. E qualquer um poderia simplesmente alterar esse valor de ID para
sanduíche de presunto, por exemplo Você sabe, isso pode ter
muitos efeitos adversos. Primeiro, isso poderia quebrar
o software. Segundo, isso poderia causar, você sabe, perda de informações. Você sabe, isso pode ter muitos efeitos
negativos no software. Então, o que eu quero
fazer é manter esse ID privado para a classe. Eu só quero que a
própria classe saiba sobre esse ID e gerencie o ID
internamente para essa classe Não quero que ninguém
no software modifique nenhuma outra classe ou qualquer outra parte do
software para tocar nesse ID Talvez eles possam simplesmente
dar uma olhada,
mas eu não quero que eles
editem, por exemplo. É aqui que os
modificadores de acesso são úteis. Agora, os modificadores de acesso aplicam
o que
é chamado de encapsulamento, ou
seja, garantir que
dados confidenciais, como ID, nesse caso, sejam ocultados de
usuários ou pessoas, ou mesmo de outros
softwares que
nunca deveriam ter Esse é um exemplo de encapsulamento
e por que o encapsulamento é importante ao gerar Vamos dar uma olhada em como
podemos restringir o acesso a determinadas variáveis ou mesmo
métodos usando modificadores de acesso Vamos para nossa aula. Vamos falar sobre vários modificadores de
acesso que podemos ter em C Sharp Agora, o primeiro é
o que se chama público. Você pode ver aqui em público. Isso significa apenas qualquer coisa
definida como pública, você pode ter uma
variável, por exemplo, ou até mesmo um método. Por exemplo, este aqui embaixo, se eu tornar isso público. E isso significa que quando criamos
um objeto dessa classe, podemos acessá-lo de
fora da classe. Podemos acessá-lo de
qualquer lugar em nosso projeto. Em qualquer lugar em nossa solução. Eu digitei o primeiro jogo, depois um pouco lá, e agora podemos acessar o ID Podemos acessar o método de gerar
novo ID aqui. Isso porque eles
são públicos e podemos acessá-los
de qualquer lugar. Agora, o outro é
o que é chamado de interno. Podemos ter variáveis aqui, podemos ter
construtores internos, podemos ter métodos internos A diferença entre público
e interno é que o interno só pode ser acessado
na montagem ou projeto atual. O que isso significa?
Bem, venha até aqui. Até agora, estamos trabalhando
com um projeto até agora. Agora o que podemos fazer é ter outro projeto em nossa solução. Poderíamos ter 50
projetos, por exemplo. O que isso significa em nosso projeto. Aqui, nosso projeto padrão, somente as classes dentro do projeto podem acessar coisas
internas. Se estivermos em outro projeto, talvez esse projeto
represente o banco de dados, como a camada de dados ou
talvez o front-end onde talvez estejam todas as coisas
gráficas. Então, eles não podem acessar coisas
internas porque elas são apenas internas
ao projeto atual. Falaremos mais sobre
vários projetos posteriormente, mas essa é basicamente
a palavra-chave interna. Outro modificador de acesso
é chamado de protegido. Agora, falaremos
sobre proteção mais tarde, então não se preocupe com
isso por enquanto. O último sobre o qual eu quero
falar é privado. Agora, a privacidade é muito importante para o
exemplo que acabei de dar com relação
ao acesso ao ID
de fora dessa classe. Que privacidade ela impõe? Variáveis locais como
essa ou mesmo métodos como esse só podem ser
acessados de
dentro da classe atual. O que eu fiz foi
alterar esse ID para privado e alterei
esse método para também privado. Se eu voltar ao meu programa principal aqui e colocar um ponto
depois desse objeto, você verá que
a propriedade ID, a variável ID, está
ausente dessa lista. Você também notará que
o método para gerar um novo ID também está
ausente dessa lista. Você pode ver o que
está acontecendo aqui. Está impondo o encapsulamento. Ele está escondendo
informações confidenciais porque queremos apenas que a classe de
videogame possa gerar novos IDs e você controle o ID
do videogame. Ninguém mais em todo esse software precisa
saber sobre IDs. É exclusivo do videogame e
deve permanecer exclusivo do videogame. Portanto, esses campos devem
ser privados porque somente o videogame precisa
saber disso, são informações
privadas. Então, considere
isso assim, por exemplo. No entanto, o nome
do editor é público. Vamos tornar a classificação interna. Enquanto eu estiver trabalhando
no mesmo projeto, devo ser capaz de acessar o
nome, o editor e a classificação. O que eu posso fazer aqui, classificação
do nome e editora. No momento, o ID é privado. Se eu tentar usar isso de qualquer maneira, por exemplo, coloque algumas
informações dentro do ID lá. Você pode ver que eu tenho
um erro aqui. E se eu passar o mouse sobre
isso, diz que o ID de pontos do videogame está inacessível devido ao
seu nível de proteção Isso porque é privado. Na verdade, não podemos acessar essas informações se
tentarmos executar o software
e
compilá-lo, ele nem vai virar letras Então você pode ver que isso é
o quão rigoroso é aplicado. Assim que eu mudar esse
ID para público ou interno
, a
linha vermelha desaparecerá. A proteção desapareceu. Podemos executar o
programa normalmente. Então esse é o poder dos modificadores de
acesso em C Sharp. Ele aplica o que é chamado de
encapsulamento e protege nossos dados confidenciais de
outros softwares, de outros segmentos do software
existente e até mesmo de usuários que trabalham em diferentes partes
do software Ele reforça a integridade dos dados e evita muitos problemas adversos que podem ocorrer por causa disso Esses são modificadores de acesso
em C Sharp e por isso são muito úteis na
criação de classes e objetos Por fim, quero falar sobre que pode ter modificadores de acesso Aqui temos um método que
tem um modificador de acesso. Temos alguns
construtores aqui que têm modificadores de
acesso e também
algumas variáveis locais Eles também têm
modificadores de acesso aqui. Mas você notará que a
classe que contém todos esses
elementos também
tem um modificador de acesso Agora, o público é o modificador de acesso
mais fraco. Se algo for tornado público, qualquer pessoa em qualquer lugar da solução
poderá acessar esse item. No entanto, a classe em si
é marcada como interna. E isso significa que somente
classes dentro do projeto ou
montagem existente podem acessar essa classe. Por padrão, esse modificador de acesso
mais forte substitui qualquer coisa Vamos substituir todos esses modificadores de acesso
público aqui. E isso porque
a classe ao redor está marcada como interna. Por padrão, o acesso a
eles será interno. Se eles forem públicos, será algo
parecido com isso. Mesmo que estejam
marcados como públicos, é
assim que eles
serão acessados. No entanto, se eu marcar
a classe como pública
, não há problema
porque esse é o modificador de acesso mais fraco Tudo isso será
público se você já trabalhou com permissões de arquivos e
pastas para sistemas
operacionais
e várias configurações podem substituir as subpastas. Funciona de forma muito semelhante a
isso Para esclarecer, se eu conseguisse
marcar essa classe como privada, por padrão
, tudo
dentro dela seria privado, independentemente
do modificador de acesso Esse é o ponto que estou
tentando transmitir. Agora, escrever modificadores de acesso
em C sharp é opcional. Se eu remover o
modificador de acesso da classe,
então, por padrão, as classes
são todas internas Eu poderia escrever isso
e isso
seria exatamente o mesmo
que fazer isso. É opcional, mas é
considerado interno por padrão. No entanto, qualquer coisa
dentro da classe, métodos, construtores,
propriedades ou variáveis,
por padrão, são todas privadas, menos que sejam explicitamente marcadas
como públicas ou internas.
Então, presume-se que
sejam Escrever isso seria exatamente
o mesmo que escrever isso. Nesse caso, o
privado é opcional. Poderíamos remover o modificador
de acesso
privado do método e
da variável aqui em cima E isso terá
exatamente o mesmo efeito porque, por padrão, qualquer coisa dentro da
classe é considerada privada se
não houver modificador de acesso
42. 9-5. Propriedades: Eu vou falar
sobre propriedades na loja. Agora, também
discutiremos a palavra-chave get
e a palavra-chave set, também conhecidas como
getters e setters Então, o que tudo isso significa? Bem, vamos dar uma olhada. Se você acompanhou
os outros tutoriais
até agora relacionados à programação
orientada a objetos, então isso vai fazer sentido e
começar a partir daí Caso contrário, eu
recomendo fortemente que você
os assista para que você esteja
prestes a entender o que vou lhe mostrar. O que é uma propriedade de loja? Por que devemos usá-los? Portanto, as propriedades da loja impõem um
dos princípios fundamentais da programação
00, que
é o encapsulamento E isso é apenas garantir informações
confidenciais não sejam acessíveis de nenhum outro lugar. Como quando falamos sobre
essa variável privada aqui, ela só é acessível
dentro da classe e ninguém que a acessa
tem controle sobre
isso, por exemplo. Então, isso vai levar
isso um passo adiante. Então, vou
apresentar um cenário aqui e mostrar
um dos benefícios
de usar propriedades nítidas , coletores
e configuradores Neste exemplo, definimos
uma classe de videogame aqui. Ele tem várias variáveis
aqui que podemos usar e um construtor com
três parâmetros Aqui estamos configurando
quatro objetos de videogame. Jogo 123.4 Dentro
do construtor estamos criando um
nome de videogame, o editor do jogo e uma classificação para o jogo,
digamos que, quando nosso
programa é iniciado, todos esses dados são
carregados no sistema Em algum momento posterior
no software, o usuário
deseja modificar. Por exemplo, o nome
desse jogo aqui. Eles clicaram no botão de edição, talvez no cara, e querem
mudar o nome Por alguma razão, talvez o videogame agora tenha um
nome diferente. Vamos pedir ao usuário um novo nome para este
jogo aqui, Game One. E eles vão digitar
algo no sistema. Digamos, por exemplo, que pedimos a eles um novo nome, podemos definir isso usando
o nome da variável aqui. Talvez eles acidentalmente tenham
pressionado G no teclado e
depois pressionado Enter O que estamos fazendo aqui é apenas passar entrada
deles para essa
variável.
Não tem problema nenhum. Continuaremos com nosso dia. No entanto, talvez isso não
seja uma boa ideia. Talvez queiramos validar
essa entrada primeiro. Talvez queiramos ter certeza de que o nome do jogo tenha
pelo menos dois caracteres ou não
contenha caracteres numéricos
ou algo parecido Talvez precisemos fazer alguma
verificação. É aqui que
as propriedades C sharp podem entrar. Nesse cenário específico, há muitos motivos para
usar as propriedades C sharp, mas esse é apenas um exemplo que
veremos. Agora, o que eu poderia
fazer nesse caso é que, em vez de definir a variável
name diretamente, eu posso criar um método
aqui chamado update name. E isso pode receber nosso
novo nome do usuário. O que ele pode fazer, ele pode fazer
várias verificações de validação. Pode dizer, ok, o novo nome
é menor ou
igual a um caractere? Nesse caso, não podemos atualizar o nome e podemos fazer qualquer
outra validação do nome. E, finalmente, podemos
realmente atualizar o nome. Por exemplo, o que
posso fazer aqui é dizer, primeiro
jogo para atualizar o nome. Agora, em vez de
definir uma variável, posso usar um método. Para conseguir
isso, eu passo nosso novo nome potencial
que o usuário nos dá. Então, esse método
retornará verdadeiro se puder ou
falso se não puder. E então atualize o interno em uma variável de nome aqui
internamente na classe E isso é perfeitamente aceitável vez de usar um
método nesse caso, porque o que pode
acontecer é que talvez precisemos um método para
atualizar o editor ou de outro
método para atualizar a classificação. Mas agora estamos usando métodos para atualizar o nome, por exemplo. Bem, ainda podemos
acessar o nome em si, então precisamos restringir o acesso
ao nome porque queremos apenas atualizar o campo de nome usando nosso
novo método, atualizar nome. Então, é essencialmente aqui que entram as propriedades
C sharp. E o princípio de tornar variáveis
locais apenas para uma
classe privadas, você pode ver em nossa classe aqui que
temos todas essas
variáveis,
aqui temos três públicas
e uma privada. Examinamos um exemplo e vou
dizer agora que é prática
comum tornar privadas todas as suas variáveis dentro
das classes. Isso significa que ninguém
fora da classe pode modificar essas variáveis de
forma alguma. Se eu acessar o jogo, um objeto. Agora não consigo acessar
o nome diretamente. Não consigo acessar a
variável do editor, nada. A única maneira de acessar ou atualizar o nome é usando
nosso método de atualização. E é exatamente isso que queremos porque quando o usuário
digita alguma entrada aqui, queremos que ela
passe pela validação. Queremos ter
certeza de que o nome tenha pelo
menos tantas letras ou, você sabe, várias outras coisas. E então queremos
finalmente atualizá-lo. Portanto, esse método aqui é uma solução aceitável
sobre como fazer isso. E isso impõe que todas as nossas variáveis aqui sejam privadas porque
são sensíveis Não queremos que outras
pessoas, você sabe, acessem e coloquem
quaisquer valores antigos, e isso impõe o encapsulamento,
bem como o princípio do Core 00 Mas e se eu te dissesse que há uma maneira mais fácil de
fazer esse método? Não precisamos escrever
um método como esse para cada vez
que atualizamos uma variável. Talvez haja outra maneira. É aqui que entram
as propriedades C sharp. Então, vou criar
uma nova propriedade C Sharp. Agora, quando criamos uma propriedade, damos a ela um modificador de acesso Vou chamá-lo de
público porque quero que todos acessem
nosso campo de nome. Então, o nome é uma string. Como você pode ver aqui,
o nome é uma string, então eu tenho que dar um nome a ele. Agora, ao criar
propriedades e variáveis, por exemplo, elas
também são conhecidas como campos. Os campos em si geralmente e normalmente são
todos minúsculos. Você pode ver todos
esses casos aqui. As propriedades em si
só têm uma primeira letra
maiúscula. Se as variáveis
aqui tiverem duas palavras, então seria
algo parecido com isso. Caixa de título, por exemplo, sem os espaços em branco. Essa é uma prática comum. Os campos locais aqui, as variáveis locais em
minúsculas e as propriedades são sempre
capitalizadas no início Isso é apenas uma boa prática. Depois de fazer isso,
vou mostrar a você uma propriedade
C sharp em sua forma básica agora. Sempre que quisermos atualizar
o nome do campo privado, examinamos essa
propriedade aqui, assim como quando falei
sobre o exemplo Sempre que quisermos
atualizar o campo de nome, usamos esse método Bem, em vez de usar
esse método aqui, vamos usar essa propriedade C
sharp. Sempre que quisermos acessar
essa variável local aqui, sempre
usaremos
nossa propriedade em vez disso Considere isso como um acessador
para nossa variável local aqui. Para que a variável realmente obtenha o valor dela,
ela a retornará
usando a palavra-chave return. Sempre que quisermos definir um valor, a
variável local será
igual a essa palavra-chave especial
aqui chamada valor Esse é o valor que está sendo
passado para isso. Vamos dar uma olhada em um exemplo
disso agora. Se entrarmos em nossa classe
principal aqui, vez de usar esse
método aqui em nosso exemplo, o que eu quero fazer é
dizer o nome do jogo um. Esta é a
propriedade da nossa loja aqui. Então, podemos realmente dar a isso
um valor como, por exemplo. Agora, o que está acontecendo aqui estamos usando o nome da propriedade, mas internamente
dentro dessa classe, ela está realmente entrando aqui
e definindo o valor Esta seção está aqui
dentro desta declaração Get. É aqui que queremos
fazer essa validação. Vamos copiar tudo
isso aqui, depois vamos colocar esses
colchetes em uma nova linha Vamos deletar isso por enquanto. O que estamos fazendo aqui é que sempre que definimos essa propriedade shot, essa instrução set é chamada Você pode ver aqui quando usamos um sinal de igual com um novo
valor nesta propriedade da loja, internamente nesse bloco definido, internamente nesse bloco definido,
tudo isso é executado
no final disso, só
queremos definir nossa variável
local aqui,
nome, para qualquer
valor passado Esse
valor mágico de palavra-chave sobre o qual eu estava falando será igual a
esse valor aqui, o que quer que esteja sendo atribuído. Sempre que essa
propriedade aqui é definida, que é o que estamos fazendo,
estamos configurando para, então estamos fazendo toda
essa validação aqui. Precisamos usar o valor
mágico da palavra-chave, que é o valor que estamos
realmente verificando. Isso faria exatamente o mesmo que esse método aqui. valor apenas substitui o
nome nesta instância, vamos dar uma
olhada e
examiná-lo mais uma vez Estamos atribuindo um valor ao
nome da propriedade da loja aqui. Agora, o valor será igual a, seja, pode ser qualquer coisa. Isso realmente
não importa. Então, o fluxo de
execução entra aqui, e esse método set é chamado porque estamos
definindo um valor, essa palavra-chave mágica aqui. O valor será igual porque esse é o
valor que está sendo passado. Agora estamos verificando
se o tamanho
do nome do usuário é
menor ou igual a um. Se for, bem, não
podemos atualizá-lo,
então, boa sorte, fazemos qualquer outra validação,
seja ela qual for. Se finalmente pudermos atualizá-lo
, definiremos o nome da
nossa variável privada, que é o valor
que está sendo passado. Essa é a mágica de usar uma propriedade de loja e
a palavra-chave set aqui, não
precisamos de um método
totalmente novo. Para fazer isso, podemos usar a
funcionalidade embutida A principal conclusão disso é que as propriedades
da loja controlam o acesso
a informações confidenciais E esses itens são todos os nossos campos locais. Aqui,
todos são considerados informações
confidenciais. Não queremos que os usuários simplesmente
coloquem valores antigos aqui. Talvez queiramos alguma
validação para garantir, você sabe, que os valores
transmitidos sejam precisos. Você sabe que eles são válidos ou
por qualquer outro motivo. E então, quando finalmente existirem, poderemos atualizar nossas variáveis
privadas sensíveis e preciosas nesse caso. Portanto, essa é a vantagem de
usar propriedades C sharp. Falamos sobre a
palavra-chave set bastante extensivamente. Vamos abordar a palavra-chave
get bem rápido. Na verdade, a palavra-chave
get obtém o valor da nossa variável
privada. Novamente, podemos fazer várias coisas ao longo do caminho antes de
finalmente devolvê-lo. Podemos fazer o que quisermos aqui, assim como na
palavra-chave set aqui, podemos fazer o que quisermos. Mas, no final das contas, finalmente
vamos devolvê-lo daqui. O que podemos fazer aqui,
vamos enviar o nome
do jogo aqui para a janela
do console. Quando essa linha é executada aqui, enviamos apenas o nome do jogo
um para a janela Então você pode ver aqui. Então, o que acontece
internamente é quando
realmente obtemos esse valor, então o que queremos fazer é
obter o nome do jogo Internamente, esse
bloco get está sendo chamado. Podemos fazer o que
quisermos aqui, qualquer verificação, qualquer validação que possamos
registrar em um banco de dados ou arquivo. E então podemos finalmente retornar nossas informações confidenciais aqui, o campo privado daqui e depois para a janela. Você pode ver a palavra-chave get, neste caso controla a obtenção de nossa variável
local aqui. Da mesma forma, a palavra-chave set
controla a inicialização de
um valor em nosso precioso campo
local confidencial aqui E, novamente, é sempre uma
boa prática ter uma propriedade C sharp para cada um dos seus campos
privados aqui. E, por padrão, você deve
sempre tornar seus campos locais privados, a menos que haja alguma circunstância
atenuante ou motivo especial Uma das outras
coisas que podemos fazer com propriedades
C sharp é torná-las somente
para leitura. O que quero dizer com isso
é que o usuário pode acessar as variáveis
privadas, mas não pode inicializá-las, não pode dar a elas nenhum valor Por exemplo, digamos que,
no campo do editor, queremos torná-lo
somente para leitura. O que eu quero dizer com isso? Por exemplo, digamos que,
se eu quiser obter o editor
de qualquer um desses objetos do jogo, eu usaria o editor do Game One. E isso seria como ler somente eu posso acessar
as informações. Mas quando eu realmente
tento definir os dados, por exemplo, definindo o
nome, não consigo fazer isso. Não vai me deixar, como
faço para fazer isso? Talvez seja uma coisa útil. O que podemos fazer aqui é criar uma nova propriedade para
nosso editor. Novamente, temos nosso formato
familiar, usamos letras maiúsculas
apenas por boas práticas. Então, o Visual Studio está
nos ajudando , sugerindo o que talvez
queiramos fazer Isso é ótimo, vou usá-los. Veja como fazer com que uma
propriedade seja somente para leitura. Sim, simplesmente não definimos
uma palavra-chave definida. Só tenho uma chance de entrar aqui. Agora, você não pode ter
um conjunto sozinho, você sempre precisa de um. Mas você pode ter apenas um get
que o torne somente para leitura. Vamos dar uma
olhada nesse exemplo. Agora, se quisermos exibir o
editor na tela,
podemos simplesmente fazer isso. Podemos exibir o
editor na tela. Não tem problema algum
, vai funcionar. Se eu tentar realmente
definir um valor aqui, quero atualizar esse
editor para qualquer coisa, na verdade. Você pode ver que há um erro
aqui, há uma linha vermelha. Se eu passar o mouse sobre isso,
você pode ver aqui propriedade ou o indexador
não podem ser atribuídos, eles são
somente para leitura Isso é porque, na verdade, não
definimos uma palavra-chave definida aqui. Não há um setter, não podemos
realmente definir um valor aqui. Isso é muito útil se você tiver algum campo confidencial aqui onde deseja apenas acesso de leitura. Talvez queiramos ler
nosso campo de ID aqui, mas não queremos que o usuário o
defina, por exemplo. Então, teríamos algo assim, em que forneceríamos apenas acesso de
leitura às nossas
variáveis locais aqui. Outra coisa que
podemos até mesmo fazer é adicionar modificadores de
acesso às
nossas e definir palavras-chave Aqui temos nosso nome aqui, queremos que todos
recebam o nome. Mas, no entanto, talvez queiramos tornar esse cenário
privado. Somente coisas dentro da nossa classe
aqui podem realmente fazer isso. O que podemos fazer aqui é
tornar o setter privado. E isso significa que se tentarmos definir esse valor de nome aqui de
qualquer lugar fora dessa classe, ele não vai virar letras. Então, se eu for para o arquivo
principal aqui, o que estou fazendo é
tentar inicializar o nome como um valor.
Eu passo o mouse sobre isso Você pode ver que ele não pode ser usado
nesse contexto porque o
acessório definido está inacessível Na verdade, não podemos configurá-lo de qualquer lugar fora dessa classe. Assim que eu remover isso, você verá que o erro desaparece e podemos definir o
nome novamente. As propriedades nítidas são,
na verdade, muito poderosas, acabamos de abordá-las, mas acho que isso
será suficiente para você
começar a se
esforçar para usá-las O que você deve
tirar disso é que as propriedades em C Sharp controlam
o acesso usando getters e setters aos
seus campos privados, que fazem parte de
suas classes em C Sharp Obrigado por assistir.
43. 9-6. Herança: Ok, herança em C Sharp. Você pode ter ouvido
a palavra antes, talvez não a tenha ouvido, mas vou
explicá-la agora. Então, o que é herança
em C Sharp? Basicamente, o
princípio fundamental da herança é aumentar a reutilização do código E isso é muito importante mesmo em termos de programação
orientada a objetos,
não em termos de programação orientada a objetos O problema é que, se copiarmos
e duplicarmos o código
, nosso software
acabará sendo muito
difícil de manter Ele terá
um tamanho de arquivo grande e você
terá muitos problemas. Sempre, sempre reutilize o
código sempre que possível. Vamos dar uma olhada em um exemplo de
herança em C Então, o que eu tenho aqui é um aplicativo
muito básico. Eu criei um novo objeto animal e tenho uma
classe de animais para isso. Vamos dar uma olhada
na classe de animais. Então, aqui está minha aula de animais. Tem dois campos privados
aqui, nome e idade. Então, o nome do
animal pode ser Rocky, e a idade de Rocky pode ser sete, como Rocky pode ser
um cachorro Eu tenho dois
métodos básicos aqui que apenas ecoam o nome
do animal janela
do console
e também outro método aqui que reflete
a idade do Eu tenho duas propriedades comerciais aqui, duas propriedades públicas que permitem controle sobre meus
campos privados aqui, nome e idade. Portanto, é uma aula muito simples. Eu criei um objeto
animal aqui. Eu defini o nome de propriedade
e era rochosa para sete. Agora, estou apenas usando esses
métodos aqui que apenas refletem esses valores na tela
se executarmos o aplicativo Agora você pode ver
que é muito simples. Meu nome é Rocky,
tenho sete anos. Então, essa é uma classe básica de
animais lá. Agora, digamos que eu
queira expandir meu aplicativo. Talvez eu queira um
software onde eu possa
criar um zoológico de animais. Talvez eu queira uma aula de cães, aula de
ratos, uma aula de gatos,
uma aula de hamsters Talvez eu queira talvez
20 classes e cada uma representando um
animal à sua maneira. Se viermos aqui agora, podemos clicar com
o botão direito do mouse no projeto aqui e adicionar uma nova turma. E digamos que queremos
criar uma classe de cães. Essa aula terá
tudo a ver com um cachorro. Por exemplo, talvez
o zoológico tenha centenas de cães e queiramos gerenciar nossos cães em sua
própria classe de cães. É perfeitamente razoável. Novamente, podemos
ter uma aula de gatos, uma aula de hamsters, muitas coisas Mas o que queremos, nossa classe de cães, queremos toda
essa funcionalidade aqui dessa classe de animais, porque nosso cachorro terá um
nome, terá uma idade. Mas talvez tenha
outras coisas, como talvez alguns métodos relacionados
à escavação E nem todos os animais sabem cavar, por exemplo, talvez algo
específico para um cachorro. Mas queremos essa funcionalidade
principal. Nosso cachorro vai
ter um nome e uma idade. Eu quero todas essas coisas e vou colocar
isso na minha aula de cães. Então, agora eu posso
meio que construir sobre isso. Posso adicionar alguns métodos
para, você sabe, o cachorro cavar ou implorar por guloseimas,
ou talvez certos truques para cães Mas o problema é que copiamos toda essa funcionalidade principal que
funcionará, sem problemas Mas o problema é que quando
eu tenho outra aula, talvez uma aula de gatos ou
uma aula de porquinhos-da-índia, novamente, eu quero que eles tenham essa funcionalidade básica também E o problema é que vou
ter todas essas informações em cerca de 20 classes diferentes e vai ser muito
difícil mantê-las. E não só isso,
vai aumentar, como eu disse antes, o
tamanho do arquivo no aplicativo. Como podemos contornar
esse problema aqui? Nossa loja tem algo que podemos utilizar e isso se
chama herança Herança em C Sharp, é muito fácil de começar, mas talvez seja mais
complexo de dominar Mas vamos começar e dar
uma olhada em como podemos fazer isso. Não precisamos de nenhuma dessas
funcionalidades em nossa classe. O que podemos fazer é herdar a funcionalidade
da classe animal Toda essa lata de coisas aqui, todas as coisas públicas de qualquer maneira. E podemos ir para nossa aula de cães
e usar dois pontos e depois digitar a
classe da qual queremos
herdar as características Nesse caso, será
animal apenas fazendo isso. Um pequeno
trecho de código aqui. Agora, nossa classe de
cães
conhece todos os métodos públicos aqui e quaisquer propriedades públicas que
possamos ter nesta classe. Vamos dar uma olhada em um exemplo. No momento, você pode ver que nossa aula de
cães está perfeitamente vazia. Nossa classe de animais
tem toda essa lógica. Vamos criar um novo
objeto para um cachorro e ver se podemos
realmente usar algumas
dessas propriedades e
métodos aqui. Vamos criar um novo
objeto para um cachorro. Vou chamá-lo de Do.
Podemos definir o nome do cachorro. Bingo, por que não a idade do cachorro? Podemos configurá-lo para
três, por exemplo. Vou apenas renomeá-los. Você pode ver aqui que
não há linhas vermelhas sob
essas propriedades. Não há erros ao
usar esses métodos. Podemos até mesmo executar o
aplicativo, sem problemas. E agora, olha, meu nome é Bingo. Eu tenho três anos de idade. Você pode ver aqui que o cão
herdou toda a
funcionalidade do animal, todos os métodos
e propriedades públicos do animal Você pode ver que aqui está a aula de
cães aqui. Está totalmente vazio. Mas você pode ver que estamos
reutilizando todo esse código aqui , o que é muito
eficiente e esse é o ponto da herança Neste exemplo aqui, dizemos que animal é
a classe dos pais, como você tem um
pai e um filho, que a criança pode herdar
a capacidade de respirar, sangrar
ou comer
coisas em seu DNA É daí que vem a
terminologia. O animal, nesse caso, seria o pai e o cachorro
a criança. Mas alguns outros sinônimos
para isso
seriam a classe base
ou a superclasse cão seria a criança, a classe derivada
ou a subclasse Eles são todos sinônimos, mas basicamente significam o
mesmo tipo de coisa. Ao considerar a
herança em C Sharp, você deve considerar uma coisa, um pensamento que deve estar
passando pela sua cabeça, que é um cachorro, um animal é
um Um animal é um rato, um animal. Se sim, então a herança
é perfeita para você. E você não está
entendendo mal o conceito. Sempre considere quando você está
herdando em uma loja se
é um relacionamento A herança é um assunto muito
longo. Mas
vou explicar outra coisa para que
fique absolutamente claro
o que vou fazer. Vou definir
um método dentro nossa classe de cães que
é exclusivo para cães. Eu quero que seja, talvez
latir, por exemplo. Como todos os cães latem, deixe-me criar um método
em que o cachorro latiria. Então você pode ver que eu criei
um método aqui chamado bark. E tudo o que ele faz é
gravar na janela do console. Uau, uau. Então, muito simples. E assim como nos
humanos, se você tem um, você pode herdar coisas
ao nascer, como mencionei antes Mas os pais não podem
herdar da criança. Por exemplo, se a criança tem uma nova habilidade, como
latir, por exemplo
, o animal
não tem conhecimento disso Assim como em um relacionamento entre pais e
filhos, se seu filho tiver uma nova habilidade, talvez tenha se tornado um artista. Isso não significa que os
pais sejam artistas. Você sabe, herança
não funciona dessa forma. Então, deixe-me mostrar um
exemplo disso agora. Então, definimos um método
na classe dog chamado bark. Se eu for ao nosso
programa principal de canhões aqui, se eu colocar um pequeno ponto
após o animal aqui, você verá que o animal não tem
conhecimento do método do latido Nem mesmo está nessa
lista o que se espera. No entanto, se formos até o
cachorro aqui e digitarmos, temos nosso método que
acabamos de criar chamado latido? Podemos executar o aplicativo
agora, você pode ver que pode. Então o cachorro está latindo e então estamos apenas ecoando o nome e
a idade do Esse é um exemplo muito básico
de herança em uma loja.
44. 9-7. Substituição de métodos (polimorfismo): Método OK em vez de andar de bicicleta. Se você ainda não viu o
tutorial anterior sobre herança, sugiro que
assista, pois é do
que eu tenho
aqui Eu tenho uma aula básica de animais. Estamos dando à
classe animal um nome e uma idade. Agora eu tenho uma aula de cães. E, novamente, o cachorro
tem nome e idade e também uma
classe de gatos aqui. E eles fazem várias
coisas com o animal. Estou dizendo o nome da
idade e fazendo barulho o mesmo para o cachorro
e o mesmo para o gato. Se eu for para minha aula de animais aqui, teremos as coisas usuais, os métodos
do último tutorial. Mas também temos mais um método aqui chamado fazer barulho. Tudo o que ele faz é
ecoar algo na tela que diz que faz ruídos
aleatórios de animais Eu tenho uma classe de cães que
herda de animais. Ela herda todas as
funcionalidades públicas que
definimos para ela. E uma classe de gatos que também herda dos animais,
mas eles não fazem nada As aulas de cães e gatos não estão
fazendo nada. No momento, se executarmos o programa, você pode ver aqui,
meu nome é Henry. Eu tenho cinco anos. Faz ruídos aleatórios de animais. E faz o mesmo com o gato. O que estamos fazendo aqui é herdar toda
essa funcionalidade Mas você pode ver, em
particular, que estamos herdando esse método
aqui chamado make Noise Agora isso faz parte da classe
animal, por exemplo, podemos não saber que
tipo de animal temos, só
temos um
animal genérico chamado Henry. No entanto, na minha aula de cães, bem, eu sei que os cães latem. Por exemplo, S, eu
gostaria que Lassie tocasse um bar. Não quero que Lassie
faça barulhos aleatórios de animais. mesmo acontece com a
aula de gatos. Temos Felix Eu gostaria que o
gato, por exemplo, fizesse isso facilmente definindo um novo método aqui chamado
latir na classe dog. Então, na classe cat, posso definir um método
chamado make noise ou per, meow ou algo parecido,
que é exclusivo de um gato Mas o que podemos realmente fazer é substituir esse método
aqui chamado fazer barulho Isso significa que podemos herdar essa
funcionalidade de ruído Mas não vai fazer
isso, vai fazer outra coisa. Isso é outra coisa que podemos
definir em nossa classe infantil. Por exemplo, a classe de cães. Como podemos substituir esse método? Como herdamos
isso e o substituímos? Bem, na
aula infantil aqui, cachorro, já
estamos
herdando o método porque estamos fazendo ruídos
aleatórios de animais Mas queremos que o cachorro late. Então, como fazemos isso? O que temos que fazer na classe principal,
então, neste caso animal, precisamos tornar o método o
que é chamado de virtual. E o que é isso, é uma
nova palavra-chave chamada virtual. E isso apenas diz, ok, qualquer pessoa que herde essa classe, você pode dar sua
própria definição para esse método, se
quiser. A escolha é sua. Você não precisa agora. Eu nem estou fazendo isso. Eu executo o programa, estou herdando
toda essa funcionalidade. Virtual é basicamente
dizer, ok, existe
a opção de
redefinir seu próprio conteúdo Para esse método, é opcional, você não precisa.
Isso é virtual. Mas o que queremos fazer, sim, na verdade queremos
nossa própria funcionalidade. Por exemplo, nesta aula
infantil aqui, faça o que eu quero
fazer ao chamar o método make
noise aqui. Eu quero latir. Eu
quero que o cachorro late. Para fazer isso, eu digo
latir ou gritar, ou talvez ambos. Por que não? Copiei
esse método acima, mas não colocamos o virtual aqui Usamos uma nova palavra-chave
chamada override. E isso é novamente uma palavra-chave
especial. Na classe base, a classe principal, usamos
a palavra-chave virtual. Na classe secundária, usamos a palavra-chave override Isso é basicamente dizer, ok, estou herdando esse método
do animal da classe parental, mas quero minha própria definição Quero ignorar sua lógica
canônica e colocar minha própria alternativa sempre na
classe infantil,
neste caso, neste caso Na classe base, temos que
configurá-la como virtual. Se não colocarmos o virtual
, não poderemos substituí-lo Eles andam juntos como um
par em nossa aula de gatos. Bem, eu quero o gato para mim agora Por exemplo, é tão simples quanto se eu
executasse o aplicativo. Agora você pode ver aqui que
meu nome é Henry. Agora Henry é um animal genérico. Ele não é um cachorro ou
não é um gato. Henry faz ruídos aleatórios de
animais. No entanto, Lassie
or Less é um cachorro. Quando chamamos o método de fazer
barulho aqui para o cachorro, então o cachorro vai
latir e gritar Bem, o gato
não fará ruídos
aleatórios de animais porque a classe cat também substitui
o Faça barulho e o
gato está miando. Você pode ver que esse é um exemplo
bastante básico de como podemos reutilizar
esse método aqui, fazer barulho definido
em nossa classe mãe, mas dar nossa própria
definição a ele Isso está reutilizando o
código existente, como esse método aqui. Mas não queremos essa
funcionalidade, queremos a nossa. O processo de definir
nossa própria definição é um exemplo do que se
chama polimorfismo O que é isso? É
uma palavra grega que significa muitas formas ou muitas formas. Mas é um princípio fundamental da programação orientada a
objetos. Então você esteve
fazendo um exemplo de polimorfismo esse tempo todo,
talvez Mas esse é o princípio fundamental
da programação 00 e é muito importante, como
você já viu. Isso é obtido por meio de
herança e reutilização de código. Mas não só isso, mas fornecendo sua própria
definição para algo. Então isso é polimorfismo. Portanto, este é um exemplo de substituição de
método em C sharp.
45. 9-8. Herança multinível: Ok, herança em vários níveis. Se você ainda não assistiu aos tutoriais
anteriores
sobre herança, eu recomendo fortemente que você
os assista agora, pois eles seguem essa herança
de vários níveis Então, vamos ver um
exemplo aqui. Aqui eu tenho uma aula de animais, aqui está aqui. Ele define algumas
coisas básicas para fazer com animais, especialmente esse método
aqui de fazer barulho. Agora, esse método é virtual, o que significa que qualquer classe filha
desse animal da classe base pode opcionalmente, definir seu próprio
conteúdo para esse método Ok, nós conversamos sobre isso, agora temos duas novas classes. Um chamado carnívoro e sua classe parental é animal
e outro chamado O carnívoro é como
comer carne e um herbívoro se alimenta de plantas e um herbívoro é um
animal Então, isso satisfaz esse
tipo de relacionamento. E o herbívoro
substitui o método do animal da classe parental e define sua própria funcionalidade, ou seja, sou herbívoro
, emito ruídos de comer plantas, e o mesmo acontece
com o carnívoro comer plantas, e o mesmo acontece
com define sua própria funcionalidade, ou seja, sou herbívoro
, emito ruídos de comer plantas, e o mesmo acontece
com o carnívoro. Ele está substituindo
o método virtual e definindo seu próprio código Sou carnívoro e faço barulhos de comer
carne. Está bem? Se criarmos
um objeto carnívoro ou herbívoro
e executarmos esse método, obteremos Agora, gato e cachorro. Agora, o gato é um carnívoro. O cachorro também é carnívoro. Você pode ver que o que está
acontecendo aqui é que o cachorro é quase como o
neto de um animal A aula de
carnívoros fica entre cachorro e animal. A classe base aqui é
animal, depois animais, criança é o carnívoro, então o filho do
carnívoro Esse é um exemplo de herança em
vários níveis. Temos uma hierarquia aqui. Temos o neto, o cachorro. O pai é o carnívoro. O avô seria
o animal, por exemplo. Há várias camadas
de herança aqui, você pode fazer isso perfeitamente em
C sharp Isso é só um exemplo. Você pode ver aqui que o cão também substitui o
método de fazer barulho Está latindo, uau. Então, vamos dar uma
olhada em um exemplo. Aqui estou criando um novo animal, que é a classe base,
como o avô Estou criando um novo cachorro que é como o neto e um novo gato, e então estou chamando o método de fazer barulho em cada um deles Eu não tenho um objeto carnívoro. Eu não tenho um objeto herbívoro. Vamos executar o aplicativo aqui. Faz ruídos aleatórios de animais porque não sabemos
qual animal é Henry Isso é o que definimos então. Cachorro e gato têm suas próprias
definições para fazer barulho. Bark, wolf e O, o que acontece se eu remover
esse método aqui do cachorro? O que acontece? Estou
herdando um carnívoro Estou herdando um animal
como o avô desse? Bem, vou te mostrar agora que ele herda a classe principal, então você pode ver agora que eu não tenho um método chamado
fazer barulho em cães Quando o cachorro faz barulho, ele olha para a classe dos pais
e, nesse caso, é carnívoro Na verdade, o Carnivore está
substituindo fazer barulho e dando sua própria definição
quando executamos Este é Henry, o animal
aleatório Noise. Vamos colocar isso
em vista aqui. Esse é Henry, esse é o cachorro. Porque a classe de cães
agora não está se sobrepondo a isso. Agora ele salta para seu progenitor, que é um carnívoro
que o substitui Agora o cachorro está dizendo: eu sou um carnívoro, faz barulho de comer
carne, e o gato ainda tem seu próprio método anulado definido para que o Mas esse é um exemplo muito
básico de herança
multinível em C Sharp e como
podemos utilizá-la Quantas camadas de
herança você pode ter? Quão grande pode construir essa árvore
genealógica animal, por exemplo? Bem, não há um limite
real definido, mas ao criar software, você não quer torná-lo
absolutamente ridículo Talvez 234 níveis dependam do
tamanho do seu aplicativo Então, tendo dez ou 50
níveis de herança, não
consigo pensar em
um exemplo de por que você gostaria
de fazer isso Mas o objetivo deste
tutorial é apenas mostrar que isso é possível
e, você sabe que é, as pessoas o usam no mundo real. Há um outro tipo de herança, que é
chamado de herança múltipla É aí que uma classe, por exemplo, como o gato, pode herdar não
apenas, por exemplo, de um
animal, mas talvez de
algo como felino ou Então, duas aulas. Agora, o shop
não oferece suporte nativo para isso, mas isso pode ser obtido
por meio de interfaces, que discutiremos
em um tutorial posterior Portanto, existem diferentes
layouts para herança, mas esse é apenas um exemplo
de herança multicamada Então, posso começar com você? Espero que este tutorial tenha ajudado
você a considerar muitas
das possibilidades de
herança na loja.
46. 9-9. A palavra-chave selada: Eu quero falar sobre a palavra-chave selada na loja
e ela tem a seguinte aparência. A palavra-chave selada é bastante
útil para restringir a herança no nível da classe.
O que isso significa? Aqui eu tenho um exemplo de
herança de vários níveis na loja C. Eu tenho uma aula de jogos que é como a mãe, por exemplo. Eu tenho um videogame,
que é a criança. E então eu tenho Super Mario, que é o neto Então, parece algo assim. Então, aqui está o jogo da classe básica. Ele só tem um método
que diz o que é legal e está marcado como virtual. Isso significa que qualquer classe
secundária disso pode optar por substituir esse
método, se quiser Então, abaixo do jogo de classe
base, tenho um chamado videogame
que
herda do jogo e
substitui esse método Mas em vez de dizer que
o jogo é legal, está dizendo que esse
videogame é legal. Então eu tenho a classe de
netos
neste aplicativo que é
herdada do videogame Ele também está substituindo o método
what is call. Agora diz que Super Mario está pronto. Se eu olhar para este
aplicativo aqui onde eu
configuro três objetos e
apenas chamo esses métodos, ele só vai gerar os resultados desses métodos, ou
seja, polimorfismo O que posso fazer com
a palavra-chave selada é, na verdade, restringir a
herança em uma classe O videogame é como o
recheio desse sanduíche. Seu pai é um jogo, mas seu filho é Super Mario. Então, por exemplo, se eu disser que
essa era uma classe selada, isso significa que nenhuma outra classe
pode herdar dessa classe, então ela não pode ter
mais filhos Imagine que talvez seja
uma fasectomia ou
algo parecido uma fasectomia ou No entanto, você deve
tentar lembrar que agora, se eu for para
a aula infantil, você pode ver que agora
há um problema. Super Mario não pode derivar de videogame de classe
selada porque videogame não pode ter
mais filhos. Está selado. Isso evita a herança
em nível de classe aqui, o que quero dizer em nível de classe Isso significa apenas
nesta linha aqui. No entanto, também podemos
usá-lo no nível do método. E isso restringe qualquer
herança adicional em um método,
não em toda a classe, mas apenas Como regra geral, não podemos colocar isso na
classe básica, nunca
podemos colocar isso na classe principal,
a mãe definitiva O que faríamos é definir um método aqui chamado
what is cool. Nós o marcamos como virtual. Quando algo é
marcado como virtual, isso significa que a
classe filha pode fornecer sua própria definição
substituindo o método Já fizemos isso antes. Agora vou até a criança imediata, que é o videogame. Estou ignorando esse
método, certo? É a primeira
vez que estamos substituindo esse método porque é
o filho imediato É aqui que posso
usar a palavra-chave selada. Você só pode usar
selado com substituição. Você não pode usá-lo com o virtual. Tem que estar pelo menos
um nível abaixo. Agora estou restringindo qualquer acesso
adicional a esse método. O que é legal agora, a
pobre classe Super Mario é que ela não pode mais usar esse
método. Você pode ver. Portanto, não pode substituir o membro
herdado, o que é chamado
porque está selado O uso da
palavra-chave selada impede, no nível da
classe, qualquer
herança adicional da própria classe E um nível de método evita qualquer outra
anulação do método, desde
que o método
esteja marcado como selado Então esse é o poder da palavra-chave
selada em C Sharp.
47. 9-10. Aulas abstratas e métodos abstratos: Vamos falar sobre
classes abstratas e métodos abstratos. O que eles são? Por que
devemos usá-los? Vamos dar uma olhada
neste exemplo aqui, seguindo o exemplo anterior. Se você ainda não viu
os outros tutoriais, eu recomendo fortemente que você
os assista porque eles
seguem um desses Temos nossa classe base aqui, animal, e estamos apenas
criando um animal chamado Henry. Temos nosso cachorro que
herda do animal
e, novamente, um gato que
herda do E estamos apenas ecoando
o nome do animal, do cachorro e do gato Aqui está nossa aula de animais.
Não está fazendo muita coisa. Temos três métodos. Marcamos, fazemos barulho, dizemos idade e dizemos
nome. Tudo como virtual. Se as turmas infantis quiserem
substituí-las, elas podem fazê-lo. Agora estamos substituindo o mesmo nome. Se obtivermos o
nome do cachorro, está dizendo:
oh, meu nome é então o nome do cachorro e
depois uau no final E o mesmo com o gato.
Não está acontecendo muita coisa. Na verdade, não
construímos muito sobre isso. Executamos o programa,
é isso que você pode
ver, por exemplo. É bem normal. Agora imagine que você tem um software muito
grande. Você tem outras dez pessoas
trabalhando no software e quer uma aula
para cada animal. Você está imitando um
zoológico, por exemplo. Você está criando um
software para zoológico ou até mesmo um jogo de Pokémon E você quer uma classe para cada
personagem ou cada animal. Você poderia ter uma pessoa em sua equipe criando
todas essas classes, mas em equipes de talvez
dez ou 100 pessoas, você vai
delegar isso Você não será
o único a criar essas classes. Nessas aulas, temos uma que diz “faça barulho” e
que está latindo e uivando Temos um que
diz diga o nome e está dizendo o
nome do animal, por exemplo, o cachorro aqui. E o cachorro grita depois de repetir nome.
O mesmo com o gato. Mas e se nosso colega de equipe Randy, por exemplo, estiver
criando uma aula de hamster Talvez ele se esqueça de
ignorar esse método. Ele se lembrou de dizer o nome, mas talvez tenha esquecido de
fazer barulho quando
o aplicativo é executado, em vez ignorar fazer barulho e
ele está emitindo sons de hamster Isso só
fará com que a classe padrão pareça soar aqui, ruídos
aleatórios de animais Então, como podemos dizer ao
Randy, nosso amigo, que você esqueceu de
ignorar esse método, fazer barulho, que seus hamsters
não fazem barulho de hamster Bem, podemos realmente impor isso em nosso animal de classe parental O que podemos fazer em animais dizer, ok, vou redigir
um contrato e dizer qualquer classe que herde
essa classe tem que substituir,
digamos, esses três métodos Caso contrário, o software
nem mesmo compilará. Não podemos nem mesmo executar o software que garante que
nosso amigo Randy,
por exemplo, substitua os métodos queremos que nosso amigo
Randy Podemos introduzir algo
chamado classes abstratas. Para conseguir isso, o que as classes
abstratas fazem? Imagine que tudo bem, se eu quiser uma classe abstrata
e um método abstrato, qualquer classe que
herde essa classe aqui tem que substituir
esses Eles precisam especificar
uma definição. Se esse for um método abstrato pertencente a uma classe abstrata, se Randy, nosso amigo, criar uma classe Hamster
, o software
nem será executado Se ele não fornecer sua própria definição para esses métodos, essa é a vantagem de uma classe abstrata e de
um método abstrato. Eu vou te mostrar
como configurar isso. Agora, a primeira coisa que
fazemos para configurar uma classe abstrata é
marcar a classe como abstrata. Isso é tão simples quanto escrever a
palavra-chave abstrata lá. Isso faz algumas coisas. Depois de marcarmos uma
classe como abstrata, não
podemos mais criar um
objeto a partir dessa classe. O que isso significa? Se
formos ao programa aqui, você pode ver que estamos criando um objeto animal
aqui chamado Henry. Agora não sabemos
qual animal é Henry, ele acabou de ser usado
em nosso exemplo. Mas você pode ver aqui
agora que há uma linha vermelha abaixo dessa nova linha de
instância aqui Quando eu passo o mouse sobre isso, ele diz possível criar uma instância
do tipo abstrato ou animal de
interface Isso porque, se você marcar
qualquer classe como abstrata, não
poderá mais criar
uma instância dessa classe. Agora, Henry, vamos
ter
que decidir que tipo de animal
Henry é neste momento. Ele é um cachorro, um hamster, um gato ou outra coisa. Mas agora marcamos essa classe de
animais como abstrata. Não podemos criar uma
instância de animal. Henry vai ter que ir e nós vamos ter que tomar
uma decisão sobre o que Henry é. Mas isso é intencional. Se você tiver uma classe abstrata, não
poderá criar uma
instância dessa classe. Agora, método abstrato. Então, temos nossa classe
abstrata configurada. Agora vamos criar
um método abstrato. Como mencionei, se
um método for abstrato, qualquer classe filha herde essa classe deve
fornecer uma definição Por exemplo, nossa classe de cães
herda de um animal. O que eu vou fazer excluir esses dois métodos. O cachorro está apenas herdando
as coisas normais. Agora, vou marcar
esse método como abstrato. Esse é um método abstrato. Quando eu marco um
método como abstrato, não
podemos fornecer uma
definição para o método. Como mencionei antes, ele exige que todas as
classes secundárias forneçam sua própria definição porque não
podemos nem mesmo criar
uma instância
dessa classe e estamos
apenas forçando as classes
secundárias a fornecerem
sua própria Então, não
faz sentido sequer ter uma definição aqui
porque é irrelevante Ele nunca seria
chamado ou acessado quando você define um método
abstrato, é apenas um modelo. Está apenas dizendo, ok, para
todas as classes infantis, que você precisa fornecer sua própria
definição para esse método. Na aula de gatos, estamos
fazendo exatamente isso. Temos nosso próprio método aqui e substituímos quando você define um método como abstrato para fornecer
sua própria definição,
assim como virtual, você usa
a palavra-chave override Agora, na aula de cães, você pode ver que há um erro. Se eu passar o mouse sobre o cachorro
aqui, estou dizendo olha, o cachorro não implementa membro abstrato
herdado. O
animal faz barulho Você pode ver que o software
nem está compilando. Simplesmente não podemos
compilar o software. Essa é a razão pela
qual temos que fazer, temos que definir esse método. Nosso amigo Randy, que esqueceu
sua definição de hamster
fazendo barulhos de hamster Bem, agora o software não
compilará
fisicamente , a menos que nosso colega de equipe lembre de
sobrescrever esses métodos Esse é um ótimo uso de
ter um método abstrato. Podemos fazer isso com
todos esses métodos. Por exemplo, por
exemplo, diga nome. Podemos definir um
modelo para isso. Você pode se perguntar: qual é o objetivo de
ter um método? Então, por exemplo, por que
dizer, envelhecer bem? Isso porque todas as nossas
aulas para crianças, como cães e gatos, ainda
podem usar,
digamos, a idade aqui. Por exemplo, podemos chamar, digamos, idade nesses métodos, podemos usá-los de qualquer classe
secundária dessa. Esses métodos ainda são úteis. Então esse é um método padrão, mas esse é um método abstrato. Nos métodos abstratos,
estamos basicamente forçando todas as classes infantis de animais
a implementar algo Para dar uma definição, uma função, isso é o que é
um método abstrato. Isso está forçando todas as classes infantis a implementar uma
definição para elas. No entanto, ainda podemos ter métodos
normais, como
idade, por exemplo. Ainda podemos usar o
virtual e fazer com que cães e gatos substituam
os métodos virtuais está perfeitamente bem, mas esse é o
objetivo do resumo. Portanto, usar classes abstratas aqui, como animal, não apenas
impõe a abstração, sobre a
qual falamos com modificadores de
acesso anteriormente, mas também o polimorfismo, onde podemos definir nossa própria como animal, não apenas
impõe a abstração, sobre a
qual falamos com modificadores de
acesso anteriormente,
mas também o polimorfismo,
onde podemos definir nossa própria função para esses métodos. Aqui, não só isso, mas classes abstratas podem impor qualquer classe filha herdada de animal dê alguma funcionalidade
a esses métodos, considere isso como um projeto,
um contrato ou algo parecido Agradeço que este tutorial
possa ser difícil de ler, mas fique à vontade para
repeti-lo repetidamente
até que você entenda Mas esse é o
princípio genérico por trás das classes
abstratas e dos métodos
abstratos na loja.
48. 9-11. A palavra-chave com this: Vou falar sobre
essa palavra-chave em C sharp, é exatamente assim. O que é isso, é basicamente um atalho para uma
instância de uma classe Aqui temos uma classe chamada dog, e eu estou criando uma instância. Isso pode ser um atalho
para essa instância aqui. Se eu olhar minha aula de cães aqui, ela tem um método
chamado fazer barulho. Quando chamamos esse método
, estamos apenas escrevendo bark woof
na janela do console Se olharmos para isso, agora
estamos ligando para fazer barulho. Se eu executar o programa, você
pode ver que ele não faz muita coisa. Se eu entrar nessa classe de cachorro, posso me referir a essa instância
atual quando esse método
está sendo chamado. Por exemplo, eu entro aqui Se eu digitar isso,
posso me referir a qualquer coisa relacionada
à instância atual que
está sendo criada aqui. Vamos dar uma olhada em um
exemplo disso, só para que eu possa provar isso para você. Eu criei uma classe
chamada helper. Agora, o ajudante não faz muita coisa. Ele tem um método
chamado fazer mais barulho. É preciso um parâmetro, que é um tipo de cachorro, e há a
instância do cachorro. Isso está sendo passado como
um parâmetro para esse método. Estamos escrevendo uma linha, estou fazendo mais
barulho com o nome do cachorro. Se eu entrar na minha aula de cães aqui, vou criar
uma nova instância de ajudante para que eu possa
usar a classe Então vou usar
ajuda, fazer mais barulho. Eu quero passar por
uma instância de cachorro. O que eu posso fazer é passar
a palavra-chave this, porque isso representa
a instância que eu criei aqui. Quando chamamos o método
nessa instância. Imagine isso sendo
lembrado aqui. Agora, isso representa
essa mesma instância. Imagine isso sendo isso. Agora, quando chamamos o auxiliar, estamos chamando o
método, faça mais barulho Essa instância está sendo passada
. Já percorreu um longo caminho. Agora estamos apenas
ecoando o nome
do cachorro que pertence à
instância atual Se eu executar o programa agora,
você pode ver Barkworfi'k. Mais ruído O quê? Está em branco porque não
demos um nome ao cachorro. Vamos dar um nome ao cachorro. Então, nome do cachorro. Vamos chamá-lo de Rocky. Por que não? Agora o cachorro tem um
nome. Vamos executá-lo novamente. Agora, estou fazendo mais
barulho para Rocky. Você pode ver que esse é o
poder da palavra-chave, isso. Ele usa a instância atual, é basicamente um
atalho para ela Imagine que isso seja um atalho
para a instância atual. E podemos fazer o que
quisermos com ele. Podemos acessar,
acessar propriedades, acessar qualquer campo privado ou até mesmo passá-lo para diferentes
métodos como parâmetros. Esse é o poder
dessa palavra-chave na loja. Outra coisa que podemos fazer com
essa palavra-chave em C Sharp. Aqui está um bom exemplo. Vejo que as pessoas fazem muito isso
se tivermos um construtor para uma
classe como animal, e ele usa dois parâmetros, por exemplo, nome e idade Em nosso construtor, queremos
construir nosso objeto. O que fazemos é definir nosso nome de campo local para
o parâmetro, assim. Em seguida, definimos a idade para
o parâmetro também, assim. Agora que fizemos isso,
podemos realmente usar essa palavra-chave para diferenciar
essa instância de nome Esse é o parâmetro
dessa instância de nome. Esse é o campo privado. O que podemos fazer para tornar isso
mais óbvio é dizer isso. Agora, esse nome
se refere a essa, porque essa é a
instância atual dessa classe, vai se referir a
essa. O mesmo com a idade. Isso se refere à instância
que é essa aqui. No entanto, o nome aqui se refere a esse porque não está
na instância atual. Está sendo passado
como um parâmetro. Você verá muito isso ao
configurar construtores, e isso apenas diferencia os nomes para que
não haja ambigüidade É claramente óbvio
o que está acontecendo. A instância atual aqui
é igual ao parâmetro. Você verá muito isso
em seus empreendimentos futuros.
49. 9-12. A palavra-chave base e os construtores de curso base: A palavra-chave base na loja. Qual é a palavra-chave base? Agora, você usaria a
palavra-chave base ao tentar acessar de uma
classe secundária, como cachorro. Aqui, essa é uma classe filha, queremos acessar qualquer coisa
na classe base, daí a palavra-chave base. Considere isso como um
atalho para acessar métodos, propriedades e
coisas assim. Aqui, por exemplo, eu tenho uma classe
básica de animais aqui que tem alguns
campos privados e alguns métodos. Por exemplo, esse método aqui é chamado de método animal, é público e faz parte
da classe animal. O que posso fazer com
o cão da classe infantil entrar aqui e
dizer base e então
acessar o método animal porque neste caso, essa é uma
classe infantil. A base é opcional, mas você
pode ver como ela funciona. Isso adiciona um pouco de clareza. Por exemplo, o que tenho aqui um método
chamado info que apenas exibe na tela algumas informações sobre
esse cachorro atual Se eu for até aqui, criei um novo objeto aqui,
uma instância de cachorro. Eu lhe dei um nome, uma idade e uma raça. E então eu estou apenas
enviando as informações aqui. Então, quando executamos o programa, podemos ver algumas
informações sobre o cachorro. O que você verá muito é apenas adicionar um pouco
de clareza, porque o nome e a idade são definidos na classe base do animal aqui. Assim, você pode ver o nome, idade, isso adiciona um pouco de clareza. Se você olhar o código, poderá ver rapidamente que, tudo bem, esses são membros da classe
principal para dar uma olhada lá. No entanto, Breed é
membro dessa classe, então ela não tem
a palavra-chave base, mas você pode ver facilmente sabe onde elas pertencem apenas
olhando para essa palavra-chave. Mas essa não é a principal
característica da classe base. O que eu quero
falar agora é se você tem um animal na classe dos pais,
por exemplo. Se eu configurar um construtor
no Animal This, você pode ver que há um pequeno
problema com isso Se eu agora tentar
executar o programa, ele não vai me deixar, se eu for até minha turma filha, qualquer uma das classes secundárias, esse erro apareceu. Essa pequena linha vermelha. Se eu passar o mouse sobre isso, há uma mensagem de
erro um pouco enigmática Agora, por padrão,
os construtores não são herdados porque não são
realmente membros de uma classe Mas agora eu defini um
construtor em animal aqui. Agora está tendo um problema. Nem consigo compilar
meu software. O que vamos
fazer aqui é definir um construtor em cachorro aqui Assim, quando eu crio
meu objeto de cachorro aqui, não preciso definir
todas essas propriedades. Posso simplesmente
colocá-los em parâmetros aqui ao criar
nossa nova instância. Vamos dar uma olhada em
como podemos fazer isso. Quando criamos um objeto de cachorro, quero especificar um nome
que esteja na classe principal, uma idade que também esteja
na classe principal
e também uma raça. Eu os quero porque
todos os parâmetros e a
raça fazem parte da
classe dos cães, não da classe base. Se eu for para a aula de
cães aqui, a classe infantil, começo a
criar um construtor Quero saber
o nome do cachorro, a idade do cachorro
e também a raça. Parece algo assim. Agora há um atalho aqui. O que podemos fazer aqui é passar o nome e a idade para a classe base. Como fazemos isso é depois
do construtor aqui, colocamos dois pontos e
colocamos a base da palavra-chave Em seguida, abra e feche os
parênteses aqui. Isso basicamente chama o
construtor da classe base. Nosso construtor aqui
usa dois parâmetros. base, nesse caso,
é um atalho para o construtor
da classe mãe O construtor aceita
dois argumentos. Se voltarmos aqui, ele assume o nome
, assume a idade. Agora estamos lidando com
esses dois parâmetros aqui. Eles estão sendo enviados para
a classe base e o
construtor é chamado Então só precisamos
fazer algo com a raça. Definimos isso aqui. Agora podemos configurar nossos parâmetros aqui quando estamos
criando a nova instância. Agora não precisamos de nada disso. Essencialmente, isso fará exatamente a mesma coisa
se eu executar o programa. Agora você pode ver que ela gera
todas as informações. Mais uma vez, como isso
funciona? Estamos criando uma nova
instância da classe de cães. Estamos chamando o construtor de
cães, que usa três parâmetros Aqui está nosso construtor de cães. Sim, ele aceita
três parâmetros. Depois que o construtor é chamado, ele pega esses dois parâmetros e os envia
para a classe base Na classe base, você pode ver que há
dois parâmetros.
Aqui está, chamando o
construtor com dois parâmetros Nós só temos um construtor, ele tem dois parâmetros,
então isso é chamado Isso define nossas propriedades
aqui, nome e idade, que posteriormente definem
nossos campos privados por meio de getters e setters Depois que o construtor
construiu nosso fluxo de objetos animais volta e, em seguida, o resto do construtor do
cão é chamado que apenas define o campo
local aqui, raça para reprodução aqui. É basicamente assim que
funciona em segundo plano. É só chamar o construtor da classe
base. Escreva aqui, você pode estar se perguntando por que não podemos
simplesmente remover isso? E eu faço com que o nome base seja igual ao nome e depois
à idade, por Não, não vai funcionar porque essa
terminologia aqui em cima,
a base de dois pontos, está na
verdade chamando o construtor da própria classe
mãe Portanto, é necessário e esse erro
se resolverá sem isso. E mesmo se você colocar
essas bases lá, ainda haverá
esse erro aqui porque o construtor da classe mãe nunca
é construído Então, na
verdade, ele nunca cria esse objeto animal porque
essa é a classe principal. O cão da classe infantil
depende disso. É por isso que é necessário aqui. E esse é o poder
da palavra-chave base na loja.
50. 9-13. Interfaces: Interfaces na loja. As interfaces são outra forma de obter abstração na loja Falamos um pouco sobre classes
abstratas antes. abstração é um princípio
orientado a objetos chave, que é apenas o
processo de ocultar os detalhes internos e
mostrar apenas a funcionalidade Vamos dar uma
olhada nas interfaces loja como uma pequena atualização. Vou me referir apenas a
este projeto em que
criamos uma classe abstrata de
animais aqui. Aqui está nossa aula abstrata de
animais. Temos alguns campos privados e métodos
públicos aqui e também
algumas propriedades públicas. Eu tenho um método abstrato aqui, porque a classe dog aqui é herdada da classe
abstrata animal, ela tem que substituir
esse método abstrato É forçado a fazer isso. E esse é o objetivo das classes
abstratas
por meio do polimorfismo Estamos ignorando esse
método, faça barulho. E estamos apenas produzindo woof,
woof para nossa aula de cães Quando criamos um novo
objeto de cachorro e executamos o método, fazemos barulho, simplesmente
ouvimos uau, uau Em princípio, essa é a classe
abstrata que existe. Somos forçados a ignorar
esses métodos abstratos. Aqui, vamos dar
uma olhada em como podemos criar uma interface animal e também ver como as interfaces diferem das
classes abstratas. Interfaces na loja, bastante
semelhantes às classes abstratas. O que vou fazer é criar uma interface totalmente nova na loja. Em seguida,
mostrarei algumas diferenças entre
classes e interfaces abstratas. Então, nossa classe de cães aqui usará nossa
nova interface. Tudo ficará
claro momentaneamente. Se formos para o
lado direito do nosso projeto, clique com o botão
direito do mouse, vá para Adicionar
e depois vá para a aula. No menu aqui,
basta escolher Interface. Agora podemos dar à interface o nome
que quisermos, mas eu quero criar
uma interface animal. Ao criar
interfaces, é sempre boa prática usar um I
maiúsculo de antemão Isso porque quando
você adiciona interfaces, ou pelo menos tem um projeto
muito grande com talvez dezenas ou
centenas de interfaces, você pode distingui-las
das classes normais. Aqui temos animais e
você pode ver animais. Essa é claramente uma interface, só porque a
chamamos dessa forma. É apenas uma boa prática. A diferença entre uma
interface como essa aqui e uma classe, essa aqui. Aqui está apenas a diferença
na palavra-chave, que é que temos uma palavra-chave de
classe para uma classe e a
palavra-chave de interface para uma interface. Praticamente qualquer outra coisa
aqui é a mesma. Essa é a única
diferença sutil aqui. Agora, interfaces em C sharp, você pode considerá-las praticamente 100%
totalmente abstratas. O que isso significa?
Bem, se você assistiu ao tutorial da classe abstrata
como este aqui, temos alguns
métodos abstratos aqui. Quando temos um método abstrato, não definimos um corpo para ele. Como nossas classes
herdam essa classe abstrata, elas definem seus próprios
métodos para elas, como a classe cachorro e a classe
gato, por exemplo Eles fornecem código. Quando vamos para nossa aula
abstrata, ela não tem corpo, por exemplo. No entanto, uma
classe abstrata pode definir seus próprios métodos, como
digamos nome, digamos idade. Eles também podem fazer várias
outras coisas. Isso não é verdade
com interfaces. Considere uma interface como uma classe puramente abstrata em
que você não define corpos Há uma pequena exceção para essa regra relacionada a membros
privados, mas vou discutir isso talvez mais tarde ou
em outro momento. Considere as interfaces como
uma classe puramente abstrata. Não estamos definindo corpos em
interfaces para nossos métodos. Se eu for até minha aula de
cães aqui,
que é herdada
dessa classe abstrata de animais, você pode ver que estou substituindo um método de fazer barulho e seguida, dando a ele minha
própria funcionalidade Eu quero fazer o mesmo tipo
de coisa na minha interface. Na minha interface, quero
definir um método
chamado make noise, que será abstrato porque esse é o
propósito da interface. Se eu definir um novo método chamado
fazer barulho, como você diz, porque é abstrato, eu
não tenho um corpo aqui. E, por padrão, isso é público. O modificador de acesso
é público por padrão. E isso ocorre apenas por design de interfaces, porque queremos que todos usem
essas interfaces. Então, assim, definimos nosso primeiro método
em nossa interface. Muito simples, não é? Porque é público e
abstrato por padrão. Não precisamos de nenhum
modificador de acesso, como público. É opcional e não
precisamos da palavra-chave abstrata. Por exemplo,
é assim que se define um método abstrato público em
C Sharp para uma interface. Agora vou para minha aula de cães. No momento, ele está herdando
dessa classe abstrata e
eu estou bem aqui Eu quero implementar
a interface. Então, vou
colocar um I na frente. Portanto, agora ele usa nossa interface em vez de nossa classe abstrata. Agora, como podemos reescrever isso para que funcione com
nossa interface aqui? Bem, quando herdamos de uma classe abstrata e
temos um método abstrato, como
falamos antes, usamos a
palavra-chave override aqui Mas com interfaces, não
usamos a palavra-chave override, ela não é absolutamente necessária Isso é perfeitamente suficiente. Por exemplo, outra coisa. Se optarmos por não definir um método para nossa interface
e deixá-la assim. Se passarmos o mouse sobre isso aqui, dizendo
que dog
não implementa membro da
interface make noise,
assim como as classes abstratas Isso está nos forçando a fornecer
uma implementação para
esse método para que possa nos
forçar a fazer isso Quando você tem grandes equipes
de pessoas, por exemplo, é muito útil porque
todas as suas aulas são
um pouco padronizadas E então todos vocês substituirão esse método de fazer ruído aqui, assim como falamos
antes em classes abstratas Agora eu tenho essa aula de cães aqui. Ele está implementando o método make
noise que
definimos em nossa interface
e, por meio de polimorfismo, está definindo sua própria
funcionalidade Se eu for até o programa
aqui em que criamos um novo objeto dog
e chamamos o método make noise , disponível
na interface, obteremos
exatamente o mesmo resultado. Então, deixe-me examinar algumas semelhanças e
também algumas diferenças entre classes abstratas na loja
C e também entre
interfaces Porque talvez, superficialmente, eles consigam algo
muito semelhante antes, quando tentamos criar uma instância de uma classe
abstrata. Não nos deixaria.
Não é possível, e isso ocorre por meio do design. Mesmo que eu tente
fazer a mesma coisa com uma interface, por exemplo, isso não vai permitir que eu nem mesmo o Visual Studio ofereça um
recurso de preenchimento automático para isso Quando eu passo o mouse sobre essa nova tentativa de
instância aqui,
está dizendo que não é possível
criar uma instância
do animal de interface de tipo abstrato Portanto, não é possível. Em uma classe abstrata, podemos ter um construtor, mas ele é chamado apenas
pelas classes filhas, não em nenhum lugar fora
dessa cadeia
de herança Você não pode ter um construtor
porque nunca,
sob nenhuma circunstância,
construiria uma interface A interface
funciona como um contrato,
portanto, qualquer coisa
que implemente
a interface pode substituir os métodos disponíveis Sem construtores nas interfaces. Se quisermos fazer isso,
o objetivo é ter uma classe e depois
implementar uma interface, ou herdar de uma
classe abstrata e definir nossas próprias substituições para
esses Por exemplo, é
por isso que não criamos novas instâncias de
classes e interfaces abstratas
e, portanto, não
precisamos de um construtor Outra coisa que também
abordamos foi o fato que classes abstratas podem
ter campos aqui, o que você não pode ter
em uma interface. Novamente, em métodos aqui, podemos definir corpos em classes
abstratas. No entanto, em interfaces, não
podemos porque é
puramente abstrato Essas são algumas diferenças aqui. Você pode estar se perguntando
a seguinte pergunta. Por que eu deveria usar uma interface quando em
uma classe abstrata, por exemplo, eu posso usar campos, posso definir
corpos de métodos se eu quiser. Por que eu deveria usar uma interface? Qual é o objetivo?
Parece mais limitado, sim. Talvez seja 100% abstrato, por exemplo, mas por que eu
deveria usar um? Bem, as interfaces
suportam a ideia de herança
múltipla em
C Sharp, por Se eu tiver uma
interface animal como animal, posso criar uma interface chamada talvez carnívora,
por Então, nossa classe de cães pode,
na verdade, implementar a partir de animais e iconívoros ou talvez
algo parecido Portanto, ele pode ser implementado a partir de
várias classes aqui, várias interfaces, e você não pode fazer isso
com classes abstratas. Portanto, esse é um
dos principais pontos fortes das interfaces em C Sharp Então, vamos dar uma olhada em
um exemplo agora. Se eu vier aqui, clicarei com o botão direito do mouse no projeto, vou para Adicionar interface de classe. Eu só vou
criar iconivorre porque os cães são carnívoros Também é um animal. Talvez haja uma
maneira melhor de representar isso, mas vamos dar uma
olhada neste exemplo. Então você pode ver o
objetivo disso. Em carnívoros, vou definir um método chamado talvez comer carne porque
todos os carnívoros comem carne Assim mesmo. Novamente, é abstrato e público por padrão. É tudo o que precisamos neste caso. Agora, se eu quiser
herdar ou implementar de
várias interfaces, separo a classe
dos dois pontos, assim como Em seguida, insira a classe ou interface que eu quero
implementar ou herdar Mas se eu quiser herdar
de várias interfaces, basta colocar uma vírgula aqui Então eu posso colocar a próxima
interface iconivor, por exemplo. Agora você pode ver que há uma linha
vermelha porque ela não implementa que nosso novo membro
coma carne, o que é verdade. Não definimos um
método para fazer isso. Se eu for até aqui e
digitar comer carne, agora estou implementando esse
método aqui da iconivor Estou implementando esse
método a partir do animal agora. Todo mundo está feliz, não
há linhas vermelhas, tudo satisfeito. Posso então colocar minha
própria definição, algo como comer carne. Então, se eu acessar
minha inscrição aqui, eu apenas digito comer
carne, por exemplo. Agora, esse é o
método que estamos implementando a partir do nosso
novo ícone de interface. Ou coma carne. Ah, vamos livrar disso porque não podemos criar uma nova instância
de uma interface. Agora estou criando
um novo objeto para cães e agora estou comendo um pouco de carne. E isso é um membro
da nossa nova interface. Você pode ver aqui, este é um exemplo muito rápido de
herança múltipla em C E isso é obtido por meio do
uso de interfaces, algo
que você não pode
fazer com classes abstratas. Esses são os benefícios de ambos. Você pode ver que,
usando interfaces em C Sharp e também classes
abstratas, podemos obter abstração, que é um princípio fundamental de
programação orientada a objetos Agora, testando seu
conhecimento sobre herança ou talvez apenas perguntando se você entende
completamente esse entende
completamente Por exemplo, se eu acessar
meu aplicativo principal aqui, posso criar um novo método aqui. Por exemplo, vou
chamar isso de fazer barulho. Não
retornará um valor, apenas
fará barulho sobre nossos animais na janela do
console. E
vamos usar um parâmetro aqui porque o cachorro implementa nossa interface animal porque sabemos, falando sobre herança, antes que um cão
satisfatório seja um relacionamento, um cachorro é um Da mesma forma, nossa aula de gatos. Um gato é um animal, um hamster é um animal Então, podemos simplesmente ir até
aqui e considerar o animal como parâmetro, porque nosso cão implementa essa interface aqui Então, podemos fazer as coisas a partir daqui. Podemos dizer que faça barulho. O que podemos fazer aqui é criar um objeto de cachorro. Então, podemos passar nosso cachorro para esse método aqui
chamado fazer barulho. Então, porque o
cachorro é um animal, isso vai
funcionar, sem problemas. Ele chamará
o método de fazer ruído no objeto aqui, que é um animal. É um animal. Se eu criar um objeto gato, posso usar esse mesmo método porque gato
implementaria animal. Nesse caso, eu poderia criar uma classe Dolphin,
desde que ela implemente animal Novamente, posso chamar esse
método, sem problemas. Você pode ver que esse é o
poder da herança, mas também do uso de coisas
como interfaces Isso também funciona com classes
abstratas, assim como antes, sem problemas. Desde que minha classe de cães herde da classe
abstrata animal Você pode ver agora
que se eu executar este programa, você pode ver que agora está
dizendo woof, woof Da mesma forma, se eu tenho uma
classe de gatos como esta aqui, ela implementa do animal o
método de fazer ruído e substitui seu próprio tipo de lógica
aqui, que é O. Então eu vou para o programa, eu crio um novo objeto gato, então eu quero fazer
barulho com E enquanto estiver
implementando nossa interface
, ela
funcionará, sem problemas. Você pode ver o
poder da herança e por que usamos interfaces Só precisamos
passar a interface
do software,
por exemplo, como um parâmetro de método ou
até mesmo um retorno de um método, ou praticamente qualquer coisa. Novamente, se eu executar o programa, você pode ver através do
polimorfismo que estamos substituindo o método de fazer
ruído para cães e gatos, mas também usando interfaces para transmitir esse objeto Você pode ver que é muito poderoso e as possibilidades também
são infinitas. Você pode ver aqui se eu mudo essa interface para nossa classe
abstrata aqui, vá para a classe e
certifique-se de que ela implemente
a classe abstrata Com classes abstratas, usamos a
palavra-chave override porque essa é a diferença entre
elas e as interfaces Nós refletimos isso também
na classe de cães. E depois volte ao
nosso programa principal aqui. Em seguida, execute o programa. Você pode ver que distribuímos uma classe abstrata e ela funciona exatamente da
mesma forma que uma interface. Mas há diferenças
sutis, como discutimos anteriormente, entre interfaces
e classes abstratas. Mas esse é um
exemplo de como eles se comparam e também
das vantagens de usar interfaces para satisfazer a herança
múltipla em C Espero que este tutorial tenha ajudado você e obrigado por assistir.
51. 9-14. Resumo de O: Então, acabamos de concluir
alguns tutoriais sobre programação
orientada a objetos Agora,
examinamos praticamente todos os princípios do paradigma de
programação E agora
vamos meio que fechar círculo e refletir
sobre o que aprendemos e colocar algumas palavras-chave
e coisas assim. Então, novamente, como mencionei
no início de nossa jornada 00, C sharp é uma linguagem de
programação orientada a objetos. E usar 00
realmente ajudará você a
estruturar seus projetos. Quando seus projetos
ficarem muito grandes, será
muito mais fácil mantê-los. você
pratique muita reutilização de Talvez você
pratique muita reutilização de
código no futuro Se você continuar essa jornada, trabalhará
com outras pessoas. Talvez em uma empresa
que também entenda de programação. Todos
vocês conhecerão e já entenderão as mesmas técnicas
para escrever software. Então você vai começar a
correr muito rápido. Então, vamos examinar algumas das terminologias novamente
para que você entenda completamente E então vamos passar
para algo um pouco diferente. Programação orientada a objetos. Novamente, é um paradigma, que é uma forma de
fazer alguma coisa Conversamos sobre aulas. Agora, as classes modelam objetos do mundo
real. Então, se você tem um
software sobre uma biblioteca
, uma aula pode ser um livro. Como um livro é um objeto do mundo
real, sua aula de livros deve
ser altamente coesa Isso significa que a aula
sobre o livro deve ser apenas sobre o livro. Não deveria ser sobre o
usuário ler o livro. Então, quando você tem uma
classe de livro, todos os métodos, todas as propriedades devem estar
sempre relacionadas ao livro. Essa é uma prática muito boa e suas aulas devem
ser fracamente acopladas Isso significa que sua aula de leitura
deve ser sobre o livro. Sua classe de usuário deve
ser sobre o usuário. E eles
realmente não deveriam ter muito em comum com os outros objetos. Agora, os objetos estão criando uma
nova instância de uma classe. Uma classe é como modelo com todos os
métodos e propriedades. E quando quisermos criar
uma nova instância disso, você pode ter uma ou
milhares, se quiser. Isso se chama
criar um objeto. Portanto, um objeto é apenas uma
instância de uma classe
e, quando você cria uma instância, isso é chamado de instanciação Agora, a herança
promove a reutilização do código
e, quando você reutiliza o código, isso o torna mais sustentável . Não precisamos copiar o código e colocá-lo em cada classe, porque se tivermos
uma classe como cachorro
, ela pode herdar de um animal Se tivermos uma classe chamada gato, novamente ela pode herdar
de um animal E muitas dessas classes
terão os mesmos recursos. Então você vai usar e
escrever muito menos código. E quando você escreve
muito menos código, isso significa que seu código
será muito mais sustentável muito mais fácil
de gerenciar Além disso, o tamanho
do arquivo do software será mínimo. Além de testar o
software, você pode ter muito
menos código para testar. Portanto, a herança, apesar de tudo, é um
princípio muito bom a ser praticado Falamos sobre polimorfismo, aquela palavra grega estranha que
significa muitas formas ou muitas formas, o que significa muitas formas ou muitas formas, obtivemos com a
sobrecarga Ao falar sobre métodos, como podemos ter parâmetros
diferentes mas com o mesmo nome de método. Mas também, mais recentemente,
falamos sobre polimorfismo com substituição de
método. Em uma classe
base como animal, podemos Então, quando herdamos
dessa classe, em uma classe de cachorro, gato ou
hamster, podemos substituir esse método e fornecer
nossa Podemos ver o resultado
disso quando executamos
o aplicativo, por
exemplo, ao usar o, o cachorro latirá ao usar
o método make noise. Ao usar a classe de gatos, o gato miará Podemos reutilizar esse mesmo método , mas fornecendo
funcionalidades diferentes Isso é polimorfismo. Últimos dois. Agora, as duas últimas pessoas se
confundem entre as duas porque são muito parecidas
e andam de mãos dadas. E isso é abstração de encapsulamento. Agora, o
encapsulamento oculta a funcionalidade interna
de Ele só permite o acesso por meio
de um conjunto público de funções. Por exemplo, quando
falamos sobre modificadores de
acesso
públicos e privados, porque queremos ocultar
nossas informações confidenciais, como nossos
campos privados, por exemplo Mas acesse-os apenas por meio de métodos
públicos para que possamos verificar os dados e garantir que as pessoas não estejam
quebrando coisas. Coisas assim, por exemplo. E também propriedades de lojas marítimas. Quando se fala em abstração, significa exibir apenas informações
essenciais e ocultar os detalhes mais importantes
. E fizemos isso por meio de classes
abstratas e também de interfaces. Então, imagine como uma cafeteira, se você quiser preparar um café, pressione o botão de preparação do
café. Se você quiser ligar um
carro, gire a chave. Você não precisa
saber como funciona o motor de partida de
um carro, nem o alternador ou o carregamento da bateria Como usuário, como desenvolvedor, você só precisa girar a
chave para fazer o carro funcionar. Semelhante a uma
cafeteira,
você prepara um café, não precisa saber
como os eletrônicos funcionam, como a água é aquecida. Tudo isso é
abstraído de você, é uma
informação desnecessária Se você é apenas um
usuário final dessas coisas, como uma cafeteira ou
o motorista de um carro, simplesmente não
precisa saber disso. E isso é abstração. E vemos isso
na vida cotidiana, todos os dias, várias vezes ao dia. E essa é a
diferença entre encapsulamento e abstração Novamente, os dois principais termos de programação
orientada a objetos, mas
andam muito de mãos dadas. E às vezes, muitas vezes pode
parecer que há uma linha um pouco confusa entre encampamento e
abstração por esse Então, parabéns,
examinamos todos os princípios
da programação
orientada a objetos E se você optar por outra linguagem, como
C plus ou Java, poderá transmitir esses
princípios e começar a trabalhar
quase imediatamente. Não está vinculado ao C.
Sharp é algo muito popular e também usado em
muitas linguagens de programação.
52. 10-1. EXERCÍCIO: pirâmides de desenho: Hoje vamos desenhar pirâmides e vamos desenhá-las em nosso tipo de aplicativo de
console E vamos
deixar o usuário decidir o tamanho
que deseja que
sua pirâmide seja Por exemplo, se o
usuário digitar 45
, uma pirâmide será gerada aqui E
terá 45 linhas de altura, como você pode ver aqui. Parece muito
legal, não é? No entanto, se o usuário
digitar o número cinco, por exemplo, sua
pirâmide terá apenas
cinco linhas de altura Isso é meio que um exercício. Isso não apenas testará suas habilidades de programação em C sharp, mas também
testará sua habilidade lógica. Como você pode analisar um problema
e desenvolver uma solução
dividindo-o em
pequenos subgrupos e, em seguida,
atacando o Então, vou resolver esse problema e mostrar como eu
abordaria essa tarefa
para que você possa ver como minha mente funciona e como eu abordo
esse problema específico. É muito comum
ver exercícios como esse ao conduzir
uma entrevista de emprego. Por exemplo, o entrevistador pode perguntar como você desenvolve um pequeno
software para gerar uma forma ou uma pirâmide ou
algo parecido Porque qualquer pessoa pode pesquisar sintaxe e código na internet Mas o que muitos
empregadores gostam de fazer atualmente é testar como sua mente funciona, como o pensamento
lógico. Veja se você consegue
encontrar uma solução
no local e
talvez também sob pressão. Então, vou desenvolver uma solução para isso e vou mostrar como
eu penso sobre isso passo a
passo para que você possa ver como minha mente funciona e
como eu abordo esse problema. Vamos embora. O primeiro passo é analisar o problema. Quando o usuário insere um número, isso indica a
altura da pirâmide Não apenas a altura
da pirâmide, mas o número de
linhas desenhadas Você pode ver que há
cinco linhas aqui. A pirâmide termina quando
há o símbolo de uma libra, e a base da pirâmide
cobre toda a linha Mas você pode ver aqui, é
a altura da pirâmide, que é indicada por A pirâmide tem cinco linhas de altura, isso é uma coisa a se notar A segunda coisa a observar é que todos esses quadrados
são preenchidos Se eles não estiverem preenchidos
por hashes aqui, o símbolo da libra
representa a pirâmide Em seguida, eles são preenchidos
pelo plano de fundo, que é indicado por hífens. Aqui você pode ver que o topo da pirâmide tem
o símbolo de
uma libra
e, em ambos os lados
, quatro hífens Na próxima linha, você pode ver a pirâmide aumentar
em dois em vez de um Aqui agora são três
e, em seguida, há um
hífen a menos em cada lado Novamente, abaixo, a pirâmide
cresce em dois por linha
e, em seguida, o hífen
diminui Temos algumas regras aqui. A cada nova linha, a
pirâmide cresce em duas. E cada nova linha, o hífen, encolhe
uma em cada lado Uma última coisa a
observar é que,
neste exemplo, em que tenho
uma altura de pirâmide de cinco, temos nove caracteres
ao longo da largura aqui, cinco abaixo e nove de largura Temos muitos
dados com os quais trabalhar. Vamos ver como podemos desenvolver
uma solução para esse exemplo. Se você acompanhou nossos
tutoriais anteriormente, talvez
tenha visto o exemplo que
fizemos quando desenhamos um
cubo na tela Agora, esse exercício é
um pouco diferente, é um pouco mais complexo, mas os princípios e procedimentos nos
bastidores são bastante semelhantes. Nesse exemplo,
usamos alguns loops, usamos quatro loops Este exemplo
não deve ser diferente. Quando vemos dados
repetidos como esse
e desse tipo em nossa cabeça, devemos pensar: ok, um loop deve estar envolvido Algo deve estar circulando e
iterando para gerar
esses hífens iterando para gerar
esses Então, precisamos de outro loop para gerar
esses símbolos de libra. E então talvez um terceiro loop aqui para continuar
com os hífens Há algumas maneiras de abordar
esse problema. Talvez pudéssemos fazer
um loop em que simplesmente trocamos o personagem
pela parte da pirâmide Sim, isso também pode funcionar. Ao desenvolver
soluções como essa. Existem algumas
soluções para o problema, mas a escolha é sua. Ao fazer essa escolha, você quer fazer a mais fácil eficiente em termos de tempo. Mas também gere o código
que seja mais sustentável, mais sustentável por
você mesmo no futuro, mas mais sustentável
para qualquer colega de equipe que
realmente assuma seu código
e o desenvolva no Há muitas coisas em
que pensar. Acho que a maneira como eu abordaria esse problema é ter um loop principal
descendo o eixo y. Temos um loop principal que
gera cada linha por vez. Então, dentro desse loop, terei um loop que
gera esses hífens Um segundo loop que gera a
parte da pirâmide, que é essa E então um terceiro loop que
continua com esses hífens, um loop principal que
faz o eixo y. Então, dentro desse loop, acho que três loops separados Essa é uma solução perfeita para
abordar esse problema. Vamos dar uma
olhada nisso agora e ver se podemos desenvolver
algo assim. Então, aqui está o código que
temos até agora, ele realmente não está fazendo
nada, está apenas enviando algumas
mensagens para o usuário,
dando as boas-vindas ao software Obrigado por usar o aplicativo. Isso é o que ele faz. E então estamos fazendo a pergunta ao
usuário. Estamos pegando a entrada do usuário, convertendo-a em um número inteiro e armazenando-a em
uma variável inteira Agora, o que eu
quero fazer é criar um método. Porque quando eu crio um método, eu posso chamá-lo várias
vezes de vários lugares, e então eu posso gerar
pirâmides de onde eu quiser Acho que toda a lógica para
gerar a pirâmide
do tamanho personalizado aqui
deveria pertencer a um método E então é facilmente
reutilizável por qualquer outra coisa. Vou criar
um modelo de método. Agora, o método não terá um tipo de retorno
porque eu só quero que o método
desenhe a pirâmide Isso criará
um parâmetro e esse será apenas
o tamanho da pirâmide Aqui está nosso método básico. A primeira coisa
que eu disse que ia fazer foi gerar um loop, que imprimiria
cada linha sucessivamente e que
desceria pelo eixo y. Vou criar
um loop para fazer isso. Então esse laço aqui representa
a altura da tela. Então, a altura da
pirâmide, neste caso, porque a pirâmide
toca a parte superior
da tela
em que estamos desenhando e também a parte inferior, é seguro dizer
que qualquer número que o usuário forneça a
altura total da pirâmide, não
temos fundo acima da pirâmide e nenhum fundo abaixo da pirâmide Fazer o eixo y de um
menor ou igual ao
tamanho da pirâmide e incrementar em um
garantirá que desenhemos pirâmide ao longo
do eixo
y Agora, dentro desse loop, mencionei que uma solução
possível era ter três loops
separados O primeiro para desenhar os
hífens no lado esquerdo, o segundo para
desenhar a pirâmide
e o terceiro para continuar com os hífens
no lado Deixe-me configurar esses loops agora sem realmente
pensar em escrever código Por exemplo, eu já
tenho esse bom modelo. Acabei
de gerar
esse modelo pensando logicamente no problema Preciso de um laço para desenhar para baixo até o
tamanho da pirâmide Então, dentro de cada linha, preciso de algo gerando a pirâmide e o plano de fundo
em cada linha separada Eu já tenho um pequeno modelo
legal aqui sem realmente
pensar muito no problema. Quando desenhamos os
hífens à esquerda, a única coisa que queremos fazer é enviar um hífen para a tela Vamos fazer isso agora.
Da mesma forma, quando desenhamos os hífens à
direita, vamos desenhar um Da mesma forma, quando
desenhamos a pirâmide, precisamos do símbolo da libra Praticamente a única
coisa que precisamos fazer agora é descobrir quando
esses loops terminam Quando analisamos o
exemplo anterior e o usuário inseriu o número
cinco, por exemplo
, a pirâmide tinha
uma largura de nove, mas uma altura de cinco A primeira linha da
pirâmide tinha o símbolo de uma libra, mas tinha quatro
hífens em cada lado Precisamos descobrir quando
parar de desenhar hífens. Para descobrir quando parar desenhar hífens
no lado esquerdo, precisamos descobrir quando
encerrar esse Da mesma forma, a largura que
devemos desenhar a pirâmide em cada lado e também quando
parar de desenhar hífens
no lado direito E ao desenvolver
um software como esse, alguns dias você terá a
máxima clareza. Isso será fácil para
você, basta digitar os valores. Sabe, você está
tendo um bom dia. Mas às vezes, se eu estou apenas cansado ou não estou com
a mentalidade certa ou talvez você seja um
iniciante e saiba que está
meio que resolvendo isso na sua Bem, então não é uma pena
usar algo como Microsoftic Cell ou um bloco de
notas apenas para traçar todos os seus números, para que você possa usar seu espaço livre
no cérebro para encontrar uma solução para o problema ou talvez
qualquer Portanto, não há vergonha em criar nós ou algo parecido,
é perfeitamente normal Deixe-me abrir o Excel e traçar
alguns desses números aqui. Eu abri o Microsoftic Cell aqui e mapeei
a Bem, solução inesperada. De qualquer forma, se o usuário digitar
o número cinco, por exemplo
, sabemos que nossa pirâmide
terá cinco unidades de altura Quando o usuário digita cinco, ele gera uma
pirâmide parecida com esta A solução que
desenvolvemos até agora. Eu tenho um loop que
imprime cada linha por vez. Esse é o nosso loop principal. Denotamos isso com y. Você pode ver aqui que
acabei de chamá-la variável y, y é igual
a E vai até o tamanho
da pirâmide. Menor ou igual ao
que eu vou fazer. Vou colocar a
variável y aqui. A próxima coisa dentro desse loop, eu tenho três loops Um gerará esse conteúdo, o próximo loop
gerará esse conteúdo e o terceiro loop
gerará esse conteúdo. Eu também vou
colocar isso aqui. Esse será o
primeiro conjunto de hífens um. Essa será a pirâmide, e esse é o segundo
conjunto de hífens Agora, quando y é um, esta é a primeira
vez que nosso loop Queremos gerar quatro
hífens à esquerda, queremos gerar um
caractere para a pirâmide e também quatro hífens à direita quando y é
dois Agora nosso loop está se repetindo
pela segunda vez que estamos
gerando essa linha Nosso primeiro loop
gerará três hífens. Nosso segundo loop
gerará três segmentos
para a pirâmide Novamente, os hífens serão os mesmos
à direita, depois três e depois
na terceira linha Você pode ver para onde
isso vai: dois, a pirâmide será cinco
e os hífens dois, depois a linha número quatro
e a linha número Eu só vou preencher. Agora você pode ver
aqui alguns números sobre quantos caracteres serão impressos para cada
iteração do loop Agora, usando isso, você pode
descobrir o que precisa fazer. Você tem mais clareza
em sua cabeça. Você não precisa se
lembrar desses números. Você pode indicar a capacidade do seu cérebro de pensar em uma
solução para o Vamos ver como gerar uma
solução para esse problema. Quando o usuário
digita o número cinco
, cinco é o
tamanho da nossa pirâmide Nosso tamanho variável, que
entra em nosso método, será cinco na primeira
vez que o loop for executado. Lembre-se de que y é o nosso loop. Na primeira vez que o loop é executado, y é igual a um. Podemos ver que quando y é um, o número de hífens
em cada lado aqui é um a menos que o
tamanho da pirâmide Na segunda vez que o loop é executado, você pode ver que os hífens em cada lado são dois a menos do que
o tamanho da pirâmide Você pode ver uma pequena
regra aqui. Você pode ver que
quando o tamanho é cinco e subtraímos
um do tamanho,
obtemos o número de
hífens em cada lado Quando Y é 25, menos dois é 35, menos três é dois. Você pode ver que para
gerar o número de hífens em cada lado, pegamos o tamanho
da pirâmide
neste exemplo como cinco e
subtraímos Isso nos dará o número
de hífens em cada lado. Vamos ver como gerar
esses loops de hífen. Esses são os dois
loops que geram os hífens à esquerda
aqui e também à direita Dissemos que o
número de hífens para cada linha é o
tamanho total da pirâmide E subtraímos y disso. Nós apenas dizemos tamanho menos Y. Para aumentar a clareza, colocamos
colchetes e isso aumenta a
legibilidade.
Estou muito confiante. Agora, para cada linha, estamos produzindo o número
correto de hífens à esquerda
e também à direita O que muitos desenvolvedores tendem a
fazer é executar o aplicativo mais cedo. Há algumas
razões para fazer isso. Primeiro, você pode ver se sua
última alteração foi correta. E segundo, você pode simplesmente observar o estado atual
do aplicativo. Na verdade,
dá um pouco mais prazer ver o que
você já fez Vamos dar uma olhada. Agora, na verdade, estamos chamando o método, agora estamos pegando
o número do usuário. Estamos chamando o método
e, em seguida, esse método
está sendo executado. Vamos dar uma olhada
nos resultados até agora. Se eu digitar o número cinco, agora você pode ver que tudo está em uma linha. Então, por que isso? Isso porque, depois
de todos esses três loops, não
estamos realmente
produzindo uma linha totalmente nova Também há um pequeno
problema aqui. Toda vez que
produzimos um personagem, produzimos uma
nova linha dois Isso também é um erro. Toda vez que
produzimos um caractere, não queremos
escrever uma nova linha, queremos apenas escrever
esse caractere. Então, usamos o console para fazer isso quando realmente
queremos uma nova linha. Bem, então vamos fazer isso depois de todos esses loops Vamos dar uma
olhada no aplicativo agora e ver como ele se parece. Então você pode ver agora que temos
um pouco em forma de rumbus. Parece muito interessante, mas você pode ver que o
número de hífens está correto Começamos com 43210. Agora precisamos corrigir
essa seção intermediária aqui, que é a pirâmide Vamos dar uma
olhada em como fazer isso. Vou voltar ao
Excel, vou voltar ao Excel. Agora, o que eu quero fazer
é descobrir como
gerar esses números usando
nossas informações disponíveis. Temos o tamanho da pirâmide e também temos o valor de y. Em cada iteração do loop, já
fizemos as quantidades de hífen para Parece muito simples de fazer, mas como geramos
esse número usando as informações
que temos na primeira linha? Aqui, a pirâmide
é um personagem, você pode ver lá na linha
dois, a pirâmide é Você pode ver em cada nova linha, a pirâmide aumenta em símbolos
de duas libras,
13579, todos eles são números
ímpares Como podemos gerar
esses números usando as informações
que temos aqui? Para aqueles que
são bons em matemática, provavelmente
é muito
fácil para você, mas às vezes os desenvolvedores não são muito bons em
matemática atualmente. Talvez nos anos 70 e 80, quando todos os matemáticos
e médicos faziam um pouco de programação, fosse bastante óbvio, mas hoje em dia é programação de TI É uma habilidade um pouco separada.
Às vezes, não se traduz
diretamente em matemática. Mas se você notar aqui
com esse valor de y aqui, vamos pegar o número três. Por exemplo, se multiplicarmos
três por dois, obtemos seis. E então subtraímos
um disso, então obtemos o valor cinco Novamente, talvez quatro. Por exemplo, quatro vezes dois é oito. Subtrair um é 75
vezes dois é dez, subtrair um é nove E eu acho que essa é
uma regra que pode funcionar
em todo o campo, mas devemos sempre testar
com 1.0 em casos como esse. Um vezes dois é 21 é um. Sim, isso parece funcionar também. Acho que essa pode ser
uma regra que funciona. O que podemos dizer é que p é igual a y multiplicado por
dois, menos um. Essa é uma regra que deve
funcionar para gerar a pirâmide com base no próprio número
da linha Pode haver muito mais
soluções para esse problema, mas essa certamente
funcionaria para nós com base em y aqui. Voltando ao nosso software, aqui temos o valor de y em cada iteração do loop O que fazemos aqui é gerar
a pirâmide em cada linha quando y é
três, por exemplo Então, queremos gerar
cinco desses símbolos de libra. Aqui dissemos que é Y multiplicar por dois e depois
subtrair um Seria
algo parecido com isso. Eu acredito que isso funcionaria, mas para adicionar um pouco de clareza, eu sempre uso
colchetes extras como este Isso só o torna mais legível para que possamos ver o que está acontecendo Mas você obteria
exatamente o mesmo resultado usando isso devido à massa do lance, porque a multiplicação
vem antes da subtração Mas em casos como esse,
eu sempre escrevia assim. Por exemplo, vamos dar uma olhada no exemplo agora
e ver o que está acontecendo. Se produzirmos o número cinco, inserirmos o número cinco, você pode ver agora que obtemos
uma bela pirâmide Isso é muito legal, não é? Isso funciona para números
maiores? Digamos que 35. Isso parece muito bom. Sim,
parece que está funcionando. Você pode ver que é assim que eu
abordaria um problema em
algo assim. Praticamente escrevemos 90% do código apenas
analisando o problema. Não precisávamos realmente
pensar em C sharp e programação. Nós literalmente apenas
olhamos para a pirâmide, dissecamos um pouco o problema e o dividimos
em pedaços menores A única parte difícil
foi descobrir os limites
desses quatro loops Então, quantos hífens
devemos desenhar, quanto da pirâmide
devemos desenhar em cada linha
e, novamente, os
hífens à direita E também uma pequena complicação sobre novas linhas e
coisas assim, o que é meio normal Às vezes todo mundo
comete erros, é normal. Mas você pode ver como
isolamos esses problemas e usamos o Microsoft Excel para
executar os números, então não precisávamos realmente manter todas essas informações
em nossa cabeça. Podemos simplesmente
pegar o problema aqui, dissecar tudo, analisar todos os números
e depois
descobrir como obter
esses números a partir das
informações que temos ,
seja a altura da
pirâmide ou
o valor de y em cada
iteração do Assim, você pode ver como resolvemos o problema sem
realmente pensar nisso. Nós realmente não usamos
nenhum poder cerebral. Tudo em nossa
mente foi despejado no Excel e podemos criar uma solução
a partir disso Então é assim que eu lidaria com
uma situação como essa. Especialmente se eu estivesse muito cansado ou de ressaca
e não conseguisse pensar, então, você sabe, deixe as
ferramentas fazerem o trabalho por você Então, voltando
ao Visual Studio agora estamos desenhando pirâmides
bem legais Podemos até substituir
o fundo um belo espaço em branco vazio. E talvez possamos
desenhar duas pirâmides. Quer dizer, nós o colocamos em um método, então agora podemos repetir o
método com muito mais facilidade. E esse é o poder dos métodos. Então, se eu agora colocar
o número cinco, por exemplo, agora estamos gerando três pirâmides uma
em cima da outra Isso é muito legal, não é? De qualquer forma, é assim que eu abordaria um
problema como esse. Novamente, é algo comum que você pode encontrar em entrevistas de emprego. Mas, na verdade, o poder de um programador é
testar o pensamento lógico Como sua mente funciona? Um bom programador
não é alguém que consegue lembrar da sintaxe e
regurgitar Um bom programador é alguém
que consegue pensar logicamente, resolver um problema e encontrar uma solução adequada Isso é o que é um bom
programador. Então, espero que você tenha achado
este exercício útil e obrigado por assistir.
53. 10-2. Soluções, vários projetos e namespaces: Neste tutorial, mostrarei
como
configurar vários projetos
no Visual Studio. Falarei um pouco sobre a
terminologia, como soluções,
projetos, montagens
e também espaços nominais Também posso mostrar como acessar arquivos de diferentes
montagens. Isso será muito
útil daqui para frente. Se abrirmos o Visual Studio, podemos obter esse diálogo aqui onde podemos criar
um projeto totalmente novo. Aqui, vamos clicar aqui e, em
seguida, vamos
criar um aplicativo de console. Se eu clicar em Avançar aqui, ele me perguntará
o nome do meu projeto. Agora, como eu escolhi um aplicativo de
console aqui, isso é o que representa
uma interface gráfica de usuário, algo que o usuário pode ver. Da mesma forma, você pode ter um aplicativo
Windows Forms, que também é um Gooey Mas esses são os projetos de
interface gráfica do usuário
porque tem uma janela que podemos
ver ao nomear esse projeto Por exemplo, é bastante comum em aplicativos
ter o que é chamado de arquitetura
de três camadas, em que você tem um projeto representando
a interface Talvez em um site que possa ter um aplicativo de console HTML, tenha uma janela preta e qualquer lógica relacionada a isso. E então você tem
uma camada intermediária, às vezes chamada
de camada de negócios, que tem todos os cálculos em
segundo plano, toda a lógica, tudo a ver com o cérebro
do aplicativo E talvez a terceira
camada seja como um banco de dados no que diz respeito a todos os
dados. A capacidade de obter
dados de um banco de dados. Você sabe, talvez esteja emparelhado com um banco de dados Oracle
ou um banco de dados SQL. Então, tudo tem a ver
com a camada de dados. Isso é o que é comumente conhecido como arquitetura de três
camadas Quando você cria esse projeto em C sharp aqui no Visual Studio, primeiro estamos criando
o cara aqui. E esse é o
aplicativo de console neste exemplo. Então, vou chamá-lo de
algo assim. Normalmente, o que eu faço e o que outras empresas de software fazem é quando você cria o cara, você pode colocar o cara no
nome do projeto. Se o projeto foi chamado de aplicativo de
teste, por exemplo, você pode ver
algo assim, como cara do aplicativo de teste. Ou teste um cara. Ou talvez um cara teste o Ap,
algo parecido. Pelo nome, você sabe instantaneamente que está
lidando com o cara, a interface gráfica do usuário. Então, eu vou apenas
testar o Apoe, por exemplo. Você não precisa
fazer isso assim, mas essa é uma boa prática e também
é bastante comum. Se você continuar com
seus esforços, verá muitas vezes isso Vou criar
o projeto agora. Aqui temos nosso cara. Realmente não faz muita coisa. É apenas uma janela preta que se
fechará instantaneamente. Mas esse projeto aqui, se virmos para a direita, esse projeto aqui representa
algo a ver com nosso cara. Qualquer coisa gráfica que
o usuário possa ver, qualquer coisa a ver com o cara, tudo isso está
contido aqui. Você pode ver no topo
aqui, nós temos uma solução. Agora, a solução pode conter
vários projetos, talvez 102030, e podemos adicionar projetos
diferentes aqui Então, por exemplo, vamos
criar uma camada de negócios. E isso terá todo o código, toda a lógica, todos os
cálculos, por exemplo. Novamente, ao criar uma solução, se for apenas um
pequeno projeto de teste, por exemplo, muito pequeno, talvez você esteja apenas
fazendo uma maquete rápida
, ter uma arquitetura de três
camadas é bastante Pode não ser necessário, mas se você souber com antecedência será um projeto grande ou algo que pode se conectar a um banco de dados ou ter
muita complexidade. Então, você precisa considerar
sua arquitetura antes de começar a
criar outro projeto. Agora vamos criar
a camada de negócios. Então, se eu clicar com
o botão direito do mouse na solução Adicionar, posso ir para um novo projeto aqui. E na hora de escolher os projetos, eu já tenho meu cara aqui,
esse aplicativo de console. Então, eu realmente não
quero outro, especialmente agora,
talvez no futuro. Depende das minhas necessidades. As necessidades de todos são diferentes. Mas algo como uma camada
de negócios em
que você tem código e
praticamente código puro. Então você quer algo
chamado biblioteca de classes. Se eu clicar em Avançar aqui, posso ligar para a biblioteca da turma
novamente do jeito que eu quiser. Mas se meu aplicativo for
chamado de aplicativo de teste dessa forma, talvez
tenhamos algo como
B L, uma camada de negócios, ou LL, uma camada de lógica de negócios
ou algo parecido. Algo representando uma camada diferente
no aplicativo. Normalmente, eu gostaria de uma camada
de negócios, por exemplo. Então, esse projeto
conteria todas as coisas
comerciais, como a
extremidade comercial do sistema, se você ver aqui. Agora temos dois projetos. Temos nossa interface gráfica
de usuário. Agora temos nossa
camada de negócios aqui e ela
conterá todos os cálculos
e coisas assim. Agora, por fim, se eu escrever, clique na solução novamente. Eu poderia adicionar algo
como uma camada de dados, talvez um projeto de banco de dados
ou algo parecido. Também pode ser
outra biblioteca de classes representando a camada de dados. Algo bem parecido. Você poderia dizer Dow para camada de acesso a
dados ou
algo a ver com dados. Ou até mesmo banco de dados para banco de dados.
Isso realmente não importa. Eu poderia chamá-lo de
algo assim. Então, esse último projeto
aqui, esse terceiro, representaria
qualquer coisa a ver com vincular nossa solução a
um banco de dados em potencial, seja Oracle, SQL, meu CQL, algo
assim, não importa E agora temos três projetos. Agora, arquitetura, há muitas arquiteturas disponíveis na
construção de software, como na construção de um prédio Não há uma maneira única
de construir um prédio. Há muitas maneiras diferentes, mas essa é muito popular. O que acontece é que, se talvez você
tenha 50 pessoas em sua equipe, você trabalha para uma empresa. Algumas pessoas saberão
sobre HTML, por exemplo, mas não saberão nada sobre talvez um banco de dados ou
cálculos complexos em C sharp neste projeto. Então, o que acontece é que eles
só trabalharão neste projeto. Da mesma forma, se você é
uma pessoa que trabalha com bancos de dados
, você só trabalhará
nesse projeto de banco de dados aqui. Separar suas soluções por projetos
diferentes também ajuda trabalho em equipe e
coisas assim Somente pessoas que
conhecem o banco de dados, por exemplo, trabalhariam
com esse projeto de banco de dados. Esse é um pouco do
raciocínio por trás disso. Como faço para obter meu projeto
aqui, por exemplo? Esse cara, como faço
para que ele fale com esse projeto? Porque, por padrão, adicionei três projetos
aqui na solução, mas nenhum deles está
conversando entre si. Como podemos conseguir isso? Se eu for para minha
interface gráfica de usuário, por exemplo, este projeto aqui, vou
para dependências aqui Agora, dependendo da
versão do Visual Studio, essa é a mais nova No momento, ela se
chama dependências Se você tiver uma versão mais antiga, ela pode dizer referências
ou algo parecido. Se você clicar com o botão direito do mouse e
acessar Adicionar referência do projeto. Quando eu faço isso, aparece uma
janela. Agora posso ver todos
os projetos em minha solução conforme indicado
por este menu à esquerda Aqui, quero verificar os projetos que
quero vincular ao meu cara, digamos que quero falar com minha camada de negócios, onde todos
os cálculos são feitos. Eu apenas verifico isso
e pressiono OK. E agora, internamente, minha interface
gráfica de usuário, agora pode
se comunicar essencialmente com esse projeto aqui, a camada de negócios onde estarão todos
os cálculos Vamos colocar uma amostra aqui
para que possamos fazer alguma coisa. Não vai fazer muita coisa. Configure um método muito simples aqui dentro do que é chamado
de camada de negócios. E o que isso vai fazer é simplesmente retornar
a string hello. Isso é tudo que ele vai fazer. Vou chamar isso de olá. Vou chamar
isso de olá turma. Agora, dentro da nossa
camada de negócios aqui, eu tenho uma classe
chamada hello class. Ele tem um método, e tudo o que esse método faz é
retornar a string hello. Agora, se eu voltar ao meu projeto de
interface gráfica de usuário aqui, testo o cara do aplicativo e eu digitamos, por exemplo, hello class. Você pode ver que
nem está nesta lista, mas na verdade eu referenciei
o projeto a esta Por que não consigo acessá-lo? Bem, é aqui que entram os
namespaces. Se você está acompanhando
esses tutoriais até agora, verá bastante esse espaço de
nome de palavra-chave, quase em todos os arquivos E então tem um nome. Normalmente, o nome
do namespace é gerado
automaticamente
a partir do nome do projeto. Por exemplo, esse projeto
aqui se chama Test App Guy. Mas se eu passar para
minha camada de negócios, meu projeto de negócios que criei, você pode ver
que o nome
do projeto está aqui.
Agora nomeie o espaço. É como uma
forma lógica de organizar as coisas. Por exemplo, já falamos antes sobre a
aula de matemática, por exemplo, onde fazemos arte matemática, raiz
absoluta ou quadrada
ou algo parecido. Mas a aula de matemática, se eu passar o mouse sobre isso, você pode ver que ela pertence a um namespace chamado
sistema aqui Por padrão, quando eu crio um
novo projeto no Visual Studio, recebo alguns
espaços de nome por padrão. Todos esses espaços de nome aqui, esses sete, são fornecidos
para mim por padrão. Essencialmente, posso usar qualquer código que a
Microsoft tenha
me fornecido e que esteja
contido em qualquer um desses espaços de
nomes aqui, assim como eu tenho um
namespace aqui com um E eu tenho um código aqui. Por padrão, posso utilizar qualquer código dentro
de qualquer um desses espaços de nomes. Isso é muito parecido
com o que temos aqui. O que eu preciso fazer, bem, eu preciso falar com o namespace onde
eu defini esse método, porque no momento não é. Aqui. Você pode ver
onde definimos o método dentro de um
namespace chamado test app PL. Se eu copiar isso, eu
volto para a minha camada masculina, aqui, logo acima, eu uso uma palavra especial
chamada usar o quê? Usando does, ele permite que você
use um namespace diferente. Se eu simplesmente colar
esse espaço de nome aqui, seguido por dois pontos, se eu digitar hello class, agora você pode ver que
tenho acesso a ele, essencialmente usando
esse espaço de nome Eu tenho acesso a qualquer coisa dentro desse namespace,
dentro desse arquivo. Espero que isso faça sentido agora, porque a classe hello está definida
em teste no namespace B L, como você pode ver aqui,
está dentro do namespace Eu posso acessar todos
os seus recursos. Vou criar
uma nova instância do hello class aqui. Agora eu posso dizer olá,
retornar olá. E isso vai
me dar aquela corda. É assim que eu posso falar com uma classe diferente dentro de
um namespace diferente, que está dentro de um projeto
diferente. Agora, para maior clareza, se eu abordar
minha solução aqui, vou para minha camada de
negócios de aplicativos de teste aqui. E eu vou a uma aula
aqui, por exemplo. Você pode dizer que ele tem o espaço de nome
padrão. Se eu criar uma nova turma,
clico com o botão direito do mouse em Adicionar nova turma. Eu chamo do que eu
quiser, não importa. Você pode ver novamente que ele tem o mesmo namespace
porque foi retirado do projeto. Não importa
quantas aulas eu crie. Por padrão, ele usará o nome do projeto
para o namespace. Mas você pode renomear
o
namespace para o que quiser Você pode ver que esse é o
poder dos namespaces. Na loja, você pode ter
namespaces aninhados, por exemplo, um namespace dentro de um namespace, o
que é bastante comum no Visual que Você pode ver que há um namespace chamado system dentro dele Há uma chamada coleções. Dentro disso, há
um chamado genérico. Pense em um namespace como uma forma de agrupar
as coisas Se você tiver alguma coisa
dentro de um projeto, que tenha a ver com um
projeto, todo o seu código ,
por exemplo, na camada de
negócios, como
o coração do aplicativo, será um projeto, uma montagem, por exemplo. No entanto, dentro desse projeto, você pode ter coisas diferentes. exemplo, você pode ter
parte do projeto para calcular a área de
uma casa ou algo assim, mas dentro desse projeto, você pode ter algo
completamente diferente, como calcular uma declaração de imposto Mas talvez essas duas
coisas
precisem existir dentro do mesmo
projeto por qualquer motivo. E nesse caso,
você os
agruparia logicamente em talvez um espaço de nomes
diferente Então, qualquer coisa relacionada ao trabalho
na área de uma casa, você pode chamar isso de um espaço
nominal e
outro para fazer declarações
fiscais ou
qualquer outra coisa. O exemplo pode ser qualquer coisa e isso pode ser um espaço de nome diferente. Então, você está meio que
agrupando logicamente por uma atividade ou função ou o que quer que você decida ao pensar em projetos,
pense em arquitetura, por exemplo, na forma como
você estrutura sua solução Mas, ao pensar em namespace, pense em
coisas mais lógicas, como agrupar partes
de código semelhantes E essa é uma espécie de
diferença nesse caso. Então, vou mostrar mais
uma coisa sobre
vários projetos, montagens
e
coisas assim Agora, esse é um assunto bastante
complicado, um assunto bastante amplo, na verdade. Mas o que estou mostrando
é suficiente para seguir o restante
desses tutoriais Mas não só isso, mas quando você inicia suas próprias
soluções e projetos, você tem uma ideia geral de como você deve
estruturar as coisas. E também como
organizar seu código, que é muito importante à medida que seus projetos se tornam
maiores. Agora, se viermos até aqui, temos nossa solução aqui com nossos três projetos abaixo Agora, cada um deles
representa como uma assembléia. É uma palavra que você
vai ouvir muito, mas quando as pessoas falam
sobre montagens e o modificador de
acesso interno
, ela é interna
à montagem, que normalmente é
representada por Um projeto por montagem. Agora, se eu acessar
esse botão verde de reprodução aqui, ao clicar aqui, nossa solução será compilada, todos os nossos projetos
serão compilados e uma montagem será criada
para cada um de nossos projetos. Então, se eu for para o meu sistema de
arquivos
agora, agora estou usando um sistema de janelas
para o projeto principal aqui. Ele está criando um
arquivo EXE aqui. Novamente, alguns
arquivos com isso. Mas você também pode ver
que, na verdade, está criando um arquivo DLL aqui para
cada um de nossos projetos. Agora, esses são
chamados de montagens aqui, porque temos três
projetos neste caso, também
temos três
montagens Você pode ver
os bastidores e como isso é representado
no mundo real. Quando você dá esse
software a seus amigos ou talvez o empacota
em um arquivo de configuração, você pode ver como
esses projetos são representados como
arquivos binários aqui, normalmente um para cada projeto. Uma coisa que vou mencionar
é que ter essa
palavra-chave de uso aqui é um tanto opcional se eu
decidir removê-la, por exemplo, você pode ver isso não vai
mais funcionar porque não consegue localizar o namespace em que essa classe está
contida. O que podemos fazer nesse caso é apenas qualificá-lo com
o namespace Toda vez que uso a classe Hello, preciso dizer ao sistema
onde ela está localizada, por
exemplo, em qual
namespace ela está? Nesse caso, posso
qualificá-lo com o namespace antes
do nome da classe Mas se eu continuar usando
essa classe
neste arquivo talvez 1020 vezes, terei muitos
tipos de código redundante Então, em vez de
fazer isso, posso remover tudo isso e usar o espaço para nomes
na parte superior do arquivo. E então eu não preciso mais
qualificá-lo toda vez que o uso Então, essa é uma vantagem de usar o namespace aqui, NC
54. 11-1. Pontos de interrupção e passo de código: Depuração, depuração em C Sharp. O que é depuração? Se você acompanhou
meu tutorial até agora, trabalhamos com a linguagem
C Sharp, fizemos muitas coisas diferentes Orientação de objetos, loops,
cálculos, métodos. Mas durante esses
exercícios, por exemplo, e trabalhando com a linguagem, o fato da vida é
que os humanos são humanos. Eles vão cometer erros, sejam intencionais
ou não,
ou apenas um Essas coisas acontecem. É
aqui que entra a depuração. Agora, depuração é um termo vago. A palavra depuração é usada
em dois sentidos diferentes. Podemos dizer, ok, vou fazer uma depuração, e esse é o processo
de tentar encontrar Talvez seu software não tenha bugs, mas você
tentará encontrar alguns apenas para
garantir que funcione corretamente.
Isso é normal. Você também pode usar o
termo depuração quando
o software tem um problema e você está tentando
localizá-lo Então você diria que
vou tentar depurar meu software porque
há um erro Não sei onde está, mas
preciso tentar encontrá-la. Portanto, é usado em dois sentidos aqui. Agora, como mencionei, o fato da vida é que
ninguém é perfeito. Se todos fossem perfeitos
, as empresas de software nem mesmo
contratariam equipes de teste para realizar testes. Você não teria algo
chamado testes unitários. Você não precisaria
testar seu código. Mas o fato da vida
é que não somos perfeitos. E é por isso que
precisamos saber sobre depuração e tentar
encontrar erros em Agora, até agora, nesta série de
tutoriais, usamos o Visual Studio. Agora, o Visual Studio é ótimo. Ele contém muitas ferramentas recursos e,
para ser
honesto, mal descobrimos para ser
honesto, Ele tem um compilador que
compila nosso código. Ele tem o IDE onde
podemos realmente digitar para criar soluções de
projetos. Ele tem esse recurso de
preenchimento automático, também conhecido como Intellisense Então, muitas coisas diferentes, mas uma outra coisa que ele também tem é o que é chamado de depurador Portanto, um depurador é um
software,
um programa totalmente separado, escrito E o trabalho do
depurador é se
conectar a outro
software Isso é chamado de
anexar o depurador. Então, a qual software esse
depurador se conecta? Bem, esse é o seu
código, seu software. Toda vez que você pressiona o botão
verde de reprodução, seu software é compilado
em segundo plano Se você estiver usando o
Windows, por exemplo, ele é compilado em um
EX, por exemplo Em seguida, o depurador pode
se anexar a esse
arquivo EXE nesse caso, mas não apenas Ele pode se conectar a outro processo de execução
que seu sistema está executando É muito poderoso.
Então, qual é a vantagem desse depurador
se conectar ao Qual é o propósito
disso? Por que faria isso? Bem, quando um depurador
se conecta ao seu software, ele permite que você
exerça um nível de controle enquanto seu E ele pode examinar
segmentos específicos do código quando algo pode dar errado durante
a execução do software Imagine que você possa pausar seu software a
qualquer momento Digamos que seu software carregue, ele está rodando em um loop. Por exemplo, talvez um loop de quatro, e você pode simplesmente interromper a execução no
meio do Digamos que você tenha quatro voltas
e conte até dez. Você pode parar seu software
a qualquer momento, por exemplo, quando ele é
contado até quatro. Então, enquanto o
software está em execução, você pode acessar seu código
e inspecionar tudo. Você pode ver os valores das variáveis. Você pode até mesmo controlar
a execução. Então, faça manualmente esse loop anterior fazer mais duas iterações,
por exemplo E você pode fazer isso sozinho. Você já viu aqueles filmes de
super-heróis em que o cara é muito rápido e
o mundo inteiro está congelado Mas como ele é tão rápido, ele pode interagir com
as pessoas em tempo real. Imagine que seja
como um depurador. O mundo está cuidando
de seus negócios. Mas essa entidade super rápida, esse herói super rápido, pode
voar na velocidade
da luz e modificar coisas
e controlar coisas É mais ou menos assim que
um depurador funciona. É muito poderoso e divertido de
usar, para ser honesto E o processo de pausar
seu aplicativo enquanto ele está em execução usando o depurador é chamado E quando eu disse que você pode
realmente controlar a execução. Por exemplo, se seu software estiver em execução e estiver prestes
a executar um método,
você pode ignorá-lo completamente, passando por cima dele e
controlando o fluxo
do software
enquanto ele está em execução, o que é
chamado de alteração de código O depurador é, na verdade um software
bastante poderoso
,
e 99,999% dos desenvolvedores usariam um depurador Então, vamos dar uma
olhada em um exemplo disso. Agora, como entramos neste mundo em que somos um super-herói rápido E podemos pausar o software
e mudar as coisas, alterar os valores das variáveis e pular métodos
e coisas assim Como fazemos isso? Bem,
vamos dar uma olhada. Então, se você está
acompanhando nossos outros tutoriais até agora, quando escrevemos algum código, pressionamos este botão
verde de reprodução aqui em cima Quando pressionamos o
botão verde play, nosso software é executado. E quando queremos matá-lo ou
terminá-lo, ou riscamos a janela
aqui ou
pressionamos esse botão vermelho de
parada aqui em cima Então é isso que temos
feito até agora. Se você for para a esquerda
desse botão verde de reprodução aqui, verá uma lista
suspensa aqui. Por padrão, ele deve dizer D bug, mas por baixo
também tem release Agora, esses dois itens aqui
são muito importantes. Se tivermos bugs
selecionados nesta lista, toda vez que
pressionarmos o botão verde de reprodução, o depurador também será executado
e também
se conectará ao nosso Para os curiosos, se você
selecionar a versão nesta lista
, normalmente a usamos quando queremos fornecer o software a outra
pessoa, pois ele não contém nenhuma informação de depuração Mas, por enquanto, vamos
falar sobre depuração aqui. Agora, isso é chamado
de modo de liberação. No momento, queremos
depurar nosso programa, encontrar alguns erros
e fazer algum trabalho de detetive Normalmente, quando
desenvolvemos software
como desenvolvedor e encontramos
erros e desenvolvemos nossa solução, usamos esse modo de
lançamento aqui, bug. E é por isso que é padrão. Então, como eu disse antes, quando executamos o
aplicativo aqui e nosso software está sendo executado
em segundo plano,
o depurador, o depurador do
Visual Studio,
se conecta se E eu posso provar isso para você
se eu abrir o Gerenciador de Tarefas. Aqui está meu gerenciador de tarefas aqui, esses são todos os
aplicativos que estou executando. Aqui está o Visual Studio,
mas abaixo você pode ver o console do depurador do Visual
Studio Isso está sendo executado em
segundo plano e na verdade, está conectado
ao nosso software. Mas até agora, nós realmente
não fizemos nenhum uso disso em nossos tutoriais
anteriores, mas neste tutorial
e nos próximos, vamos usá-lo
bastante Agora vamos dar uma olhada no depurador
do Visual Studio. Vamos dar uma olhada em como fazer
uma depuração aqui. Eu tenho um aplicativo de amostra. Quando esse método principal é executado. Aqui está entrando em um
circuito de arame sem fim. O aplicativo nunca
será encerrado. Toda vez que esse laço de arame faz um loop, solicitamos que o usuário
insira um dia da semana Estamos pegando a resposta deles, armazenando-a em uma variável e, em
seguida, passando
a resposta para esse método aqui, dependendo do dia
da semana em que eles inserem. Temos uma
declaração switch que imprime uma mensagem personalizada, dependendo do dia da semana em
que ela é inserida. Muito simples, toda vez
que ele envia uma mensagem, estamos apenas inserindo uma linha
em branco e voltando novamente para solicitar outro
dia da semana É uma
aplicação bastante simples. Com esta aplicação, tenho um pequeno problema quando
digito na quarta-feira. Não está me dando a saída
real que eu quero. Quando eu digito quarta-feira, quero que ele imprima
quartas-feiras ou mitos, o que não acontece atualmente Por exemplo, se eu
digitar terça-feira, recebo uma resposta para terça. Mas na quarta-feira, você pode ver que está me dizendo que eu
inseri um dia inválido Agora eu entendo que este é um software
muito simples, mas imagine que esse software
seja muito complicado. Você pode ter 50 arquivos. Você pode ter métodos, métodos, métodos chamada,
métodos dentro de loops Então você pode ver que pode
ficar muito complicado. Então, vamos dar uma
olhada em como podemos depurar um aplicativo como esse Sabemos até agora, usando nossas habilidades de detetive,
que terça funciona Portanto, o código está
entrando nesse método. A declaração switch foi executada e estamos recebendo uma
resposta para terça-feira. No entanto, quarta-feira não
está funcionando. Então, há um problema com
esse código nesse ponto. Pelo menos é
o que eu pensaria. Parece que quando
eu digito na quarta-feira, ele está gerando esse tipo de seção
padrão aqui Por que está fazendo isso?
O que eu poderia fazer nesse caso é adicionar o que é
chamado de ponto de interrupção. Se você passar por
esse lado esquerdo aqui, há uma barra cinza. Quando vou a qualquer lugar
nessa barra cinza, você pode ver um círculo cinza lá. Se eu clicar com o botão esquerdo, ele adiciona um ponto vermelho. Então você pode ver
aqui, isso se chama. O que está definindo um ponto de interrupção? Por que isso é chamado de ponto de interrupção? Bem, quando eu executo o software aqui e digito em qualquer
dia da semana, você pode ver a
execução do código parar para lembrar quando eu expliquei
a você o que era um hambúrguer, e eu disse, é como
aquele super-herói que pode se modificar em tempo real, você sabe, como a
velocidade da luz Essa é a inação do depurador. Agora, o depurador se
conectou ao nosso software definindo o que é chamado de
ponto de interrupção, esses Aqui, podemos definir
quantas quisermos. Toda vez que o código atinge
um desses pontos vermelhos, o software congela Isso vai parar. Nada
mais pode ser feito. Se eu tentar abrir meu software, não
consigo interagir com ele. Está totalmente congelado. E temos
controle total no nível do código. Essa peça amarela aqui, é nela que está congelada. E esse é nosso primeiro ponto de interrupção. Então, nada mais pode acontecer. Está congelado no tempo. Então, o que podemos fazer enquanto
está parado aqui, podemos realmente inspecionar as coisas. Olha, se eu passar o mouse sobre isso, posso ver o valor
da nossa variável aqui Eu posso ver o valor
disso sendo passado aqui. Então, é muito legal, não é? É como interagir com o mundo enquanto o
mundo está congelado Você sabe, sinta o poder. Então esse é o poder
de um ponto de ruptura. Isso quebra o software. E eu não quero dizer
quebrar como quebrar um copo de vidro ou
quebrar um vaso de vidro Quero dizer, interrupções em pausa,
tipo parada . Pare a execução Então isso é o que é um ponto de interrupção. A próxima coisa sobre a
qual quero falar é o que é chamado de escalonamento de código O que é escalonamento de código? No momento, nosso software
está congelado no tempo. Está congelado nesta
linha aqui. A instrução switch
ainda não foi executada. É amarelo, o que significa que está prestes a ser executado,
mas ainda não. O que podemos fazer executar
manualmente a
próxima linha de código. Isso é chamado de escalonamento, e podemos fazer isso manualmente Se chegarmos aqui, você
verá todos esses ícones aqui. Esse aqui
diz entrar, esse um passo para cima, esse para fora. E esse é um passo para trás. Então, muitos botões de
passo diferentes aqui. Mas o que é pisar? Bem, por exemplo, esse aqui, dê
um passo em frente. Você vê que o
atalho de teclado aqui é dez. Se eu pressionar dez, isso vai
ultrapassar essa afirmação. E isso significa que
o código será executado na
próxima linha de código ou no próximo bloco de código
dentro de uma instrução switch. Aqui está nossa opinião, que é basicamente
uma corda de garboard O que deveria acontecer é que essa
linha de código seria executada porque não temos
nenhum dia da semana que
corresponda à nossa entrada. Se eu pressionar F dez, que é um passo para cima, você pode ver o código e
vai para esta linha aqui. Agora executamos o início
da instrução switch e agora o software está
novamente congelado no tempo. Nessa linha, você pode ver que não temos um
ponto de interrupção nessa linha, mas isso não importa porque
passamos por cima manualmente Se quisermos que o software
continue em execução, pressionaríamos o botão
play, por exemplo Então, o software
continuaria funcionando até atingir um
desses pontos de interrupção vermelhos Mas quando fazemos etapas de
código, como
passo a passo em todo
esse tipo de coisa, estamos executando manualmente
uma linha de código por vez, ou um bloco de código por vez,
como uma instrução switch, por Então, esse é o poder da etapa, seja, executar manualmente segmentos do seu
código em sequência, como normalmente
seria executado Agora, o software está
congelado nesta linha aqui. Você inseriu um dia inválido. Se eu pressionar dez
novamente, agora nossa janela do console
exibirá essa linha. Se eu abrir a janela do console, você verá que essa linha já
foi executada,
mas, novamente, o software
está congelado no tempo. Novamente, neste símbolo de
quebra aqui, eu pressiono F dez novamente, e agora estamos prestes a escrever essa linha no
console F dez novamente, e agora o método é executado. Isso é muito legal, não é? Entrar no Visual
Studio ao trabalhar em C sharp é
controlar manualmente o código, executar
manualmente partes do código Isso é o code stepping. Isso nos permite
executar manualmente linhas de código. E podemos fazer isso sozinhos. E podemos fazer isso definindo pontos de
interrupção para interromper
inicialmente o código E então podemos
usar o que é chamado comandos de etapa para entrar, sair e todas
as coisas assim. Mas qual é a diferença
entre entrar, sair, superar? O que são essas coisas? Bem,
considere este exemplo aqui. Executamos o aplicativo e estou chamando esse
método cinco vezes seguidas sem nenhum
motivo real além de mostrar
a diferença. Se executarmos a etapa em que é 11
, entraremos nesse método. Se eu pressionar F 11, você verá que a próxima
linha de código a ser
executada é a
chave aberta aqui, seguida pela instrução
switch Eu entrei em um método, entrei aqui O que também podemos fazer é
ultrapassar o método. Apenas ignore tudo isso completamente. Talvez saibamos que esse
método é perfeito, não
há nada de errado com ele. Então, podemos ultrapassar todo
esse método. E então a próxima linha a ser
executada será essa aqui. Como temos etapas
em todo o método, essa é a diferença entre
entrar e superar. Podemos simplesmente pular uma seção
inteira do código. Você pode ter adivinhado
. O que é sair? Bem, estamos em um
método agora. Posso clicar em sair do turno 11 e podemos
sair completamente do método. E fazemos isso quando assumimos
o resto dos métodos. Tudo bem. Nós meio que queremos
sair daqui e voltar para onde estávamos antes e depois entrar em
qualquer outra coisa. Então essa é a diferença
entre esses comandos de etapa. Normalmente, basta entrar em
algo como um método, uma classe ou
algo parecido, ou uma propriedade, ou podemos
superá-la completamente. Então, simplesmente ignore e
continue com o resto. E se nos encontrarmos
em um método e, você sabe, tudo parece meio bom, então podemos sair dele. Então, esses são chamados de comandos de
etapas. E o processo de mover a execução do código é chamado de escalonamento ou escalonamento de
código Então essa é a diferença
com aqueles que estão lá. Então, agora eu expliquei os
pontos de interrupção. Escalonamento de código, comandos de
escalonamento. Vamos tentar encontrar
nosso problema aqui. Pode parecer bastante óbvio, mas lembre-se de que dissemos que a
quarta-feira não estava transmitindo a
mensagem correta. Então, por que isso? Então, vamos definir um ponto de interrupção nessa
instrução switch aqui porque sabemos que o problema provavelmente
está dentro dessa instrução
switch. Então, vou executar
o aplicativo agora e vou digitar Wednesday. Vou pressionar Enter e estamos prestes a lançar
essa instrução de troca. Aqui está nossa variável aqui. Posso passar o mouse sobre a entrada e posso ver, olha na quarta-feira Então, agora o que está acontecendo
é que, se eu passar por aqui, você pode ver que está atingindo
esse caso padrão Então, nenhum desses casos
corresponde à quarta-feira, mas isso parece
estranho porque eu tenho quarta-feira aqui
agora, quarta-feira Então, se eu passar o mouse sobre essa
variável, quarta-feira, oh, eu vejo, olha, o y está em maiúscula
ali. É maiúscula. Provavelmente é por isso que agora mudei esse
y para minúsculo. Eu passo o mouse sobre essa variável aqui. Parece que combina
corretamente. Então isso deve funcionar. Agora, o que eu poderia fazer é
reiniciar o aplicativo. Você vê esse ícone aqui
ao lado do botão Parar. Diz reiniciar. O que eu também poderia fazer é interromper o programa ou
riscá-lo e executá-lo novamente. Esse botão de reinicialização
aqui, o que
isso faz, reinicia o código R, mas deixa o depurador
rodando em Se você clicar em reiniciar, especialmente se tiver um software
grande, é um pouco mais rápido
começar novamente. Essa é a diferença entre o botão de reiniciar e
parar a reprodução. Uma coisa que também podemos
fazer, por exemplo, é mover manualmente
a execução do código. O que diabos isso significa? No momento, estamos executando
essa linha de código. Está prestes a ser executado. Acabamos de superar isso e agora estamos prestes a
executar esta linha aqui. Essencialmente, essa instrução
switch aqui terminou de ser executada. O que podemos fazer é passar o mouse sobre essa seta
amarela aqui Pressione nosso botão esquerdo e podemos realmente mover a execução do código de
volta para o início
da instrução switch, como se ela nunca tivesse sido executada
em primeiro lugar. Isso é muito legal, não é? Imagine arrastar o mouse
aqui usando um comando de etapa, como passar por cima ou para dentro Mas isso permite que você recue, mas não apenas uma linha,
mas várias linhas. Portanto, é um atalho para
esses comandos de etapas. Mas isso permite que você faça isso
em grandes partes, por exemplo. Agora estamos prestes a executar novamente a instrução switch, mas na verdade
modificamos o código aqui e nem
paramos nosso software. Isso é feito em tempo real. É muito legal, não é? Agora, se eu passar a usar dez, você pode ver que essa linha agora
é atingida pela linha direita. As quartas-feiras são meras, então
parece que resolvemos o problema. Era só que, era só aquele y
maiúsculo na quarta-feira. Agora, o que posso fazer
é pressionar F cinco, que é a abreviação desse botão
verde de reprodução. Então, agora eu acho que o
problema está resolvido. Eu não quero fazer mais
nenhuma depuração. Eu posso tirar meus pontos de
interrupção se eu quiser, e então eu posso simplesmente apertar
este botão verde de reprodução e isso fará com que o
software continue normalmente. Então agora está dizendo quartas-feiras
, o que é perfeito. Isso é exatamente o que eu quero. Se eu repetir novamente, obteremos exatamente o mesmo resultado. Parece que corrigimos
o problema com nosso software. Foi apenas a diferença de um
personagem. Pode ser uma pequena alteração. Mas mesmo coisas como a diferença de um caractere podem fazer com
que, digamos, foguetes Space X caiam no chão,
nunca atingindo a órbita Portanto, é muito importante que tudo seja
verificado detalhadamente. Para fazer
isso, um depurador é uma ferramenta muito útil para
realizar coisas Vou apresentar mais
um exemplo e algumas outras
ferramentas de depuração que você pode Eles são executados para clicar
e executados para o cursor. Então, vamos dar uma
olhada neste exemplo aqui. Se você acompanhou
os tutoriais anteriores, provavelmente se
lembra desse Essencialmente, este exemplo está
sendo solicitado a fornecer um número. Você digita o número 25
e, em seguida, ele desenha uma
pirâmide com 25 linhas de altura Por exemplo, porque eu coloquei 25, ele tem 25 linhas de altura. Mas você pode ver que
há um problema com o plano de fundo dessa pirâmide Esse lado direito aqui
está durando muito tempo. Deve ser parecido com
o lado esquerdo aqui. Depois de cada linha, você pode ver
a pirâmide ficar mais larga, mas o fundo
encolhe desse jeito Mas esse comportamento não está sendo imitado
no lado direito Há um pequeno
problema com isso. Vamos dar uma olhada no
que está acontecendo aqui. Aqui está o exemplo.
Aqui, estamos perguntando ao usuário
a altura que ele
deseja que a pirâmide tenha Estamos passando isso para um método. Estamos delegando toda a lógica de desenhar a pirâmide
nesse único método Aqui temos nossos quatro circuitos principais que desenham cada linha
da pirâmide sucessivamente Então, temos 34 loops, um para fazer os
hífens à esquerda, um para desenhar a pirâmide
e outro para fazer os hífens à Sabemos que temos um problema com
os hífens à direita. Essa provavelmente é uma
boa área para definir nosso ponto de interrupção e
dar uma olhada no que está acontecendo aqui Se executarmos o software, pedimos ao usuário um número. Vamos começar
com um número baixo. Números baixos são mais fáceis depurar porque
não há muitos deles. Vou digitar o número cinco. Nosso ponto de interrupção
foi atingido aqui. No momento, H não está declarado. Vamos pressionar dez para passar por cima. E agora inicializamos o
cabeçalho do nosso loop de quatro. No momento, estamos prestes a fazer a primeira iteração do loop H é um porque esse é
seu valor inicial aqui. Então H continuará
funcionando até que seja menor ou igual ao
que parece cinco. E a cada iteração
aumentamos em uma. Para a primeira linha, H vai continuar cinco vezes porque esse é
o tamanho aqui. Se eu passar por cima disso, emitiremos
um hífen, depois dois hífens, Então está feito. A
primeira linha em uma pirâmide, que tem cinco unidades de altura, produz cinco hífens Isso é verdade? É isso mesmo? Não, porque na primeira linha, ele deve produzir quatro. Está gerando
muitos hífens aqui. Por que isso acontece? Obviamente, está
gerando muitos hífens, mas os hífens à esquerda
estão gerando a estão gerando Então você pode ver aqui,
o hífen deve parar quando seu tamanho é menos y. Essa é a fórmula que
tínhamos Obviamente, fizemos isso
para esse loop de hífen aqui, mas esquecemos de replicar a mesma funcionalidade
para
os hífens à direita
usando um ponto de interrupção Você pode ver que
podemos examinar o valor de H enquanto o
software está em execução. Vamos fazer isso agora. Você pode ver que podemos
examinar os valores de H. Podemos examinar
os valores de tamanho, podemos examinar os valores de y. Podemos até examinar
valores aqui em cima, valores que entram
no método usando os comandos step, como
step over ou into, podemos realmente controlar a
execução do software. Isso é muito legal, não é? Digamos que
descobrimos a solução aqui, descobrimos o Agora, eu mencionei algumas
coisas antes sobre correr para o cursor e correr para
clicar. O que eles são? Bem, corra até o cursor e execute
para clicar nos comandos de atalho. Lembra quando eu falei sobre arrastar essa seta amarela aqui? Está aqui para que possamos
controlar a execução? Execute manualmente para clicar e execute atalhos
do cursor para
controlar o fluxo de código. É como inserir código. Se eu colocar
meu cursor aqui, por exemplo, clique com o botão
direito do mouse e
escolha executar até o cursor, clique nele e
a execução vai para
onde quer que o cursor do mouse estivesse. É um pouco curto
e é bastante útil. Outro é executado para clicar. Você pode ver quando toda
vez que eu clico em uma nova linha, esse misterioso pequeno botão
verde de play aparece. Mas você pode ver aqui,
este aqui. Eu clico nesta linha, ela
aparece aqui, é como um
fantasma verde. Então, isso é chamado de executar para clicar. Se eu clicar neste pequeno botão
verde de reprodução aqui, a execução do código vai pular
para essa linha. Portanto, é praticamente a
mesma coisa que clicar
nesta linha, clicar com o botão direito do mouse
e escolher executar até o cursor. Portanto, é apenas um
pequeno atalho útil. Assim, você pode ver
que correr para clicar e correr para o cursor são
pequenos atalhos úteis Se essa seção do código se
repetir várias vezes, posso
clicar
nela, por exemplo, e a execução do código continuará até
atingir essa linha Eles são apenas pequenos atalhos
de codificação. Este é executado para clicar
e, ao clicar com o botão direito, você pode executar para codificar o cursor, mas também existe um atalho
para isso, que é o controle F dez Quanto mais você usa
o Visual Studio, mais
aprenderá esses atalhos Mas todo desenvolvedor que eu conheço qualquer forma, saberá
entrar e sair, que é o F 10.11. E esses dois são muito úteis para
analisar o código Agora vamos executar
o aplicativo e
parece que nosso problema com os
hífens foi Foi apenas um problema com
os últimos quatro ciclos aqui. E esse é o limite superior. Portanto, ao depurar o
código em geral, você precisa se
fazer algumas perguntas Se ocorreu um erro, qual era a declaração
ou expressão o programa estava fazendo
no momento do erro? Em qual linha de código
seu programa falhou? O programa falhou? E você tinha esse tipo de linha
destacada que dizia que
havia um erro lá.
Que linha era essa? E quando seu programa falhou, quais foram os valores
das variáveis, como os parâmetros, os campos
locais, quaisquer objetos? Quais eram esses valores
quando o erro ocorreu? Qual foi a sequência de instruções executadas
no momento do erro? Você estava dentro de um método? De um método, por exemplo? Então, onde você estava? O que
foi executado de antemão E acho que já
abordei essa questão. Qual foi o resultado da
linha de código em que ela falhou? Ou talvez o resultado da
linha de código antes do erro? Então você tem que considerar
todas essas coisas. Você não pode simplesmente colocar pontos de interrupção em qualquer lugar e
esperar encontrar um erro Você tem que
se perguntar essas perguntas. Meio que direcione o erro
aproximadamente onde ele pode estar, qual classe ele pode estar, em qual método ele pode estar. Então, depois de
isolá-lo em um método específico, você pode começar a traçar
pontos de interrupção e
isolá-los um
pouco pontos de interrupção e
isolá-los Resumindo, isso é
o que é depuração. É o processo de
procurar erros, mas se você tiver um erro, é o processo
de isolar o erro Isso é o que é um depurador. Portanto, este é um depurador do Visual
Studio. E você pode usar
isso ao definir o modo de lançamento para depuração E quando você está depurando, você pode colocar coisas E é aqui que a execução do
código será interrompida. Quando a execução do código é interrompida, isso é chamado de modo de interrupção. Você está entrando no modo de interrupção e
é quando um ponto de interrupção atingido para controlar
o fluxo de execução. Usando step in para sair, alugar, clicar em locatário, cursor ou até mesmo arrastar o mouse
ao longo dessa barra de pontos de interrupção Então, isso é chamado de escalonamento de
código. Essas são
todas as terminologias relacionadas à depuração Você pode se surpreender, mas nós apenas analisamos
a superfície da depuração Espero que este tutorial tenha ajudado
você. Obrigado por assistir.
55. 11-2. Janela imediata: Neste tutorial,
falaremos sobre a janela imediata. Agora, esse é um utilitário de depuração
e é extremamente útil e é extremamente Se você ainda não viu
meu último tutorial sobre depuração, pontos de interrupção, alteração de
código, recomendo fortemente que assista isso antes
de
assistir a este tutorial,
na
janela imediata, o que na
janela imediata, o Se chegarmos aqui, você pode ver essa pequena guia
aqui chamada Janela Imediata. Talvez você já tenha visto isso antes, talvez esteja se
perguntando do que se trata. Se você não vê essa guia aqui
, se chegarmos ao topo, podemos acessar esse menu de
depuração aqui Agora é aqui que estão todos
os utilitários
e recursos de depuração e recursos Se você estava se perguntando, vá para o Windows e depois para
Imediato. E quando você faz isso,
voltamos
aqui e essa pequena guia
deve aparecer aqui. Agora, a
janela imediata pode ser usada no momento do
projeto ou na execução,
então o que isso significa? Bem, o tempo de design é quando
estamos meio que desenvolvendo. Ainda nem apertamos o botão
verde de reprodução. Não compilamos nada. Não estamos executando nada. Mas o que podemos fazer é que
podemos realmente trabalhar com nosso software
em tempo de design, para que o software
nem esteja em execução. Então, vamos dar uma
olhada neste exemplo agora para que eu possa mostrar
o que quero dizer com isso. Se você seguiu nossos tutoriais
anteriores,
criamos uma
calculadora de amostra em que
solicitamos ao usuário um primeiro número,
um segundo número e, em
seguida, um operador E então, dentro de um método
aqui, por exemplo, ele pega esses números
e um operador, por exemplo, 54, e
então talvez mais. E então, se o
operador for um sinal positivo, ele os soma e exibirá
apenas o resultado,
que seria nove. Nesse caso, o que podemos fazer realmente testar esse método na janela
imediata. É uma loucura, certo?
O software nem está sendo executado,
nem mesmo está em execução Como fazemos isso?
Vamos usar esse método aqui. Calcule, por exemplo.
Então, vou copiar isso. Vamos descer até esta janela
imediata aqui. Agora, qualquer coisa na janela
imediata começa com um ponto de interrogação
que basicamente diz, ok, eu quero executar um comando. Então, eu quero executar esse método. Então, o que vou fazer
é chamar esse método. Vou chamá-lo com cinco,
e é preciso um caractere, e me lembro dos caracteres
entre aspas simples. E faremos uma vantagem ao trabalhar na janela
imediata. O ponto e vírgula é opcional. Podemos dizer isso, não precisamos, isso realmente não importa. Agora veja o que acontece
quando eu bato em Er. Na verdade, ele executa nosso software, compila e o executa
e, em seguida, nos fornece o
resultado desse método Você pode ver que ele realmente
fez isso na época do design. Meu software nem estava em execução, ele me deu
o valor nove. É uma ótima maneira de
testar coisas como métodos, avaliar expressões
no momento do design, mas também no tempo de execução Ele também pode fazer isso enquanto
o software está em execução. Isso é muito inteligente, não é? Se eu colocar um ponto de interrupção, talvez aqui, por exemplo, vamos limpar a janela
imediata, podemos escrever, clicar nela e clicar
em Limpar. Tudo isso simplesmente
sairá pela janela para nós. Então, agora aqui em cima eu
tenho um ponto de interrupção no cálculo de resultados
duplos. Antes mesmo de chamar o método, estou interrompendo o programa, então nada mais
vai continuar Eu executo o aplicativo
clicando
no botão verde play ou pressionando cinco. Isso
não importa. Agora estamos pedindo o primeiro
número cinco e depois quatro, e então eu quero
somar esses números. Agora, o programa
parou de ser executado. Se eu descer até aqui, no canto inferior, tenho essa
janela imediata aqui. Então eu posso fazer muitas coisas aqui. Eu posso executar esse método novamente. Por exemplo, enquanto
o código está sendo executado, um recurso útil é que,
enquanto o código está em execução, temos esse Intellisense,
o Na verdade, está nos fornecendo todas as variáveis do
escopo, como a número um. Número dois, podemos passar informações
personalizadas, se quisermos. Se eu disser 54 e mais, assim como fizemos antes, depois pressionar Enter, podemos
realmente obter o resultado. Mas você pode ver aqui, nada realmente
aconteceu aqui. Ainda podemos continuar
com esse cálculo. Isso é muito legal, não é? O que eu também posso fazer é
usar variáveis existentes. Agora eu tenho o número
um, o número um. Se eu for até aqui e
destacar esse valor, você pode ver que o usuário
deu o número cinco e o número dois
ele deu quatro. E o operador, eles
usaram um plus ali mesmo. O que podemos realmente fazer
é usar essas variáveis. Na verdade, podemos ver o resultado antes mesmo de
o método ser executado. Bem, talvez eu
queira multiplicá-los. Então você pode ver aqui cinco
multiplicado por quatro é 20. Assim, você pode ver que a janela
imediata pode realmente interceptar
várias coisas Avalie expressões,
execute métodos, muitas coisas assim. Enquanto isso, o código está
realmente no modo de interrupção. Esse método ainda nem foi
executado, por exemplo. Agora, há um
pequeno detalhe nisso. Nesta
janela imediata aqui embaixo, chamei o
método de cálculo duas vezes agora. Mas imagine se o cálculo
fizesse outra coisa, talvez contasse algo
em segundo plano. Toda vez que eu executo
o calcule, ele mantém
uma contagem, um total de
quantas vezes eu o chamei Agora, a execução desse método
na janela imediata
afetaria os resultados. É como se esse método estivesse realmente
sendo executado agora, o que poderia
causar vários problemas. Então, dependendo do que
seu código faz, se você mexer na janela
imediata aqui, isso pode afetar os
resultados aqui Realmente depende do
que seu código faz. Para algo como
calcular, bem, ele realmente não
armazena nenhuma informação. Não conta nada. Ele não mantém um total contínuo de quantas
vezes foi chamado. Portanto, é muito seguro executar
na janela imediata. No entanto, há
casos em que não seria seguro, por exemplo, por
esses outros motivos Isso é apenas algo
digno de nota. Então, deixe-me demonstrar isso. Agora, só para ilustrar do
que estou falando. Digamos que esse
método de cálculo mantenha um registro contínuo de quantas
vezes ele foi chamado Mas usamos essa contagem contínua
para propósitos importantes. Talvez algo
mais dependa disso. Esse campo apenas registrará
quantas vezes o método de cálculo
está sendo chamado Quando o
método de cálculo for chamado, vou incrementar
esse campo
local em um a cada Então, se eu executar o aplicativo agora, vou definir um ponto de
interrupção aqui para que possamos pausar a execução
do software Vou digitar
alguns exemplos de figuras, como cinco mais quatro. E então eu vou
até
a janela imediata aqui. Passe o mouse sobre esse campo
privado aqui. Numb times, você pode ver que o
valor atualmente é zero. Mas se eu executar esse método
dentro da janela imediata, talvez ele seja executado três vezes. A propósito, ao pressionar a seta
para cima no teclado, posso ver minhas
coisas anteriores que digitei aqui Então isso é muito legal, não é? Então, eu executei o
método de cálculo três vezes, mas somente na janela
imediata. Se eu chegar aqui e passar o mouse sobre minha variável privada aqui, você pode ver que ela tem o valor
de três coisas em seu código são afetadas por qualquer coisa que você faz na
janela imediata aqui embaixo Portanto, é muito importante e é algo que você
deve conhecer. Novamente, obviamente,
tudo é reiniciado quando você executa seu aplicativo Mas, no que diz respeito à depuração, vale pena notar Então, acabei de falar
sobre o fato que, ao usar a janela
imediata, por exemplo, para chamar métodos, pode mudar coisas em seu código. Agora, esse pode ser um comportamento
desejado, talvez você queira fazer isso
e está perfeitamente bem. Mas há situações,
como em nosso exemplo
anterior, em que incrementamos
uma variável, por exemplo Mas precisamos disso
aqui e não
queremos que nada em nossa
janela imediata mude isso. Mas ainda queremos
executar o método a partir
da janela imediata. Bem, há algo que
podemos realmente fazer para superar esse problema na janela
imediata em eu chamo o método, que quer que você coloque aqui, seja chamando um método, avaliando uma expressão, descobrindo o
valor de uma variável, você pode simplesmente sufixá-lo
com um pequeno comando chamado S E que significa
“sem efeitos colaterais Você pode ver quando eu digito
que o Visual Studio
nos dá uma boa indicação agora. Se eu chegar aqui, você pode
ver nossa variável aqui, o número de vezes é zero. Eu volto para
a janela imediata e pressiono Enter. Então você pode ver que o Calculate
realmente calculou os números. Ele somou esses
números, mas eu especifiquei esse sinalizador de
ausência de efeitos colaterais. Se eu voltar
aqui e colher várias
vezes, ele ainda retém o valor
zero ao especificar SE, isso significa que nenhum efeito
colateral acontecerá como resultado de você chamar esse método na
janela imediata Isso é muito legal, não é? Esse é um dos recursos
que você pode fazer com isso. Então, chamamos
métodos com mudanças, chamamos métodos
sem alterações. Bem, o que mais podemos fazer
na janela imediata? Bem, podemos ver
os valores das variáveis. Então, por exemplo, número um. O que é isso? Oh,
o número um é cinco. Isso é muito legal, não é? Portanto, sempre coloque um ponto de interrogação como prefixo. E, obviamente, essas são
apenas variáveis no escopo. Então, por exemplo, se essas
variáveis não têm um valor, ou ainda não
foram alcançadas, ou não
foram inicializadas
, obviamente você não pode
ler os valores delas Portanto, é apenas o que é
chamado de escopo, que realmente temos acesso. O que também podemos fazer é
calcular expressões, por exemplo, cinco mais
sete, por exemplo. Isso nos dará o resultado e podemos fazer isso
com variáveis, então o número um dividido
pelo número dois. É muito legal, especialmente
quando você está depurando, você insere alguns números de
amostra, mas você pode interromper a execução
do código e brincar
com ele em tempo de execução , em
vez de reiniciar
o aplicativo, tentar alguns números,
reiniciá-lo novamente, tentar mais números novamente Você pode ver como a janela
imediata acelera esse problema. Você pode simplesmente inserir
o que quiser e talvez esteja tentando
localizar um erro ou um problema. Ele oferece uma maneira muito rápida, fácil e dinâmica de
tentar localizar esses
problemas e erros. É por isso que a janela imediata é muito legal nesse sentido. Mas não só podemos simplesmente chamar
métodos e analisar valores, também
podemos atribuir
valores. Se observarmos o valor
do número um que o usuário inseriu é cinco
e ele digita o número dois, que é seis. E a operadora foi uma vantagem, então vamos obter 11. O que podemos fazer é realmente
alterar os valores das variáveis. Em vez de somar cinco
a seis e obter 11, dizem que o número
um é igual Agora, o número um é igual a 11. Vamos fazer com que o número dois
seja igual a 12, por exemplo. E vamos deixar a
operadora como uma vantagem. Agora mudamos para
essas duas variáveis. Vamos subir aqui agora. Se passarmos o mouse sobre
essas variáveis, você pode ver que o número um agora é 11 e o número dois agora é 12 Modificamos os valores
dessas variáveis durante modo de
pausa enquanto o software está funcionando na
velocidade da luz, como
falamos antes. Na verdade, modificamos
as coisas em tempo de execução. É uma loucura, não
é? É incrível. Agora, se eu pressionar cinco e continuar com a
execução do software, você verá que o resultado é 23. O usuário inseriu 5.6, mas
nós meio que entramos lá, modificamos algumas coisas, mudamos essa para 11 e
essa para 12 Assim, você pode ver que o
resultado é o reflexo da mudança que fizemos
na janela imediata. Então isso é muito legal, não é? Então imagine que a
janela imediata é como um pequeno bloco de notas
onde você pode
brincar , mudar
coisas e ligar para coisas Esse é o poder da janela
imediata no Visual Studio ao
trabalhar com o C shop.
56. 11-3. Windows para locais e automóveis: Continuando com nosso
tópico sobre depuração, falarei sobre a janela de locais e
também sobre
a janela de automóveis.
O que eles são? Bem,
janelas locais e automotivas só estão disponíveis durante uma sessão de
depuração Precisamos entrar no
modo de depuração e dar uma olhada nessas janelas e, em seguida,
mostrarei o que elas
têm a oferecer para você O que vou fazer agora é adicionar um ponto de interrupção. Aqui está meu
aplicativo de calculadora simples, onde eu adiciono, subtraio ou multiplico
números Então, várias coisas aqui. Vou apenas
estabelecer um ponto de interrupção aqui sem nenhum motivo
específico Então eu vou executar
o aplicativo no modo de
depuração porque queremos
fazer alguma depuração,
o software está rodando, ele está me
pedindo dois números Vou apenas colocar alguns dados
de amostra lá. Agora, o código foi pausado, execução e nosso
ponto de interrupção foi atingido Agora, o software
está congelado no tempo e podemos fazer o que
quisermos com ele. Se chegarmos até
o canto inferior esquerdo, no meu caso, você pode ver
que temos algumas guias
aqui, várias guias Um é chamado de locais e o outro
é chamado de Autos. Aqui mesmo. Se você não encontrar nenhum desses, acesse o menu de
depuração e vá para o Windows E há
algumas opções aqui chamadas automóveis e habitantes locais Agora, talvez você não veja
essas opções de menu a menos que esteja em uma sessão de
depuração Portanto, verifique se você está
depurando no momento e se eles
devem aparecer Você também pode usar esses atalhos de
teclado, uma vez que essas
janelas estejam visíveis aqui embaixo O que essas janelas oferecem
é uma visão
em tempo real das variáveis quando examinamos a janela
imediata anterior, onde podíamos ver
os valores das variáveis
com o ponto de interrogação. Antes de imaginarmos isso como uma interface gráfica de usuário para a janela imediata em termos de
leitura de variáveis, objetos
e coisas assim. De qualquer forma, você pode ver que eu pausei a execução do código
dentro desse método de cálculo Aqui já temos
valores para um, número dois e também para o operador. Nosso resultado atualmente é zero porque não
temos um valor definido. Então, se olharmos nesta janela de
locais aqui, podemos ver todos esses valores para essas variáveis em
uma janela fácil Assim, podemos
ver claramente o que o usuário nos
deu e qual pode ser
o resultado. Além disso, se
clicarmos duas vezes no valor aqui, podemos realmente alterar essas
informações em tempo real, assim como antes
na janela imediata, podemos alterar esses valores. Eu vou para o resultado,
posso até mesmo modificar o resultado antes
mesmo de ser inicializado E além de alterar
o operador, por exemplo, ela não fornece
apenas uma visualização somente para leitura, também
pode modificar
essas variáveis e
as alterações serão refletidas durante sua sessão de depuração Então, isso é muito legal, não é? Então, examinamos
a janela de locais aqui, onde podemos ver nossas variáveis aqui e também
alterar alguns dos valores Agora, eles estão disponíveis
no escopo atual. Então, o que isso significa é que eu
estabeleci um ponto de interrupção aqui. Estamos dentro desse método, esse é o escopo atual. Podemos acessar essas
variáveis aqui, mas não podemos ler nada
fora desse método. São apenas coisas
no escopo local. O que é local para nós aqui? Isso é o que se reflete
na guia local aqui. Vamos falar sobre a janela de
automóveis agora e também como a janela de automóveis
difere da janela local Eles são muito parecidos
na forma como se comportam. Você pode alterar
os valores das variáveis e coisas assim. Você pode ver o valor de
variáveis e objetos, mas por que eles são diferentes? A janela de automóveis aqui exibe informações
sobre a linha atual Quando eu digo a linha atual, o ponto de interrupção atual, você vê que o software
está pausado aqui, indicado por esta parte
destacada em amarelo Podemos ver variáveis e
objetos nessa linha atual. Aqui mesmo, temos o resultado. Além disso, também podemos ver as informações na linha
anterior. Agora podemos ver um número de vezes, e se eu ultrapassar
isso usando dez. Então, a execução do código
vai para a próxima linha, você pode ver as informações alteradas em nossa janela de automóveis Na verdade, a principal
diferença entre automóveis e locais é
que os automóveis fornecem a linha atual e
a anterior, e os locais fornecem tudo
no escopo Você pode ver que a
janela de habitantes locais aqui não inclui horários não incluídos, porque
nós a definimos aqui Portanto, você pode ver que é um campo privado
estático da nossa classe de programa,
portanto, não está aparecendo
na janela de locais. Os habitantes locais são apenas coisas
locais para você. As coisas locais
no escopo e nos automóveis são a
linha atual e a anterior Essa é a principal diferença. Mas uma coisa que ainda não
discuti é que tanto as janelas locais quanto as janelas
automáticas podem
avaliar expressões. Se eu for até aqui, por exemplo, onde diz resultado, posso fazer o que fizemos
na janela imediata anterior, onde avaliamos
certas coisas. Eu poderia dizer que o resultado
é cinco mais quatro, então você pode ver que o
resultado é nove. Também posso usar variáveis
existentes. Número um, por exemplo, mais 567 e isso será avaliado, para que você também possa
avaliar expressões nas janelas locais e
automáticas Eu configurei um
aplicativo de amostra aqui que usa alguns objetos mais
complicados. Eu tenho uma
classe de videogame que é passada em algumas coisas
para o construtor Eu tenho uma lista de usuários e estou adicionando três
objetos de usuário a essa lista e também criando uma
lista de números inteiros Então, algumas
coisas bem complicadas aqui. Eu coloquei um ponto de interrupção
no final. Então, vamos entrar em
uma sessão de depuração
e, em seguida, nosso ponto de interrupção
será atingido
e, em seguida, veremos
a janela local para ver
como isso pode parecer a janela local para ver
como Vou
estender isso um
pouco para que possamos ver
um pouco melhor. Você pode ver aqui, isso é
praticamente tudo aqui. Agora eu tenho essas
flechas. Olha porque esses jogos são objetos mais
complicados Eu posso simplesmente clicar nesta seta. Na verdade, posso ver
todas as propriedades e várias coisas aqui dentro. Agora, esse pequeno
tem um cadeado, o que significa que é um campo
privado aqui Mas isso tem uma
pequena chave, que significa que é uma propriedade Eu posso modificar os
valores aqui, para que você possa ver que eu posso usar um visualizador de
texto para ver
isso, para que eu possa ver os
valores do título Se eu clicar duas vezes no valor, posso modificar várias
coisas aqui. Eu poderia dizer que é
para um Macintosh,
assim como antes, quando tínhamos variáveis
simples, tipos de valores
simples Eu poderia mudar os valores. Mas mesmo com
objetos complicados como esses, também
posso alterar os valores e ver a hierarquia
deles Para esta aqui, a lista de usuários,
posso expandir isso. E então eu posso expandir os
membros lá dentro e ver vários nomes, idades
e coisas assim. Portanto, é muito útil
e muito poderoso. Durante uma sessão de depuração, você pode visualizar o estado
de todos os seus objetos, sejam eles tipos de valores complicados
ou simples, ou dentro de uma
janela gráfica É realmente incrível. E se olharmos para a guia de automóveis, eu disse que a guia automática
exibe informações sobre o ponto de interrupção atual e também a linha
executada anteriormente Nesse caso, adicionamos um
ponto de interrupção nessa linha vermelha. A última declaração que foi
executada foi esta linha aqui. Portanto, esse objeto é
disponibilizado em nossa janela de automóveis Se você tiver um software muito
grande, talvez com centenas
ou milhares de objetos e variáveis
no escopo atual, também
poderá
pesquisá-los. Então, é realmente muito
útil como isso funciona. E você pode especificar
uma profundidade de pesquisa, o que significa apenas quantas
setas podem exibir
os resultados da pesquisa Então, você pode ver que também há muitas opções de profundidade. Mas esse é realmente o princípio por trás dos habitantes locais
e das janelas automáticas Ele permite que você visualize e
também altere variáveis. Mas, ao contrário
da janela imediata aqui, ela oferece uma boa interface gráfica de
usuário para trabalhar. E também fornece o estado de como são esses objetos, esses campos privados, essas propriedades públicas. Portanto, é realmente muito
útil nesse sentido.
57. 11-4. Assista ao Windows e assista rápido: Vou falar
sobre assistir agora, e isso está novamente relacionado à
depuração no O que está assistindo especificamente? Eu vou falar
sobre o Quick Watch e o Windows.
Então, o que eles são? Se você assistir meu outro tutorial sobre Windows local e automotivo, ele funciona de forma muito
semelhante a A única diferença com uma janela de observação é que
podemos escolher o que adicionar nela. Mas não só isso, podemos
avaliar expressões. Então, o que tudo isso significa? Vamos dar uma olhada. Então, agora eu tenho um aplicativo de amostra, nosso pequeno
aplicativo de calculadora. Se você está acompanhando
nossos outros tutoriais, acabei de adicionar um ponto de
interrupção aleatório Estou no modo de depuração, estou entrando em uma sessão de depuração O depurador está conectado
ao nosso software. Está pedindo dois números e um operador, cinco mais seis. Agora que nosso ponto de interrupção
foi atingido, o software está congelado. Podemos examinar as
variáveis agora. Chegamos aqui e temos
nossa conhecida janela de locais, onde podemos ver
o valor
das variáveis atuais
no escopo atual O número um é cinco,
o número dois é seis, o operador é mais e o resultado é 11. Esses são valores de todas as variáveis no escopo atual. Agora observe a janela. Se chegarmos aqui para depurar
e depois entrarmos na janela, e você
verá que há o relógio 123.4, isso significa que podemos ter até quatro relógios no
Windows, quatro Vamos falar sobre o que realmente é uma sessão de
exibição. Vou clicar em Watch One. E se chegarmos aqui, você pode ver que há uma guia
Watch One que foi criada
junto com moradores locais,
automóveis, e agora
temos uma Watch E você pode ver aqui que
diz adicionar item para assistir. O que isso significa? Bem,
podemos assistir a qualquer coisa. Nós queremos muito
gostar de variáveis, objetos. Por exemplo, se eu
chegar aqui para ver o código, temos essas variáveis aqui. O número um é o número dois é seis. Se eu clicar com o botão direito do mouse no número um, posso acessar esse menu
e clicar em Adicionar relógio. Eu vou fazer exatamente a
mesma coisa para o número dois. Clique com o botão direito em Adicionar relógio. Se chegarmos até a
janela de observação aqui embaixo, podemos ver que funciona
quase como a janela de nossos habitantes locais. Temos as variáveis que
adicionamos, temos os valores e também podemos alterar os
valores se quisermos. Você pode se perguntar: por que eu
não uso
a janela local? Ele faz exatamente a mesma coisa. Praticamente a principal
diferença entre a janela de observação e a janela
local é que, no relógio, você pode adicionar o que quiser e também pode
adicionar expressões Por exemplo, eu poderia dizer o número um mais o número
dois e depois pressionar Enter. Eu adicionei uma
expressão personalizada aqui. Agora, durante a vida útil da minha sessão de praticamente
depuração, sei qual é o valor de um mais
número dois, ou eu coloquei o número um
lá mais o número Se eu puder aprender a digitar é 11. Você pode ver que eu posso colocar
expressões aqui. Eu poderia dizer o número um
multiplicado pelo resultado. Eu posso colocar várias coisas
personalizadas aqui. Essa é basicamente uma
das principais diferenças entre a janela do relógio
e a janela local. O que eram aquelas janelas do
relógio 1234. Se chegarmos aqui para
depurar novamente, então Windows, depois assista e clique em Assistir
para voltar aqui Agora temos outra guia de observação, então podemos adicionar outras
variáveis aqui. Agora, essas janelas extras
são praticamente úteis
apenas quando você tem um aplicativo
muito grande. Você quer isolar
certas variáveis de
outras variáveis apenas
para que elas fiquem mais organizadas e você
não se confunda Se você estiver trabalhando talvez em
um aplicativo de calculadora, talvez
queira colocar todas
as variáveis monitoradas nessa janela de observação. Talvez o
aplicativo de calculadora tenha outro recurso que trate de
algo totalmente diferente. E então você coloca as variáveis do
relógio aqui. Você está organizando suas
variáveis e expressões. Você pode ter até quatro janelas de
relógio, se desejar. Esse é um dos benefícios e poderes da janela do relógio. Além de visualizar e alterar variáveis, como as janelas
locais, você
também pode adicionar
expressões aqui. Isso é muito legal. Você não está limitado apenas às variáveis básicas. Você pode até mesmo chamar métodos. Por exemplo, eu tenho um
método chamado calcular. E então eu posso calcular, digamos quatro mais oito, por exemplo. E então eu posso colocar isso lá e isso também é
avaliado. As expressões não estão
vinculadas apenas a variáveis simples, mas também podemos colocar chamadas de
métodos inteiras aqui. É muito poderoso
e também muito útil especialmente ao depurar aplicativos
muito grandes E uma coisa que mencionei
no início
deste tutorial foi o Quick
watch. O que é o Quick Watch? Imagine que você só quer assistir a uma variável simples
muito rapidamente. Digamos que você queira verificar rapidamente o valor de
uma variável. Esse é praticamente o único
propósito do Quick Watch. Se eu escrever, clique no número
um, por exemplo, e clique em Quick Watch ou Shift F nove,
essa janela será exibida. E quando essa janela aparecer, você não poderá continuar a depuração Você. Praticamente
estou preso aqui. Aqui, estou observando rapidamente
a variável número um, posso alterar seu valor, posso reavaliar o que eu
quiser. E também posso alterar ou
inserir qualquer outra expressão. Então, eu poderia dizer calcular. E também tem preenchimento automático
aqui. Então, se eu quiser dizer cinco
mais quatro e pressionar Enter, posso fazer
expressões rápidas rapidamente, mas você tem esse tipo
de diálogo irritante E, para ser sincero, prefiro usar apenas a janela do relógio porque ela faz tudo o que o relógio
rápido faz. Mas estou apenas
destacando porque
sei que algumas pessoas
preferem usar Pessoalmente, não tenho certeza do porquê. Mas está lá se você precisar. Então, essa é essencialmente
a mensagem que estou tentando transmitir. Mas a janela do relógio faz
tudo o que o relógio rápido faz. Então esse é o poder das janelas de
relógio em C Sharp.
58. 12-1. O modificador de acesso protegido: Quero falar sobre o
último modificador de acesso que
ainda não discutimos e que está protegido Já falamos sobre
público, privado, interno, mas agora vamos
falar sobre protegido. Agora, protegido é uma
palavra-chave que geralmente é usada quando você está herdando
classes em C Sharp Então, se você ainda não viu
o tutorial que fiz sobre herança e,
enquanto estamos nisso, se ainda não viu
o tutorial que fiz sobre configuração de vários
projetos no Visual Studio
, recomendo fortemente que
você os confira primeiro Aqui temos um exemplo muito
básico. Eu tenho uma aula principal aqui. Ele apenas configura quatro objetos
de videogame aqui. Se olharmos para a aula de
videogame aqui, não está acontecendo muita coisa. Ele tem um campo privado
e um construtor e herda de uma classe principal baseada
no jogo aqui E chama o
construtor de jogos daqui. Muito simples, nada que
não tenhamos visto antes. Se olharmos para a classe base, ela tem três campos privados. Ele tem um construtor
, um exemplo de método público e alguns exemplos de propriedades
públicas aqui Aqui temos muitas
coisas públicas acontecendo aqui. Agora, a palavra-chave protegida, ela se aplica a métodos como esse e também a propriedades. Se algo estiver
marcado como protegido, ele estará disponível apenas para
a classe atual, por exemplo, jogo e qualquer coisa descendente disso, todos os seus filhos Pense nisso. Se você é como
a mãe de uma família, então você só quer compartilhar coisas
protegidas com seus filhos ou
netos, por exemplo Então pense assim,
está protegido agora. Esse é um método público. Aqui. Tudo o que faz
é pegar o nome e
juntar algumas sequências e
a editora, no
momento, é pública Assim, podemos acessar
isso de qualquer lugar. Podemos acessá-lo em
nosso programa principal. Podemos acessá-lo a partir do
videogame, sem problemas. O que eu vou fazer é tornar isso protegido, então você pode ver que há
a palavra-chave protegida. Agora eu fiz isso. Se eu instanciar
essa classe aqui, jogo da classe principal Agora, a turma principal não
é filha dessa classe
, então não será. Deixe-me fazer isso,
deixe-me provar isso para você. Agora você pode ver aqui que quando eu
tento acessar o método, ele nem está
nessa lista. E veja o que acontece se
eu tentar acessá-lo de qualquer maneira, ignorando o preenchimento automático do Visual
Studios Se eu passar o mouse sobre
isso, ele diz que está inacessível devido ao
seu nível de proteção E isso é
porque está protegido. Portanto, ele só está disponível na classe atual ou nas classes
secundárias dessa classe. Por exemplo, videogame, videogame é uma classe infantil porque estamos
herdando daí Se apenas dissermos base, por exemplo, então estamos acessando a classe
base que é o jogo. Agora podemos ver esse
método, ele está na lista
e, quando tentamos acessá-lo, não
há nenhum erro. Esse é o poder da palavra-chave
protegida em C sharp. Mas existem algumas combinações que,
na verdade, podem ser combinadas com protegido, seja, protegido
internamente, protegido como privado, protegido como privado e
protegido interno. Essas são algumas
combinações que podemos usar ao lidar com o modificador de acesso
protegido Portanto, podemos basicamente
dobrar os modificadores de acesso, mas somente quando usamos protegidos Você pode ver aqui
que podemos usá-lo em três combinações por si só, que é o que
já discutimos. Está disponível
na mesma classe. Métodos e propriedades
estão disponíveis
na mesma classe ou em
qualquer um de seus filhos. Discutimos isso a
seguir, privado protegido. Se algo estiver marcado
como protegido ou privado, um método ou uma propriedade, ele
poderá ser acessado
na mesma montagem, mas também de dentro
da mesma classe derivada. Se nossa turma de jogos aqui
estiver no mesmo projeto, na mesma montagem de nosso filho, o que seria videogame. Se eles existirem
no mesmo projeto, na mesma montagem, podemos
fazer uso desses métodos. No entanto, se esse arquivo de jogo aqui estiver em um projeto diferente, não
poderemos acessar os
métodos e propriedades dessa classe filha que
é protegida de forma privada. Então, deixe-me mostrar
um exemplo disso. Agora vou marcar Publisher. Esta é uma propriedade de loja aqui. Editora, vou
comercializar como proteção privada. Agora, se essa classe existir fora
do conjunto de chamada, onde quer que queiramos
usá-la, ela não funcionará. Vamos dar uma olhada em um
exemplo disso funcionando. Podemos dizer editora. Podemos acessar isso, sem problemas. Se eu apenas disser que
uma string é igual a editor, não
há problema
porque podemos acessá-la Agora, deixe-me mudar essa classe para cá. Classe pública, principal, fora
da assembléia atual. Se você viu meu tutorial
sobre vários projetos, provavelmente saberá
como fazer isso. Se virmos aqui para
o lado direito, obteremos nossa classe de jogo. A turma principal, vou
simplesmente arrastar e soltar para o segundo
projeto que criei. O princípio é que eu
simplesmente não quero mais
isso neste projeto agora,
vou excluí-lo. Agora o jogo está em um projeto totalmente
diferente aqui. Agora o jogo está em uma montagem totalmente
diferente aqui. Podemos voltar para nossa aula de
videogame aqui, que está na outra montagem. Vá até aqui agora, você pode
ver que ocorreu um erro. Então, ele ainda pode encontrar um jogo porque estamos encaminhando
os outros projetos, para que ele saiba onde está. Você pode ver que estamos
herdando de lá. No entanto, agora uma
linha vermelha apareceu. E se você passar o mouse sobre
isso, diz que o editor está inacessível devido ao
seu nível de proteção Isso é porque nós o
tornamos privado protegido. Se algo é protegido de forma
privada
, deve estar
na mesma montagem, ou
seja, no mesmo projeto. E tem que ser um descendente
dessa classe que é
protegida como privada Agora que entendemos
proteção privada, a mesma assembléia e uma criança, é muito fácil explicar
o que é proteção interna. Que pode ser um, qualquer descendente da classe, mas pode estar em
qualquer outra assembléia Não importa onde, por exemplo, a
classe base esteja localizada. Pode ser em um projeto totalmente
diferente. Mas, desde que seja
protegido internamente, devemos ser capazes de acessá-lo. No momento, temos esse erro
devido ao nível de proteção, porque o videogame e o jogo
estão em montagens diferentes Volto ao jogo, agora
faço essa propriedade aqui,
protegida, interna ou protegida internamente. Então, eu
configurei isso lá, volto ao videogame e agora você pode ver que o
erro desapareceu. Então essa é a diferença
entre
proteção privada e proteção
interna. Significa apenas que a classe
base deve estar na mesma montagem
ou não na mesma montagem. Então, esses são os três tipos de modificadores de
acesso quando se lida com proteção, ou
seja, a classe base
e seus filhos E então podemos
dobrá-la com privada ou interna,
dependendo se a classe base está
na mesma montagem ou em
uma montagem diferente. Então esse é o modificador de
acesso protegido na loja.
59. 12-2. A palavra-chave estática: Agora vou falar
sobre a palavra-chave estática. Você pode ter visto
isso se estiver
acompanhando nossos outros tutoriais Essa pequena palavra-chave aqui chamada estática, o que isso
significa? O que isso faz? E
por que devemos usá-lo? Vamos dar uma olhada
nesse exemplo aqui. Estou apenas definindo quatro objetos de
videogame aqui e chamando o construtor
com três parâmetros Se eu olhar dentro da aula de
videogame, ela tem apenas três campos
privados. Aqui está o construtor que
define os campos privados. Eu só tenho um exemplo de método aqui que retorna o título. E apenas um exemplo de
propriedade aqui que torna o editor muito básico. Se eu tivesse uma aula como
essa, por exemplo, como eu poderia registrar o número
de videogames que
tenho em minha coleção? Este é apenas um
exemplo do que eu poderia fazer toda vez que instanciasse
a classe de videogame Eu poderia acompanhar um contador. Este contador pode registrar quantos videogames eu tenho Na minha coleção, eu
inicializo um contador com zero. Toda vez que eu crio
um videogame, posso incrementar o
contador em um Eu poderia fazer algo
assim, por exemplo. Isso funcionaria perfeitamente bem. Mas não parece
muito elegante, não é? Além disso, ele realmente
não segue muito bem
os princípios da
abstração Gostaríamos de manter
esse contador talvez escondido na aula de
videogame, por exemplo. Como conseguiríamos isso? Como poderíamos fazer
isso se configurássemos um contador dentro dessa classe de videogame,
por exemplo, aqui. Então, no construtor
dessa classe, eu incremento o contador No entanto, o problema é que esse contador pertencerá
a cada instância. Então, se eu for até aqui e a partir do primeiro jogo, posso
acessar o contador, mas ele só terá
o valor de um porque o contador pertence a
cada instância separada. Então, como faço para ter
um contador global, algo dentro desse
videogame que acompanha o número de instâncias
dessa classe que criamos. Agora é aqui que entra a palavra-chave
estática. Quando usamos a palavra-chave static ,
podemos usá-la em construtores ,
em campos , em métodos e até
em toda a classe Por exemplo, se eu definir esse
campo do contador como estático
, esse campo será
compartilhado entre todas
as instâncias que foram
criadas a partir dessa classe. É um campo de nível de classe. Qualquer coisa com estática dentro
da classe pertencerá ao nível da classe e não ao nível da
instância, como aqui. Por exemplo. Vamos dar uma
olhada em um exemplo disso. Toda vez que eu crio um
novo videogame aqui, quero que dentro do meu construtor aqui tenha um contador
que incremente Isso manterá um
registro do número de videogames em
nossa coleção Por exemplo, o que eu poderia fazer simplesmente fazer uma
linha de amostra aqui que grava no console quantos videogames temos em nossa coleção. Toda vez que construo um novo objeto da classe de
videogame, estou incrementando o contador, que é estático, está no nível da
classe em um a cada vez Em seguida, estou enviando uma mensagem para a janela do console que apenas expressa quantos
jogos eu tenho na minha coleção quando
executo este programa Toda vez. Isso é construído aqui porque estamos
criando uma nova instância, o contador será
incrementado em um a cada vez Vamos dar uma olhada nisso.
Agora você pode ver aqui, ele está aumentando
em um toda vez esse contador está sendo compartilhado
por todas essas instâncias Aqui, é muito inteligente como
a palavra-chave estática funciona. O que também podemos
fazer, por exemplo, é ter um método estático. Por exemplo, posso criar um método estático que obtém
o resultado do meu contador. Vamos dar uma olhada
nisso. Em vez disso, vou remover essa linha aqui. Por enquanto, vou
criar um método estático. O que esse método faz é
apenas retornar o contador. E é um método em nível de classe, que significa que o acessamos
a partir da classe e não de uma instância. Vamos dar uma
olhada nisso agora. Se eu entrar no programa
principal aqui, se eu for para o primeiro jogo, por exemplo, agora o
primeiro jogo é uma instância. Esse método não
aparecerá nessa lista. Você pode ver que não há nenhum método
get counter aqui. Isso porque é
um nível de classe. Nesse caso, eu teria que
digitar o nome da classe. Então, quando eu coloco um ponto após
o nome da turma, esses são todos os membros do
nível da turma aqui. Então você pode ver esse método
aqui chamado get counter. É um nível de classe,
não de instância. E agora podemos obter o número de videogames em nossa
coleção, assim. Se quisermos enviar
isso para o console, podemos simplesmente copiar
esse método aqui,
colocá-lo aqui e, em seguida,
excluir o ponto e vírgula Agora vou executar
o aplicativo. Você pode ver que temos
um resultado semelhante. Estou apenas obtendo
o total geral
do número de
videogames da minha coleção. E agradeço por ter escrito coleção de forma errada, mas
ninguém é perfeito Esse é um exemplo
de um método estático e também de um
campo estático em C Sharp. Talvez essa palavra-chave estática
que vimos em todos os nossos tutoriais até agora
esteja começando a fazer sentido Agora, nossa classe principal aqui
é chamada de programa. Por padrão, há um método
chamado main que é estático. Esse método principal é um método
de nível de classe. Por padrão, é o
primeiro método executado quando
o programa é executado. Se eu criar um novo método aqui, por exemplo, acabei de criar
um método como esse. Eu tento chamar esse
método do principal. Esse é um método estático. Esse não é um método estático. Veja o que acontece. Então você pode ver que há uma linha vermelha aqui. Se eu passar o mouse sobre isso,
ele diz que a
referência do objeto é necessária para o teste não estático do campo ou do programa de
propriedades Isso porque estamos chamando um método não estático de um método estático
que não é permitido. Se algo não
for estático , é um método em
nível de instância. Porque estamos dentro de
um método estático. Aqui, não há
instância para operar, não
criamos uma instância, não
estamos dentro do
método de uma instância. Não há nada a ver com os
casos que estão acontecendo aqui. Estamos dentro de um método estático, mas estamos tentando chamar
um método em nível de instância. Não vai funcionar. Em casos como esse, você
precisaria criar uma instância. Isso é só um exemplo. De qualquer forma, eu não
recomendaria que você criasse uma instância da classe do
programa, mas isso só ajuda na minha
explicação aqui. Depois de colocar a instância antes desse método de
nível de instância, você pode ver que o erro
foi resolvido porque qualquer coisa que não seja estática
deve pertencer a uma instância, é um nível de instância. O que também poderíamos fazer em vez
disso é apenas simular esse
método como estático Dessa forma, estamos chamando
um teste
de método estático a partir de outro
método estático. Outra coisa que podemos fazer com a palavra-chave static é marcar
uma classe inteira como estática. O que fazemos é pegar
a palavra-chave estática e colocá-la ao lado da definição da
classe aqui no topo. Quando você faz isso, tudo dentro da classe aqui também
deve ser estático. Porque se você definir
isso no nível da classe
, isso implica que tudo
dentro deve ser estático. É por isso que todos esses
erros estão aparecendo aqui. Mas a principal
coisa importante sobre marcar estática de
uma classe
é que não podemos criar instâncias
de classes estáticas. Eles são abstratos e
selados implicitamente. Se você se lembrar de uma classe
abstrata, não
poderá criar
uma instância dela. E se você se lembra
de uma classe selada, não
pode herdar dela Então isso está implícito, é por isso que temos
todos esses erros aqui ao criar
uma nova instância, então não podemos mais fazer isso Vamos dar uma olhada em como transformar essa classe em uma classe
puramente estática Aperte o cinto e
aperte o cinto. Vamos. Todos esses
campos privados devem ser estáticos. Agora, nosso construtor
em uma classe estática, ele deve ser estático Mas construtores estáticos
não podem ter modificadores de acesso. Não podemos ter público lá. Além disso, ele não pode ter parâmetros. Vamos remover esses dois também. Essa palavra-chave é irrelevante
porque tem a ver
apenas com instâncias
que também precisam desaparecer. Agora, todos os nossos métodos e
propriedades também devem ser estáticos, e isso deve bastar. Este é um exemplo de uma classe
estática aqui. Agora você pode estar se perguntando, bem, se eu não consigo instanciar
essa classe, então como esse
construtor é chamado,
por exemplo, o que está
acontecendo aqui Bem, por padrão, quando você
executa o aplicativo e
acessa essa classe, esse construtor é executado pelo
ambiente de tempo de execução uma vez Isso será executado
automaticamente uma vez. Qualquer coisa aqui no construtor,
o construtor estático deve inicializar qualquer variável ou qualquer
coisa que você queira fazer Esse é o propósito de
um construtor estático em uma classe estática Agora, se chegarmos
ao nosso arquivo principal aqui, você verá que não podemos criar instâncias da classe estática. Só podemos acessar
coisas em nível de classe. Agora, marquei tudo
como estático. As propriedades, os métodos, é assim que nos
referimos basicamente à classe. Colocamos o nome da classe como
antes e depois um ponto. Então, podemos acessar
várias coisas aqui. E agora, como não há
instâncias para essa classe, todos esses membros existirão uma vez porque esse é
o ponto da estática. Podemos definir um editor
e acessá-lo. Além disso, podemos aumentar nossa contagem de
videogames como fazíamos
antes. Não tem problema. Só para provar que o
construtor é executado uma vez, confira esse método
aqui, onde obtenho o contador do número
de videogames que tenho Vou apenas duplicar esse método, então
ele é chamado duas vezes Vou colocar dois
pontos de interrupção aqui. O código para quando
essa linha é atingida e , em seguida, entra
no construtor e coloca
um ponto de interrupção lá Agora vou executar
o aplicativo, para que você possa ver o que acontece. Agora, o construtor
não foi executado, mas a quebra está
nesta linha aqui Contador de pontos para jogos de vídeo. Se eu passar por cima disso, você pode ver que o construtor
aqui é chamado Se eu passar por cima disso, pegamos o balcão e
vamos para a próxima linha. Se eu passar por cima disso, você verá que nada acontece. O construtor é chamado apenas uma vez nessa primeira linha aqui e é ignorado nas chamadas
subsequentes para qualquer método que
exista no nível da classe Espero que isso tenha feito sentido. É muito difícil entender, mas esse é o objetivo das palavras-chave estáticas:
colocar praticamente tudo
o que
você quiser em nível de classe.
Nesse caso, o conceito de instâncias é praticamente
ignorado nesse aspecto. Eu dei um exemplo de como construtores
estáticos também funcionam O construtor é chamado
automaticamente quando você toca em qualquer
método ou membro
e, em seguida, é ignorado em
qualquer chamada subsequente Depois disso, espero que
isso ajude você. Esse é o poder da palavra-chave
estática na loja.
60. 13-1. A palavra-chave readonly: Neste tutorial,
veremos a palavra-chave somente leitura em C Sharp. Agora, o que a palavra-chave somente
leitura faz? Bem, a
palavra-chave somente leitura é chamada de tipo de dados imutável.
O que isso significa? Isso significa que, uma vez
que você tenha um valor definido dentro de
uma variável ou campo, por exemplo, não poderá modificar esse
valor
depois de definido. O que tudo isso significa e quais outras condições estão
envolvidas nesse processo? Vamos dar uma
olhada em um pequeno exemplo. Aqui eu tenho uma classe chamada Dog Dog tem um construtor que usa um
argumento chamado raça, que é a raça do cachorro Como um terrier ou um
chihuahua, por exemplo. Eu tenho dois campos privados
aqui, raça, e outro representando
apenas um ID exclusivo para cada cão que construímos. E então eu tenho uma
propriedade pública que obtém e também define a raça
do cachorro com o conhecimento que
adquirimos até agora. Se quisermos que os usuários
possam dizer, obtenha o valor da raça, mas não defina o valor que
queremos que seja lido somente então. Se tivermos uma propriedade
como essa, por exemplo, que expõe esse campo
privado aqui
, simplesmente
removeríamos essa
cláusula set aqui Quando tentamos realmente colocar
informações na raça, elas não vão para letras. Então, se eu escolher uma raça de cachorro e
tentar dar um valor a
ela, realmente não importa o que
colocamos aqui. Temos um erro. Se nos debruçarmos sobre
isso, ele diz não pode ser
atribuído, é somente para leitura Esse é um exemplo
de como fazer, digamos, uma propriedade ser lida somente em C Sharp. Mas espere. No início
do tutorial, você falou sobre campos e variáveis e
coisas assim. Como faço isso usando
a palavra-chave somente leitura? Bem, vamos dar uma olhada. Vamos voltar para
a aula de cães. Agora, o que vou fazer é
usar a palavra-chave somente leitura. Vou desfazer
essas alterações e colocar essa cláusula definida de
volta Então, agora estamos definindo o valor, mas agora vou marcar
esse campo aqui como lido. Somente depois de fazer isso, você pode ver que um erro
ocorreu aqui. Na verdade, não está mais me deixando
usar a cláusula set. Se eu passar o mouse sobre
isso, diz que um campo somente para leitura
não pode ser atribuído, então há uma pequena
condição aqui, exceto que em um construtor
podemos atribuí-lo dentro de
um construtor como aqui e exceto que ele é apenas configurador do tipo em que
o campo está definido ou O que tudo isso significa? Basicamente, significa que quando você
usa a palavra-chave somente leitura, você pode defini-la uma vez. Por exemplo, poderíamos
defini-lo aqui e inicializá-lo aqui Digamos que todo cachorro novo
seja um chihuahua, por exemplo. Não tem problema nenhum. Na verdade, estamos configurando isso, mas estamos fazendo isso
quando o declaramos Declaramos a variável aqui, mas também a estamos inicializando, o que
é permitido A outra coisa que também
podemos fazer é colocá-lo dentro de um construtor,
como dentro de um cachorro E podemos fazer isso
várias vezes. Desde que esteja dentro de um
construtor, está tudo bem. Podemos fazer isso 1.000
vezes se quisermos, mas não podemos definir isso dentro, por exemplo, dessa propriedade aqui. Não podemos dizer, criar um método
totalmente novo e
defini-lo aqui, por exemplo. Isso não vai funcionar. Você vê o ponto aqui. Mesmo se acessarmos isso
de fora da nossa classe, eu apenas coloco isso em minúsculas. Agora, para acessar o campo, você pode ver que ele não pode ser atribuído à aceitação de
um construtor Então esse é o poder
da palavra-chave somente leitura. E há
alguns motivos pelos quais você pode querer usá-los
ao trabalhar com tipos de dados
imutáveis como a palavra-chave somente leitura Você deseja usá-los para coisas que talvez
queira configurar uma vez, mas nunca desejaria
modificar o valor disso. Isso ocorre porque, por exemplo, se eu gerar uma ID de
cachorro exclusiva, faço isso apenas uma vez, mas não quero que
essa ID mude porque cada cachorro tem uma
ID exclusiva associada a ela. Se eu começar a mudar as identidades
dos cães, por exemplo, se tivermos um
software que rastreia cães, você conhece os cães
que usam a coleira E se o cachorro se perder, eles podem escanear a
coleira ou o microchip E então ele usa o ID
desse para referenciar talvez um banco de dados e descobrir onde está o dono
do cachorro. Talvez não faça essa
leitura, só então poderemos ter uma propriedade ou alguém chamando esse aplicativo poderá alterar
acidentalmente o ID, o que pode ser desastroso É por isso que os
tipos de dados imutáveis geralmente são usados. Queremos impedir que
outros desenvolvedores, ou mesmo usuários do software, modifiquem esses valores Mas para algo como um ID, em que geramos um ID exclusivo
para cada cão em nosso sistema, é muito importante criar campos como esses somente para leitura. Portanto, realmente depende
inteiramente do seu sistema
o que você deseja fazer. Mas é uma
prática muito boa dizer que, se você tiver variáveis ou campos que não deseja que
os usuários modifiquem, sempre
faça com que sejam
lidos apenas, por exemplo. Então, essa é uma maneira de
lidar com esse problema. Outra condição relacionada à palavra-chave somente leitura, por exemplo, ela
só pode ser usada em campos. Agora lembre-se de
que os campos são definidos nas classes, logo abaixo da declaração da
classe Se eu entrar no meu programa principal A aqui e usá-lo dentro de um método. Se eu definir isso
dentro de um método, obviamente removendo o privado
, você verá que
há um problema. Se eu passar o mouse sobre ele, ele diz que o modificador
somente leitura não é válido para este item Basicamente, isso significa que, ok, você não pode usar a palavra-chave
read somente dentro de um método, mas podemos usá-la
em nível de classe. Por exemplo, podemos usá-lo aqui e não tem problema algum. Isso vai funcionar muito bem. Mas não podemos usar
esses métodos internos. Há uma palavra-chave diferente que talvez
possamos usar para isso, e essa é a palavra-chave constante sobre a
qual
falaremos também. A última coisa sobre a qual quero
falar
somente para leitura é quando
podemos definir o valor. Podemos definir o valor
em tempo de compilação, que significa que podemos
atribuir um valor a ele em nosso modo de desenvolvimento quando
o software é compilado, ou
seja, quando a verificação é feita Eu posso dar um valor ao vermelho, aqui, eu posso dizer Chihuahua e
não há problema Isso está em tempo de compilação. Novamente, dentro do construtor, estamos definindo esse valor No entanto, também podemos
alterar o valor em tempo de execução quando o
software é executado. No entanto, também podemos inicializar um campo somente para leitura durante o tempo de
execução, quando nosso software
está realmente em execução Quando construímos esse objeto
dog aqui, o construtor
está sendo chamado e, em seguida, essa linha
de código é executada E isso acontece durante o tempo de
execução, quando nosso
software está em execução. Se eu executar o software, você pode ver que ele define esse
valor no construtor Não há erros
e não há problema. Podemos definir um campo somente para leitura em compilação e em tempo de execução
, em dois lugares diferentes Mas essa é a palavra-chave
somente para leitura em C Sharp e por que você deve usá-la
e também como usá-la.
61. 13-2. A palavra-chave const: Eu vou falar sobre a palavra-chave constante em C sharp. Parece algo
assim. O que é isso? Bem, a palavra-chave constante é outro tipo de dados imutável Se você assistiu ao meu tutorial
sobre a palavra-chave somente leitura
, entender
a palavra-chave constante será muito mais fácil. Neste tutorial,
explicarei a palavra-chave constante, mas também demonstrarei
as diferenças entre constante
e somente leitura, pois muitas pessoas se
confundem entre as duas e quais
devem usar e quando. Vamos dar uma olhada na
palavra-chave constante. Agora, o que vou fazer é
usar o exemplo anterior. Isso ajudará a ilustrar muito melhor
a diferença. Então, aqui tenho minha aula de cães para quem não assistiu
ao último tutorial. Eu tenho dois campos aqui, um construtor que os
configura e uma propriedade aqui que apenas obtém o valor
da raça Portanto, é uma aula simples de cães. O que vou fazer é modificar
esse campo privado aqui, que atualmente é somente para leitura, e transformá-lo em uma constante. Em seguida, vou demonstrar o comportamento e as
diferenças nesse caso. Portanto, lembre-se de que, com um campo
somente para leitura aqui, podemos realmente
definir o valor de um construtor e também
podemos inicializá-lo Deixe-me
transformar isso em uma constante agora. Agora você pode ver que um
erro apareceu. Se eu passar o mouse sobre o
erro aqui, estou dizendo
que um tipo Guid não pode
ser declarado como uma constante Certos tipos de dados
não podem ser constantes. Isso é um pouco problemático. Ok, vamos transformar
nosso ID em um número inteiro. Em vez disso, teremos um sistema que gera um
número inteiro exclusivo para cada cão único Ok, não tem problema.
Usaremos um tipo de dados diferente. Agora, há outro problema. Se eu passar o mouse sobre
isso, você verá um campo constante exige que
um valor seja fornecido Basicamente, isso significa que quando você declara uma constante
como estamos fazendo aqui, você tem que inicializá-la, você tem que dar a ela um valor
em uma única linha aqui Caso contrário, não é possível. Quando declaramos
algo como constante, temos que atribuir um valor a ele Digamos que 456, por exemplo. Agora há outro
problema aqui embaixo. Se eu me debruçar sobre isso, você pode ver, bem, a
mensagem de erro não está muito clara Mas, basicamente, depois de declarar uma constante e inicializar
um valor nela, você não poderá mais modificar esse campo ou variável
de nenhum outro lugar Não em um construtor. Você não pode
modificá-lo a partir de uma propriedade. Você não pode modificar
esse valor de fora da classe
em nenhum outro lugar. Depois que uma constante é
definida e inicializada, o que vocês dois precisam
fazer em uma linha, você não pode modificar esse valor Portanto, pense na palavra-chave constante mais
como uma leitura
mais forte com muito mais limitações em termos de modificação de seus dados Essa é uma grande diferença aqui para algo como
gerar um ID exclusivo para um cachorro, lido apenas como uma boa
palavra-chave para isso, porque podemos
inicializá-lo a partir do construtor No entanto, gerar um ID exclusivo para um cachorro com uma palavra-chave
constante seria uma maneira muito
ruim de lidar com essa situação, porque const não
seria uma boa maneira de
representar isso Você pode estar se perguntando, bem, para
que posso usar o const? Qual é um bom exemplo de
uso dessa palavra-chave constante? Parece bastante limitante e
parece que eu
realmente não posso fazer muito com isso Bem, por exemplo,
digamos que trabalhamos com eu. Quando digo torta, não me
refiro a torta de maçã. Quero dizer torta R ao quadrado de 3,1 419. Acho que o pie é acessado
na classe matemática estática. Já examinamos a aula de
matemática estática antes, quando trabalhamos com
números anteriormente. E há muitas coisas que
você pode fazer aqui. Mas você pode ver aqui, há uma chamada torta. Se eu passar o mouse sobre isso,
você pode ver que a torta é uma
constante, 3,1 4159 Eu estava perto, eu estava perto. A torta é uma constante. E isso porque a
torta não muda. A torta é sempre 3,14 159265. É apenas esse valor. Não há razão para
que eu possa pensar onde gostaríamos
de
modificar o valor de pi, porque pi é o que é. Pi é pi. É a relação do raio com
a circunferência Agora, eu não sou matemático, mas espero dizer que você nunca
precisaria modificar pi porque é Esse é um ótimo exemplo
do uso de uma constante. Nesse caso, pi é constante. Você não modifica pi.
É o que é. E quando você tenta, você pode
ver que há um problema aqui. Então pi é um bom exemplo de onde você
usaria uma constante, porque esse valor, uma vez definido, nunca
é alterado e
há muitos deles. Olha, tem um
alfinete lá e uma toalha. Eu nunca ouvi falar de toalha, mas oh, tem a
ver com brilho. OK. Aqui, uma lembrança distante
de uma aula de matemática muito antiga. Então você pode ver que esse é o
objetivo de usar a constante. É onde você nunca
gostaria de alterar o valor. E uma vez configurado, agora
é definido como constante Você define isso em tempo de compilação, não em
tempo de execução Quando seu aplicativo
está sendo executado constantemente, variáveis ou campos precisam de valores. Você pode remover o valor, executar o aplicativo e atribuí-lo enquanto o
software está em execução. Isso só acontece
em tempo de compilação. Outra coisa com constante, ao contrário de leitura somente
leitura, somente leitura, você a usa em campos privados de classes, como
explicamos anteriormente. No entanto, com Constant,
podemos usá-los como
campos privados da classe, mas também podemos
usá-los dentro de métodos. Por exemplo, posso simplesmente declarar uma variável aqui, eu a chamo de ID, dou o valor e, em
seguida, posso
usá-la no restante do
meu método aqui Eu também poderia passá-lo para outro
método, não tem problema. Variáveis constantes,
você pode definir,
declarar e inicializar e
depois passá-las pelos métodos, não tem problema algum No entanto, se isso foi lido somente
como mostramos anteriormente, não
é possível porque
somente leitura está
restrito a campos privados. Outra coisa que vou
mencionar sobre a palavra-chave
constant é que ela é implicitamente
estática por padrão Basicamente,
isso significa que é estático por padrão. Se você assistir ao meu tutorial
anterior, onde falamos sobre a palavra-chave
static, você se lembrará de que
static é um nível de classe É aqui que criamos
uma nova instância de cachorro. Em seguida, usando a instância
que criamos, podemos acessar o nível da instância, campos, métodos e propriedades. Mas quando acessamos
coisas no nível da classe, usamos o nome da classe e, em
seguida, acessamos qualquer coisa
no nível da classe. As coisas no
nível da turma são estáticas, assim como a constante aqui. O que vou fazer é tornar pública
essa identificação constante. Isso significa que podemos acessá-lo
de fora da classe. Eu volto para fora
daqui e coloco um ponto. Agora você pode ver que o ID está aqui. Isso ocorre porque os campos
marcados como constantes são implicitamente
estáticos, estáticos Se eu usar a instância
DG no nível da instância, você verá que o ID não está aqui Não está aqui de jeito nenhum. Mas em nível de classe, é
aqui que ele mora. Isso ocorre porque
qualquer coisa definida como constante é implicitamente estática Está disponível em nível de classe. Você pode ver que não é
nada estático, é apenas constante. Isso porque isso tem um
valor e não seria definido. Não podemos modificá-lo. Por que queremos que
cada instância tenha um pouco de área na memória
onde esse ID é definido? Realmente não faz sentido. Se você tiver 1.000
cães em seu sistema
, parte da sua memória
precisará estar disponível para adicionar essa ID constante para cada
cachorro em seu software. Agora, isso não faz sentido
porque, uma vez definido
, está definido, pronto. Portanto, faz sentido realmente
ter isso disponível
para a classe. Então, se temos 1.000
instâncias de cães em nosso sistema, não
temos 1.000 cópias de uma variável que
não pode ser modificada. Então essa é a razão
para isso e meio que faz sentido quando você
pensa dessa forma. Isso é realmente uma pegadinha a ver com campos constantes, é que eles estão no nível da turma Espero que neste tutorial eu tenha destacado o que a palavra-chave
constante faz, o que ela significa e,
mais importante, a diferença entre constantes e leitura somente em C nítido
62. 14-1. Memória de pilha e heap: Ao desenvolver
aplicativos com C Sharp e Visual Studio, você está criando coisas
como variáveis como números inteiros,
boolenes , talvez
instâncias de classes,
objetos, matrizes e É importante
entender o que está acontecendo com os que estão
na memória do computador. E se eu te dissesse isso? Dependendo do
tipo de dados escolhido para suas variáveis, determina onde e como elas são
armazenadas na memória. O que eu quero dizer com isso? Se você usar uma
variável inteira, uma variável bolen
ou uma dupla, por exemplo, elas
serão armazenadas e acessadas forma
muito diferente em
diferentes tipos de dados E quando digo tipos de dados
diferentes, quero dizer coisas como cadeias de caracteres, matrizes e objetos personalizados Mas por que isso é importante? Bem, há alguns
motivos pelos quais você pode querer aprender sobre memória de
pilha e pilha Primeiro, em termos de desempenho, seu
aplicativo pode ser executado e funcionar muito mais rápido quando você
entende esses conceitos. Mas não só isso, mas se eu dissesse que, por exemplo, se você passar um objeto
para um método, você poderia potencialmente perder dados ou sobrescrever dados existentes O que você pensaria sobre isso? Agora, esses são dois
dos muitos motivos para aprender sobre memória de pilha
e pilha, e esse é o objetivo
deste tutorial no momento Agora, por experiência própria,
e acredite, desenvolvedor comum
não terá muito conhecimento sobre o que está acontecendo na
memória com essas variáveis. No entanto, apenas ter um
pouco de conhecimento sobre isso permitirá que você se
destaque dos demais. Então, vamos falar sobre
memória de pilha por um momento. A arquitetura da memória de
pilha é como uma pilha de pizzas
ou algo parecido Você continua adicionando
pizzas à pilha, uma em cima da outra, e depois
as remove sequencialmente. Portanto, primeiro a primeira, seguida pela próxima
, você não pode acessar,
por exemplo, pizzas
em pedidos aleatórios Ele precisa ser adicionado à pilha. Então, adicionado à pilha de pizzas
ou removido do topo. Então é assim que a memória
de pilha funciona. É sequencial, então você adiciona coisas à parte superior e
remove da parte superior, mantemos
itens de curta duração na pilha Agora, o que é um item de curta duração? Bem, esses geralmente são
chamados de tipos de valor. Coisas como números inteiros, caracteres
inclinados do Boo, flutuantes, duplas, coisas que
são meio rápidas, coisas
simples que não são Tipos de dados simples como esses, não coisas como objetos complexos. E quando armazenamos coisas na memória da
pilha, elas são
recuperadas rapidamente É uma área de memória muito rápida, exatamente pela forma como é
arquitetada sequencialmente Agora, a área da pilha de
memória é bem diferente. Imagine aquela pilha de pizzas, mas em vez de uma pilha bem
organizada, jogue todas no chão, para que haja pizzas em
todos os lugares na memória, não
haja ordem dos
itens na No entanto, devido ao layout
natural dos itens na pilha,
a
recuperação da memória é mais lenta porque o processo é mais complicado de
acessar Portanto, é considerado
mais lento do que a memória de pilha. Geralmente, você mantém itens de
longa duração na pilha, ou seja, objetos complexos, mas também coisas que serão disponibilizadas por um longo tempo, por um longo período de
execução do seu aplicativo,
enquanto as coisas na pilha
seriam consideradas de curta duração enquanto as coisas na pilha seriam consideradas de curta Então, talvez um cálculo rápido,
como quatro mais quatro, por exemplo, quais tipos de dados e itens são armazenados na
área da pilha da memória São coisas como
objetos, classes. Quando instanciamos uma classe,
strings, strings
podem ser itens enormes,
matrizes, qualquer coisa
que seja global, disponível
globalmente Por exemplo, mesmo que um número inteiro simples seja
considerado um tipo de valor No entanto, se você tornou isso global como estático ou
algo parecido, e ele foi disponibilizado para
todas as classes do sistema
, é aqui que
as regras mudam. Isso seria armazenado na área
da memória da pilha porque precisa ser
disponibilizado para itens mais longos e duradouros na pilha Coisas como strings, classes, como todos são considerados tipos de
referência,
essa é a palavra-chave Você pode ouvir muita coisa no
futuro ao criar um novo tipo de referência que é armazenado na
área da memória da pilha O que também acontece
é que algo chamado ponteiro é
criado na pilha Então, o que acontece
é que o ponteiro
na pilha aponta para uma área da memória
da pilha onde estão os
dados do objeto Quando você cria um tipo de referência como uma matriz, por exemplo, um ponteiro é adicionado
à pilha e a parte real da
operação é adicionada à A informação na
pilha praticamente diz,
ok, você pode encontrá-la aqui neste
local de memória na pilha Essa é a única coisa
que é adicionada
à pilha quando você
cria um tipo de referência, como algo complicado,
como uma matriz, por exemplo É daí que
vem o tipo de referência do
nome , porque estamos nos referindo da pilha à pilha em que o analisador de
dados reside. E é por isso que coisas como
números inteiros, Boulen, xás tipos
simples são chamados de tipos de valor
porque o valor é armazenado diretamente na área da
pilha da memória Agora, entendo que isso é muito difícil de
entender e entender,
mas não se
preocupe em entender cada coisa que
descrevi neste tutorial A principal lição é
saber e entender que certos tipos de dados são armazenados na
área da pilha da memória E a área de memória da pilha tem suas próprias características
e benefícios, e outros tipos de dados
são armazenados na pilha, novamente, com suas próprias características
e coisas assim Nos próximos tutoriais, usarei alguns exemplos para que você possa
entender melhor isso Portanto, não se preocupe em entender
tudo agora, mas agora
vou falar sobre algo chamado
stack overflow Agora, você já deve ter ouvido falar
do site stack overflow, ou talvez já tenha ouvido falar
do termo Realmente não importa se
você já ouviu falar disso ou não, mas o que vamos
fazer é
causar intencionalmente um
estouro de pilha em E acho que será
um exemplo muito divertido de simular, porque posso mostrar que memória de
pilha tem limitação de
tamanho E é por isso que objetos grandes e
complicados são armazenados na pilha Então, vamos tentar sobrecarregar a área de memória
da pilha. Agora, com um exemplo rápido. Estou aqui no Visual Studio. Agora eu tenho uma aplicação muito
simples do método principal. Aqui estamos chamando
um método de estouro. E o método overflow consiste apenas escrever olá na janela
do console Então, não está acontecendo muita coisa aqui. Agora, uma maneira fácil de causar um estouro de pilha é fazer com
que um método se chame Você pode estar se perguntando
a seguinte pergunta: como isso causa
um estouro de pilha Não estou definindo nenhum número inteiro, booleano, nada parecido O que está realmente
sobrecarregando a pilha? Bem, quando você chama um método, a referência do método
também é adicionada à pilha Esse é outro exemplo
de memória de pilha. Assim, também podemos obter um
estouro de pilha como esse. Da mesma forma, podemos criar
alguns milhões de variáveis, os números inteiros, talvez
isso também funcione. Talvez haja muitas
maneiras de fazer isso, mas esse é um exemplo rápido de uma maneira muito fácil de fazer isso. Então, vou executar
o aplicativo agora e vamos
ver o que acontece. Eu executo o aplicativo, ele praticamente trava. Diz no Visual Studio, exceção de
estouro de pilha. Quando eu olho para a janela do
console aqui, você pode ver que diz
stack overflow repetido 24.109 vezes antes que a pilha
esteja completamente cheia e comece a esteja completamente cheia Se observarmos esse diagrama aqui, você pode ver como a memória da pilha
e da pilha cresce,
mas a memória da pilha O objetivo da
memória da pilha é armazenar valores
reais para tipos de dados, como números inteiros Na verdade, ele
armazenará, por exemplo, 15 na pilha, em vez de, se tivermos um grande tipo de
referência, como uma matriz
, isso será armazenado
na pilha porque eles podem crescer muito, muito No entanto, com a área
de memória da pilha, ela é limitada. É finito. Você só pode colocar uma
quantidade limitada de informações aqui. E, como você pode ver aqui, podemos armazenar uma referência à
nossa chamada de método 24.109 vezes Então, isso é o quão limitado é e é por isso que
nem tudo está armazenado na pilha Sim, a pilha é rápida, mas seu espaço é limitado A pilha é mais lenta, mas é muito maior Então você vê os prós
e os contras de cada um, e é por isso que
ambos existem e também por que é importante
entender os dois. Então, eu quero falar
sobre mais uma coisa, que é a pilha de chamadas O que é a pilha de chamadas? Se eu voltar ao Visual
Studio aqui e rolar para baixo, você verá que há
uma pequena janela aqui chamada stack Se você não vê essa janela, vá até o topo, vá para bug, depois windows e chame stack E isso deve aparecer
no canto inferior direito aqui. O que a pilha de chamadas faz é fornecer uma
representação visual de suas
chamadas de método, por exemplo Então você pode ver aqui que
começamos com o método principal. Aqui chamamos de estouro e repetimos isso 24.106 vezes antes de finalmente
terminar em um Ele oferece uma boa representação
visual de suas chamadas de método. E você pode ver que a arquitetura
aqui é muito parecida com o exemplo de pizza de que eu
estava falando anteriormente, com a primeira chamada
sendo a pizza de baixo. E eles são
adicionados lentamente à pilha. Mas o motivo pelo qual estou falando sobre a pilha de chamadas agora é
que, desenvolvedores iniciantes, posso ficar um
pouco confuso entre memória da pilha e a
pilha A pilha de chamadas oferece uma
boa representação visual de suas chamadas de método Mas não é memória de pilha. Isso não é o que você
vê na memória da pilha. A pilha de chamadas não
mostra suas variáveis atribuições
e
coisas assim Ele fornece
apenas as
chamadas do método , embora estejam
vagamente relacionadas, a pilha de chamadas
não é memória da pilha Posso ilustrar isso agora com um exemplo melhor da pilha
de chamadas Dê uma olhada
neste exemplo aqui. É bem simples. O
método principal aqui chama o método um. O método um chama o método 22, chama 33 chama quatro. Finalmente, em quatro, apenas dizemos olá para a janela do console. É muito simples, mas este
exemplo mostrará como a pilha de chamadas funciona e como essas referências de métodos são
adicionadas à memória da pilha Basicamente, a arquitetura da
pilha,
a arquitetura da pizza Vamos dar uma olhada em um exemplo. No momento, adicionei um ponto de interrupção aqui
na primeira linha. Então,
entraremos no modo de pausa assim que isso for atingido. Então, vou compilar e
executar o aplicativo agora,
agora estamos no modo de pausa aqui Se eu
abrir essa janela com a pilha de chamadas, você pode ver que um item foi adicionado à
pilha de chamadas, que é principal Agora vou abordar isso
pressionando 11 no teclado. Agora você pode ver que estou
dentro do método um. Agora, isso foi adicionado
à pilha de chamadas aqui. Esta é nossa primeira
pizza em nossa pilha. Esta é a nossa segunda pizza. Agora, vou
pressionar F 11 novamente. Agora temos nossa
terceira pizza no topo. Eu vou
entrar nisso novamente. Temos nossa quarta pizza. Você pode ver como isso funciona. Portanto, a pilha de chamadas oferece
uma boa representação visual de onde você está em seu aplicativo durante
uma sessão de depuração Também é semiinterativo. Você pode clicar duas vezes neles e
ver onde está, de
onde esse método
foi chamado, o que é muito útil quando
você tem vários arquivos, soluções, projetos,
coisas assim. Ele pode levá-lo diretamente para o local de onde
foi chamado. Mas essa é uma
representação semelhante à forma como
a memória de pilha funciona Temos nosso primeiro valor aqui, depois eles são acumulados
e, em seguida, são
retirados em uma ordem como esta Eles não podem ser
acessados aleatoriamente. Então, é como primeiro a
entrar, primeiro a sair, que é a terminologia, a memória da
pilha e a pilha de chamadas
usam a arquitetura da pilha usam a arquitetura da E embora estejam relacionados, não
são exatamente
a mesma coisa. Espero que isso faça sentido. Agora, se eu for para o método quatro, você verá que é o último adicionado à pilha de chamadas E então eu passo por cima disso, e agora você pode ver que eles estão lentamente sendo
retirados da pilha O método três
será o próximo a aparecer porque
acabamos de sair de lá. Depois dois, depois um. Agora estamos de volta
ao método principal. Você pode ver que é o último item restante na pilha de chamadas Então é isso que é a pilha
principal
e também é isso que é a arquitetura da
pilha E você verá a arquitetura de
pilha em muitas linguagens de
programação diferentes, mas também não se limita
à programação Uma última coisa sobre a qual vou
falar é uma palavra-chave que você poderá ouvir no futuro
chamada coleta de lixo Então, o que é coleta de lixo? Bem, quando falei sobre criação de
tipos de referência, por exemplo, coisas que são armazenadas
na área de pilha da memória, como classes,
instâncias de classes, cadeias de caracteres, matrizes e
coisas Eu também disse que um
ponteiro é criado
na pilha e isso aponta para
as informações na É como um ponteiro.
O que pode acontecer é o ponteiro seja removido
da área da pilha da memória, mas os dados reais sejam
deixados para trás na Agora, nosso aplicativo
não tem mais ideia de onde essas
informações estão. Talvez nem
precise mais dos dados. Mas ainda pode existir
na área de memória acumulada. Mas como o
ponteiro não está mais apontando para ele na área da
pilha da memória, esses dados na
pilha Não pode ser usado,
não pode ser encontrado. Pode simplesmente encher sua memória até que não
haja mais memória. Isso é um grande problema. Isso geralmente é chamado
de vazamento de memória. Então, há algo
chamado coleta de lixo que, na verdade, meio que
vai para a pilha Área da memória, calcula se há um ponteiro apontando
para ela na pilha
e, se não, ela remove libera E é isso que a
coleta de lixo faz. E em uma linguagem como C shop, você não precisa se
preocupar com a coleta de lixo Mas achei que
seria uma
curiosidade interessante para te contar Mas se você trabalha com
outras linguagens, talvez como C plus, então você precisa se
preocupar com a coleta de lixo Então, talvez seja
algo a considerar, mas é bom saber. E quando seu aplicativo é
fechado ou encerrado
, geralmente a
memória é liberada
63. 14-2. Parâmetros do método: passando por valor: Antes de assistir a este tutorial, eu recomendo fortemente que você assista
ao tutorial anterior sobre memória de
pilha e pilha Caso contrário, isso pode não
fazer muito sentido, a menos que você esteja familiarizado
com a memória de pilha e pilha Agora vamos dar uma
olhada nesse exemplo. Aqui, estamos
vendo alguns métodos passando agora alguns
parâmetros para um método. Em seguida, vamos
modificar alguns valores. Basta considerar este exemplo
aqui. É bem simples. No método principal
do aplicativo aqui, estou definindo duas variáveis de
tipo de valor aqui. Agora, eles são armazenados
na pilha, a área da memória da pilha,
são tipos de valores Em seguida, estou enviando os valores dessas variáveis
para a janela
do console Em seguida, estou chamando um
método chamado reset. E estou passando
essas duas variáveis de tipo de valor
para esse método aqui, estou redefinindo essas
variáveis que estão sendo passadas para zero e, em seguida, estou enviando-as para a janela
do console Quando o método é concluído, execução do controle é
passada de volta para cá E então eu estou produzindo os valores dessas
variáveis novamente. E então eu estou mantendo a janela
do console aberta. Pergunta, qual você
acha que seria a saída? Bem, vamos dar uma olhada no
que a saída realmente é. Vou executar
o programa agora. O valor de num um é o
valor de num dois é quatro. E então o valor dentro do método é zero porque
estamos redefinindo-os. E depois que o método é executado 6.4, é isso que você esperava Talvez sim, mas agora
veja esse outro exemplo. Vamos dar uma olhada
nesse exemplo aqui. É muito semelhante
ao exemplo anterior, mas em vez de usar um tipo de
valor simples, como um número inteiro, estamos usando um tipo de referência E os tipos de referência, como
falamos antes, são armazenados na
área de pilha da memória, e um ponteiro para esses dados
é armazenado na O que estamos fazendo é instanciar um objeto de videogame Se eu for para a aula de videogame, você pode ver que é bem simples. Ele tem um
campo privado aqui chamado título e uma
propriedade pública chamada título, que controla a obtenção e
configuração desse campo aqui. Muito simples. Estamos definindo o título do
videogame aqui, um World of Warcraft, e depois o enviamos para
a janela Estamos recebendo o título
antes que um método seja chamado. Agora estamos mudando
o título aqui. Nesse método, ele pega
um objeto de videogame e
, em um objeto de videogame e seguida, enviamos
algo para a janela Estamos enviando isso para a
janela dentro do método. Mas antes de mudarmos o título do jogo dentro desse método, estamos mudando o título do jogo para mudar algo diferente. Depois que a execução do método
for concluída,
exibiremos o título do
jogo novamente Agora, o que você acha que
vai acontecer desta vez? Ok, vamos dar uma
olhada no resultado. Se eu executar o aplicativo, você pode ver aqui o título do jogo antes do método ser
World of Warcraft O título do jogo dentro do
método é World of Warcraft. Lembre-se de que, dentro do método, isso ocorre antes da
alteração, mas depois que a execução do método
termina, voltamos ao Maine
e produzimos isso Aqui, no entanto, você pode
ver que ele está retendo o valor
para o qual o alteramos dentro do
método. Por que isso acontece? Por que essas mudanças
persistem devido a mudanças nos métodos dos tipos de referência, mas não dos
tipos de valor O que está acontecendo aqui? Bem, deixe-me explicar. Estou voltando
ao exemplo
anterior onde tínhamos dois tipos de valores
simples aqui, dois inteiros, e
os passamos para um método aqui Agora, em C Sharp, ao
passar objetos, sejam eles tipos de valor ou tipos de
referência como
parâmetros para métodos, por padrão, eles
são passados como valor. Eles são passados por valor, a menos que seja explicitamente indicado, eles devem ser
passados por referência Falaremos sobre a
passagem por referência mais tarde. Mas considere o padrão que está sendo passado por valor aqui. O que significa passar por valor? Bem, por padrão, quando você chama um método e passa esses
dois parâmetros aqui, uma cópia, uma cópia
desses dados é criada. Aqui temos um valor de seis no número um e um valor
de quatro no número dois. Estamos chamando esse método aqui. Dentro desse método, ele recebe uma cópia
dessas variáveis. Não está apontando para a mesma
área da memória deles. Eles são literalmente copiados. Então, o método
realmente funciona com uma cópia duplicada
dessas variáveis Isso é o que significa quando é passado
por valor. Qualquer trabalho que fazemos
dentro desse método aqui é feito com uma cópia
dessas variáveis. E quando o método termina de ser executado e o controle
é retornado aqui, perdemos tudo
aqui porque essa é uma cópia duplicada e só
existe dentro do Uma vez concluído o método, não
temos conhecimento
disso, a menos que retornemos especificamente
algo daqui. Esse é um exemplo de
passar um tipo de valor para um método e ele está
sendo passado por valor, isso não afeta nada
fora do método. Voltando ao nosso outro
exemplo aqui, onde mudamos o nome
do objeto do videogame. Se estou passando dados por valor
, por que essa alteração
persiste fora do método Certamente isso não faz sentido. Bem, isso ocorre porque
estamos passando um tipo de referência por valor. Como eu disse, quando você
passa parâmetros para métodos por padrão
, é por valor. No entanto, estamos passando
um tipo de referência. Lembre-se de antes de falarmos
sobre tipos de referência, que são objetos complicados. Eles podem ser matrizes, listas, coisas assim E isso é armazenado
na área
da pilha da memória, mas como eu disse, há um ponteiro que é
armazenado na área da pilha da memória que aponta para
esses dados na Quando esse método é chamado, sim, ele é copiado para o método,
mas a memória da pilha não
é Somente o ponteiro na
pilha é copiado. Agora, isso parece
contra-intuitivo, na verdade, porque ,
sim, estamos passando esse objeto de
referência por valor. No entanto, como é
um objeto de referência, estamos apenas copiando o
ponteiro dentro desse método Aqui estamos trabalhando com uma cópia do ponteiro que é
armazenada na memória da pilha No entanto, ele ainda aponta para a mesma área de
memória na pilha Neste método principal, estamos apontando para a área
da memória na pilha, mas também dentro desse método Embora estejamos trabalhando com uma cópia do ponteiro
na pilha, ele ainda está apontando para aquela
área da memória na É por isso que o título ainda muda porque, embora estejamos trabalhando com uma
cópia do ponteiro, ele ainda aponta para a
mesma área da memória É por isso que o título ainda
muda dentro do método. E podemos ver aqui, uma vez que
o método foi chamado, as mudanças ainda persistiram
após a execução do método Aqui, eu entendo que isso
é muito difícil de entender, mas se você olhar
o tutorial anterior e também este mais
algumas vezes, você entenderá
e entenderá Prometo quando disse que uma cópia do ponteiro é passada
para esse método aqui,
por exemplo, se eu agora trabalhar
com essa cópia do ponteiro Então, neste jogo aqui, eu posso inicializar um novo
objeto, uma nova instância O que isso faz é alocar
uma nova área de memória. Aqui, estou trabalhando com a cópia do
ponteiro aqui, mas estou dizendo, ok, agora crie um novo objeto
nessa cópia do ponteiro Então, o que isso vai fazer, isso vai funcionar com uma cópia
totalmente nova dos dados
e colocá-la na pilha O que estamos fazendo aqui, depois que
o método é chamado, estamos exibindo o título do
jogo aqui Na verdade, vamos colocar isso aqui. Agora temos uma nova
instância do jogo. Estamos definindo o título
dessa nova instância como alterado
e, em seguida, a produzindo E ainda estamos exibindo o título após o método aqui O que você acha que
vai acontecer agora? Bem, vamos dar uma olhada.
Vamos executar o programa. Agora você pode ver que algo um pouco diferente aconteceu. Temos nosso
título original no início aqui. Então, dentro do método,
ele foi alterado. No entanto, depois do
método, agora ele ainda manteve o
título original de antes Por que é isso que
está acontecendo aqui? Como mencionei, esse
é um tipo de referência. Por padrão, ele é passado
por valor dentro do método. Temos uma cópia desse ponteiro de tipos de
referência, que está na memória da pilha Agora estamos atribuindo a ele um
novo local de memória e configurando esse novo
local para ser alterado. No entanto, fora do método, ele não tem conhecimento
dessa nova localização de memória. Isso é somente dentro do método em
que isso está acontecendo. Somente dentro desse método temos
o conhecimento
dessa nova área da memória na pilha e
que estamos apontando para ela No entanto, essa alteração
não persiste fora
do método, em vez de trabalhar com uma
cópia existente do ponteiro, o
que, novamente,
afetará a Assim como daqui,
estamos alocando
uma nova área de memória na pilha e apontando nossa
cópia
do ponteiro para ela,
e é por isso que isso Vamos dar uma olhada em mais
um exemplo aqui. Novamente, isso terá praticamente
a mesma saída
do nosso tipo de referência
anterior, que era uma instância
de um objeto de videogame. Mas aqui temos outro tipo de
referência, uma lista. Novamente, pode ser
qualquer tipo de referência
, pode ser uma matriz
, pode ser um dicionário
, pode ser muitas coisas
diferentes. Isso, novamente, é armazenado
na memória da pilha. uma lista com quatro números inteiros, geramos a
contagem da lista
e, em seguida, passamos
a lista para esse método Agora, por padrão, ele é
passado como valor, mas esse é um tipo de referência. Uma cópia do ponteiro é
copiada para o método. Agora, o método pode funcionar com
uma cópia do ponteiro que aponta convenientemente
para a mesma área na memória de pilha que esta.
Fora do método. Em seguida, adicionamos dois
números à lista e, em
seguida, geramos a contagem da lista Quando o método for finalizado, exibiremos a contagem da
lista novamente. Quais você acha que serão
os resultados? Bem, vamos dar uma olhada. Você pode ver as contagens de 466. Isso porque o método
é adicionar dois números. E quando estivermos aqui, ele estiver apontando para a
mesma área da memória acumulada, ele reterá essa contagem Agora, no método, se eu apenas modificar um pouco a
lista aqui. Agora, dentro do método, essa lista está sendo
passada novamente como valor. Mas é uma cópia do ponteiro. Com a cópia
do ponteiro e agora apontando-o para uma
nova área da memória de pilha
e, em seguida, adicionando dois números
a essa nova lista Qual você acha que será
a saída? Agora vamos executar o programa. Você pode ver que
temos de quatro a quatro. Você pode ver que nossa lista inicial
tem quatro. Isso está correto. Dentro do método, estamos
criando uma lista totalmente nova. Ele só tem dois números dentro. É daí que vêm os dois. Agora que o método está concluído, ainda
temos acesso
a essa área original. Na memória da pilha, ele está
produzindo os quatro. Assim, você pode ver que funciona com todos os tipos diferentes
de tipos de referência. E esse é o comportamento padrão
dos métodos em C Sharp. Então, vou fechar o
círculo agora. No início do tutorial
anterior, eu disse: por que preciso saber sobre memória de
pilha e pilha Por que isso é importante? Bem, você pode ver que, se você
não tem nenhum conhecimento sobre memória de pilha e pilha, variáveis de tipo de valor
e variáveis de tipo de referência
, coisas inesperadas podem acontecer Coisas inesperadas são um
grande problema em software por razões óbvias. É por isso que é importante, e aqui está um exemplo
disso na prática.
64. 14-3. Parâmetros do método: passando por referência (a palavra-chave ref): A ref, palavra-chave que passa parâmetros do
método por referência. Se você ainda não assistiu aos meus dois tutoriais
anteriores sobre esse assunto, nos quais falamos sobre memória de pilha
e pilha mas também sobre a mensuração de valor
, recomendo fortemente que você assista antes de
continuar com este tutorial, pois eles estão relacionados aos conceitos descritos conceitos No tutorial anterior, falamos sobre como vários
tipos de
objetos passados como
parâmetros para métodos. Por padrão, eles são
passados por valor, que significa que uma cópia
do valor real ou uma cópia do ponteiro é criada e o método
funciona com a cópia Agora vou falar sobre
passar por referência. Agora, passar por referência
não é o comportamento padrão e inclui falar sobre
uma nova palavra-chave
chamada palavra-chave ref. Então, como isso funciona? Apenas para relembrar aqui, estamos configurando dois números inteiros,
gerando seus valores Então, dentro desse método, nós os
estamos passando como parâmetros, redefinindo os valores para zero e
gerando as variáveis Então, quando o método estiver concluído, geraremos o valor
das variáveis originais E você pode ver que estamos
passando esses valores por valor. O método só funciona
com uma cópia deles. Portanto, os dados nunca são alterados após o
término da conclusão do método. Agora, o que vou fazer
é mudar isso um pouco. Vou passar
esses tipos de valor. Lembre-se de que o tipo de valor são tipos inteiros, booleanos e simples
armazenados na pilha Agora vou
passá-los por referência. Para passar algo por referência, basta prefixar as
variáveis aqui com a palavra-chave ref nos parâmetros do
método Aqui fazemos a mesma coisa, apenas
adicionamos a palavra-chave ref. Agora, qual você acha que será
a saída? Bem, vamos dar uma olhada. Assim, você pode ver que ele está exibindo o comportamento
do tipo de referência do tutorial anterior Lembra quando
modificamos o valor de um tipo de referência e ele se lembrou dele depois que o
método foi chamado? Bem, isso é
chamado de passar um tipo de valor por referência. E podemos fazer isso
adicionando a palavra-chave F aqui. Qual é a vantagem disso? Bem, ao passar um
tipo de valor dentro de um método, isso não cria mais uma cópia
do valor, então nenhuma cópia está sendo criada. É basicamente dizer,
ok, ei, método. Vou passar
essas duas variáveis aqui, elas são tipos de valor,
mas quero que você
passe a referência
a elas na memória. Eu quero que você trabalhe com eles. E qualquer coisa que você fizer com eles, as mudanças serão refletidas. Então, isso está passando
uma referência para a área na memória da pilha
para esses tipos de valor, e agora eles estão sendo
passados como referência Podemos trabalhar com eles
diretamente dentro do método, e todas as alterações que
fizermos neles
persistirão quando a execução do método
for concluída Então você pode ver aqui que
eu acabei de alterá-los, agora a mudança persistiu. Então, você pode ver agora que entendemos o comportamento padrão
no último tutorial, que
é passar por valor. É mais fácil entender
a outra terminologia que
está sendo passada por referência, que é usar
a palavra-chave Ref Ok, analisamos a passagem tipos de
valor, como
números inteiros, por valor Analisamos a passagem de tipos de
referência, como objetos
complicados, por valor. Agora, analisamos a transmissão de tipos de
valor por referência. E agora, para completar
a quadrilogia, vamos analisar a passagem de tipos de referência por Aqui está o exemplo.
Aqui temos nossa lista de números inteiros que
examinamos anteriormente Nós só temos quatro
números lá dentro. E então, dentro desse método, estamos adicionando dois
números à lista. E lá fora, estamos apenas
exibindo a contagem da lista
ao longo do caminho Já vimos isso antes e você pode ver aqui
a saída aqui,
porque, por padrão, estamos
passando uma cópia do ponteiro, mas ele aponta para a mesma
área na memória da pilha Assim, você pode ver as alterações
persistirem após a conclusão da execução desse método Mas lembre-se de quando
falamos sobre o fato que podemos realmente
configurar um novo local na memória de
pilha, pegar uma cópia do nosso ponteiro e atribuir a
ele um local totalmente novo, que muda o resultado Você pode ver aqui que
a alteração não persiste nesse caso Agora vou qualificar
isso com a palavra-chave ref. Eu adiciono isso aqui quando
chamamos o método. E eu adiciono isso aqui
nos parâmetros aqui. O que você acha que
vai acontecer agora? Bem, vamos dar uma olhada. Vou executar
o aplicativo. Você pode ver agora que a
alteração realmente persistiu após a conclusão da execução do método Por que é isso que está
acontecendo aqui? Bem, você
já deve ter adivinhado. Quando passamos algo por referência usando a palavra-chave
reference, assim como
falamos antes, não estamos mais criando uma cópia, nem
estamos mais criando uma
cópia do ponteiro. Estamos praticamente
passando o ponteiro na pilha para esses
dados na memória da pilha Estamos passando o
próprio ponteiro para o método. O método agora está
trabalhando diretamente com o ponteiro original
para essas informações Agora estamos configurando um
novo objeto aqui, uma nova lista. Mas não estamos trabalhando com
uma cópia do ponteiro, é o ponteiro original Estamos basicamente criando uma lista totalmente nova por cima
da original e
adicionando dois números a ela. Se executarmos o aplicativo agora, assim como vimos anteriormente, você pode ver aqui que ele está
sendo persistido Essa é a diferença aqui. Ao usar a palavra-chave ref, não
estamos mais
copiando nada. Não estamos copiando
os tipos de valor, mas também não estamos copiando os ponteiros ao
usar tipos de referência Por que isso é útil? Bem, então nossos métodos podem
funcionar com nossos dados originais, sejam eles tipos de valor ou
tipos de referência, e as alterações podem ser persistidas quando a execução do método for
concluída Esse é o poder da palavra-chave
ref na loja. Isso completa esta série de três
tutoriais sobre pilha, memória de
pilha e tipos de referência
e valor no
65. 15. A palavra-chave struct: Neste tutorial,
vou
falar sobre estruturas em C. Estruturas nítidas usam
a palavra-chave struct, mas o que são e
como funcionam? Bem, as estruturas são
muito semelhantes às classes, e este tutorial
pressupõe que você saiba um pouco sobre como as classes funcionam, como a herança funciona,
talvez interfaces e também
variáveis de tipo de
valor e referência e também tipo de
valor e referência e a palavra-chave somente
leitura Eu já fiz tutoriais sobre
todos eles anteriormente. Se você assistiu a
tudo até agora, terá uma
compreensão completa
deste tutorial e começará
a correr. O que é uma estrutura? Vamos
dar uma olhada nesse exemplo. Aqui eu tenho
uma aula quadrada, vamos dar uma olhada nisso agora. Tem dois campos privados aqui, a largura e a
altura do quadrado. Ele tem um construtor que
configura esses campos. Ele tem um
método de amostra aqui que apenas calcula a área
com base neles E também duas propriedades públicas aqui que expõem a
largura e a altura Então, é bem simples.
Então,
o que estou fazendo aqui instanciar um novo objeto e enviar algumas
amostras para a janela Se eu executar o aplicativo agora, um quadrado com altura quatro e largura cinco tem uma área de 20. Então, na verdade,
não faz muita coisa. Então, deixe-me apresentar uma
estrutura agora e o que ela é. Então, isso vai para a classe
quadrada aqui. E eu vou apenas modificar essa palavra-chave de classe e vou colocar uma
estrutura como essa. Então, se você assistir ao meu
tutorial sobre interfaces e enumerações, onde criamos uma nova classe e apenas
modificamos a palavra-chave da classe É bastante semelhante
nesse aspecto. E agora temos uma estrutura. Essa praça agora é uma estrutura. Não é mais uma aula. Mas você pode ver que
não há erros aqui. Não há linhas onduladas vermelhas. Como é que eu acabei de modificar toda
essa classe
e não há erros. O aplicativo ainda é executado? Bem, parece que funciona. E temos exatamente
a mesma resposta, o que está acontecendo aqui? Agora, é aqui que estruturas e classes confundem
novos desenvolvedores ou desenvolvedores que realmente
não entendem os tipos de valor e
os tipos de referência Estruturas e classes podem parecer muito semelhantes
na forma como se comportam. Você pode ver aqui, eu
fiz uma estrutura, tem campos privados, tem um construtor,
tem métodos, propriedades Qual é a diferença aqui entre uma estrutura e uma classe? Posso simplesmente usar estruturas
agora em vez de classes ou devo ignorar completamente
as estruturas
e usar apenas classes? Bem, a resposta é
que você pode usar os dois. Uma das principais diferenças
entre estruturas e classes é que as estruturas
são tipos de valores. Agora, como isso funciona? Bem, falamos anteriormente que as classes são tipos de
referência. Se eu colocar isso de volta aqui, quadrado agora é uma classe. Acabei de descomentar
esse método aqui. Agora, esse método aqui, eu estou
passando o quadrado, que agora é uma classe,
para esse método. E estou modificando
algumas propriedades aqui. Eu falei sobre isso anteriormente. Quando você passa um
tipo de referência como este aqui, esse é um tipo de referência, ele vive na área da pilha
da memória para um método e, em
seguida, é passado por referência Isso significa que o método pode
acessar a memória na pilha. Ele funciona com o objeto
original quando o método é concluído. Aqui ainda temos
acesso às alterações feitas de dentro desse método se eu executar
esse aplicativo, agora
veremos essas alterações refletidas na saída aqui. Vamos dar uma olhada
nisso. Você pode ver aqui 2.020.400 É uma
variável de tipo de referência aqui. Ele vive na pilha.
Agora vamos transformar isso de volta em uma estrutura
e ver o que acontece. Agora, essa é uma estrutura
que mencionei anteriormente. As estruturas são tipos de valor
e não tipos de referência. Essas alterações não serão
refletidas na saída. Isso porque o
método funciona com uma cópia do tipo de valor. Qualquer coisa alterada aqui, é apenas refletida na cópia. As mudanças não persistirão. Vamos ver o 5.4
como vimos anteriormente. Como você pode ver lá,
uma
das principais diferenças
entre classes
e estruturas é
que as classes são tipos de
referência e
as estruturas são tipos de valor. Essa é uma das principais
características das estruturas. Vamos dar uma olhada em
algumas outras diferenças entre estruturas e classes, pois elas são bastante semelhantes e parecem operar da mesma forma. Vamos falar sobre
as diferenças. Acho que isso permitirá que você
entenda melhor o que
as estruturas podem fazer, as vantagens e também
as desvantagens. Com estruturas, não podemos
usar classes de herança,
por exemplo, podemos
herdar de uma Mas quando tentamos fazer
isso com estruturas e passamos o mouse sobre
isso, sua forma na
lista de interfaces não é uma interface O que isso significa?
Muito enigmático, não é Isso porque, com
estruturas, você pode realmente
implementar interfaces. Você pode trabalhar com
interfaces, não tem problema. Esse erro aqui está esperando uma interface
porque essa é praticamente a única coisa nesse sentido
que você pode
fazer com uma estrutura Mas quando tento
herdar de uma classe, uma classe base, ela não
me deixa fazer
isso porque não é possível Todo o conceito de herança não
existe com estruturas Essa é uma vantagem que uma classe
teria sobre uma estrutura. Não podemos herdar
de uma classe base, mas a estrutura
em si também não pode ser uma classe abstrata
ou uma classe base E isso significa que não podemos ter métodos
virtuais, por exemplo. Você pode ver aqui quando
eu tentei fazer
isso, nem é válido, é porque está
dentro de uma estrutura. Portanto, não podemos usar a
palavra-chave virtual, que significa que não podemos substituir, que significa que não podemos realizar
nenhum comportamento polimórfico E lembre-se, esse é o
conceito de substituição do método. Por exemplo, não
podemos usar o virtual, não
podemos usar o abstrato. Portanto, não podemos usar
praticamente nada com relação à herança
ou algo parecido Com estruturas, existem tipos
muito mais simples do que classes, então pense dessa forma Uma estrutura é mais
simples do que uma classe. Vamos falar sobre talvez uma
vantagem de uma estrutura aqui, ou talvez por que
usaríamos uma. Por que se preocupar? Por que não usamos aulas para tudo? Bem, as estruturas não ocupam muito espaço de memória como um objeto
de tipo de referência Por exemplo, eu tenho
um objeto de videogame aqui, uma aula de videogame. Aqui dentro, ele tem campos
privados
vinculados a outros
tipos de referência, como uma classe de jogo,
uma lista de números inteiros,
algumas strings, algumas strings, É uma pegada bastante pesada e está na pilha Por esse motivo, não o
colocamos na pilha. Mas se você usar, por exemplo, uma estrutura para uma classe
muito simples,
por exemplo, essa
classe quadrada aqui, ela só tem
tipos de valores simples, como apenas alguns duplos Mesmo que tivesse booleanos e
números inteiros, coisas assim, ele
funcionaria muito mais rápido do que alocações e
alocações Portanto, ao trabalhar na área de
pilha da memória com tipos de valores simples
e até estruturas
, ele
operará muito mais rápido E as alocações, novamente, também são muito mais rápidas e
baratas Portanto, essa é uma vantagem
de usar uma estrutura. Então você pode pensar, ok, e se eu tiver um tipo de referência dentro
de um tipo de valor? Por exemplo, uma lista de números inteiros é uma variável de
tipo de referência E então eu vou em frente e coloco
isso dentro da minha estrutura, que é um tipo de valor. Sim, é possível. Você
pode ver que não há erros. O aplicativo será executado, mas isso é considerado uma prática
ruim. Você não deveria fazer isso. Isso meio que anula
o objetivo de usar uma estrutura
em primeiro lugar, o que me leva de volta
ao meu próximo ponto Use uma estrutura somente se você tiver um contêiner para tipos de valores
simples. Por exemplo, esse quadrado aqui. Tem uma largura
que é dupla. Tem uma altura
que é dupla. Se tiver uma cor,
talvez você possa
representá-la por um número inteiro E esse número inteiro pode fazer
referência
a algo relacionado a uma cor Por exemplo, branco
pode ser zero, preto pode ser um,
vermelho pode ser dois. Eles estão trabalhando com tipos de valores
simples. Aqui, uma estrutura
nesse caso
seria perfeita porque ela
própria é um tipo de valor. Mas também estou usando tipos de
valor dentro. Nunca pretendo
usar herança, nunca planejo
usar
polimorfismo Nunca planejo outras estruturas ou coisas herdadas disso Portanto, uma estrutura
seria uma boa opção para isso. É simples, rápido, usa tipos de valor. Eu nunca quero expandir
isso com relação à herança. Se todas essas caixas estiverem
marcadas, use uma estrutura. Mas assim que começarmos a
pensar em coisas como, ok, acho que esse quadrado deve herdar de uma forma de classe base E talvez a cor
pudesse ser uma enumeração, talvez tivesse uma lista de pixels e coisas E começamos a
introduzir a herança e os campos pesados e
de tipo de referência aqui, então não, não
queremos uma estrutura, queremos usar uma classe Então, basicamente, em poucas palavras, use uma estrutura se você
tiver um objeto barato, mas use uma classe se
quiser
expandi-la e usar objetos de tipo de
referência pesado Essa é basicamente
a diferença e por que você deve usar um
e não o outro. Portanto, uma das principais vantagens de ser
um tipo de valor e tudo a ver com isso é
que você pode marcar toda a
estrutura como somente para leitura. Agora, se você assistir meus
tutoriais sobre Somente leitura, entenderá o que ele faz É um tipo de dados imutável. Depois de definir um valor,
você não poderá alterá-lo. E há muitas
razões para isso. Se eu tentar marcar
toda a classe como somente para leitura, eu me preocupo com isso, você pode dizer que
ela não é válida para este item Mas se eu criar uma
estrutura somente para leitura como essa
, por exemplo, não haverá problema algum. Obviamente, há alguns
problemas relacionados a isso. Assim, você pode ver que os campos de
instância estrutura somente
leitura
devem ser somente para leitura. Eles também precisam ser
lidos apenas. A outra coisa, é claro, não
podemos usar o modificador de conjunto
se as coisas forem somente para leitura Temos que inicializar na declaração de campo aqui, então inicializamos aqui ou
dentro do construtor Se você assistir meu
Tuchoil somente para leitura, você se lembrará disso
e entenderá isso, mas pensei em
mencioná-lo novamente Com estruturas, você pode marcar toda
a estrutura
como somente para leitura. O que você realmente não pode fazer em
uma classe usando essa palavra-chave. E você verá que, talvez,
avançando com seus empreendimentos de
programação, você também verá que essa é uma prática
bastante comum ao trabalhar
com estruturas Essa é uma
coisa poderosa que você
também pode fazer ao trabalhar
com estruturas. Mas acho que a principal
vantagem disso
é não ter medo de usar
estruturas e experimentar, mas usá-las apenas para contêineres
simples Então, coisas como quadrados em que
você tem tipos de valores simples. Assim que você começar a falar sobre tipos de
referência pesados
, nesse caso, use uma classe. Mas as estruturas são muito
boas para trabalhar com aplicativos de bagunça
rápida
ou coisas simples como essas Espero que este tutorial tenha ajudado você.
66. 16-1. Tipo de dados do objeto - boxe e unboxing: Neste tutorial,
falaremos
sobre o tipo de dados do objeto. E parece
algo assim. Você pode ter encontrado
o tipo de dados do objeto ao gravar no console. Por exemplo, quando
escrevemos no console, há muitas sobrecargas de
métodos diferentes que podemos usar aqui Mas você pode ver que um
dos parâmetros aqui é objeto, por exemplo. O que é isso? Como isso funciona? Bem, vamos dar uma olhada no
que é o tipo de dados do objeto. Se você assistiu meus tutoriais sobre herança e também sobre tipos de valores e
tipos de referência, será muito fácil entender
o tipo de dados do objeto será muito Agora, o tipo de objeto é a classe base definitiva
para todos os tipos de dados, todos os tipos definidos pelo usuário, independentemente de criarmos
instâncias de objetos, tipos de
referência, como matrizes
e coisas assim, e também
tipos de valores simples, como números inteiros, bolenes, caracteres
e coisas É a classe básica definitiva
para todos esses tipos. É um
tipo de referência, o que
significa que está armazenado na área da
pilha da memória Além disso, é como uma tecnologia
antiga. Agora
surgiu algo chamado genéricos. E, geralmente, os genéricos
são uma prática melhor, embora você ainda encontre o tipo de dados do objeto atualmente E usar o tipo de
dados do objeto pode apresentar algumas questões e problemas sobre os quais também
falaremos. Esse é o processo de
boxe e unboxing. Vamos dar uma
olhada em um exemplo agora, quando acabei de dizer que
o tipo de dados do objeto é o tipo básico definitivo,
o que isso significa? Lembre-se de antes, quando eu
falei sobre interfaces e podemos passar
a interface para métodos, então, quando implementamos
a interface, podemos transmitir
nossos objetos. Se tivermos várias classes
estendendo a mesma interface, podemos simplesmente passar esses
objetos livremente Isso é muito parecido com o funcionamento da classe
baseada em objetos. Não se preocupe se você não assistiu aos tutoriais sobre
classes e interfaces abstratas Eu vou explicar
isso agora. Aqui, estamos apenas
chamando um método e passando uma string. Só diz olá, mundo. O parâmetro é uma string. O que é ótimo
porque estamos passando uma string e depois a
enviando para a janela Um aplicativo muito simples. Agora imagine isso. Vou mudar essa string
para a palavra-chave object, sem
mais nem menos. Agora vamos executar o aplicativo. Novamente, você pode ver que temos
exatamente o mesmo resultado. Por que isso está acontecendo? Bem, é simplesmente
porque uma string como essa aqui satisfaz, isso é um relacionamento E é um objeto exatamente
como uma instância de uma classe. Por exemplo, uma aula de videogame, uma aula de cães, uma aula de animais. Também existem classes, mas elas também são objetos. Essa palavra-chave de objeto aqui pode representar praticamente qualquer tipo de
dados no sistema. Bolhas, sequências de caracteres
e até números inteiros. Por exemplo, 3456. A saída será a mesma e não haverá problemas
com a compilação do projeto Aqui temos um número inteiro aqui, 3456, falamos sobre isso inteiros simples,
cadeias de caracteres, caracteres,
boolenes , são Eles vivem na pilha, na área da memória da pilha No entanto, objetos,
eles são tipos de referência, são armazenados na pilha O que acontece aqui, há uma conversão implícita
acontecendo aqui Esse número inteiro que
estamos passando está sendo convertido em
um tipo de objeto Esse processo é chamado de boxe. Se, em seguida, convertermos esse valor do objeto
novamente em um número inteiro, isso é chamado de unboxing Se você não acredita em mim,
eu vou provar isso para você. Agora, se você trabalha com um tipo de
objeto como value aqui, ele oferece alguns métodos
que podemos usar, sendo
um deles
chamado get type. O que isso fará é obter o tipo subjacente
desse valor de objeto aqui. No momento, estamos passando
um número inteiro aqui. Se eu executar o programa, você pode ver que ele está gerando o tipo subjacente
do objeto, que é um int 32, um inteiro de 32 bits Da mesma forma, se eu
passar uma string disser olá, obteremos
uma string, por exemplo. Você pode ver que esse é
o tipo subjacente do objeto aqui, e podemos obtê-lo usando
o método get type aqui. Vamos falar sobre
boxe e unboxing agora. Vamos primeiro falar sobre
boxe. O que é boxe Temos um número inteiro
aqui chamado numb e o estamos inicializando Agora, o que estamos fazendo é colocar
esse número inteiro em uma caixa, daí o nome boxing Estamos basicamente dizendo, ok, eu quero criar um objeto
totalmente novo. Lembre-se de que essa é a classe
base definitiva para todos os tipos. Eu quero dar a isso
o valor de num. Agora OBJ deve ser igual a 1234. Agora eu quero mudar o valor
desse número aqui para 100. Você acha que esse valor
mudará com isso? O que estou fazendo é gerar dois dos valores aqui Se executarmos o aplicativo, o valor de num é 100, o que é verdade porque o
alteramos. Mas você pode ver que isso não se reflete no
valor do nosso objeto aqui. O que está acontecendo aqui? Achei que o objeto era
um tipo de referência. Quando algo é
um tipo de referência, temos uma referência a
essa área da memória. Bem, essa é a
penalidade do boxe. O que acontece aqui quando
você encaixa alguma coisa, você está praticamente colocando esse número inteiro dentro de
uma caixa de objeto Mas como o objeto
é um tipo de referência, todos os objetos são armazenados na área
da pilha da memória Tipos de valores simples, como números inteiros,
são armazenados na pilha. O que acontece aqui
quando estamos criando um novo objeto e o
configuramos como entorpecido, aqui, estamos praticamente copiando todo
esse objeto, alocando um pouco de memória extra
na área da pilha de memória, colocando esse E depois também criar o ponteiro na
pilha para apontar para ela Muitas coisas estão acontecendo
quando você faz isso aqui. Agora, isso está implícito, o que significa que acontece
automaticamente nos bastidores Você não tem
controle sobre isso. Boxe, uma operação muito
cara quando analisamos
nosso exemplo anterior em que passamos um número inteiro para o método e tínhamos
um parâmetro de objeto Tudo isso acontece nos
bastidores. Uma área inteira da memória
na pilha é alocada
apenas porque estamos passando um número inteiro e ele é convertido implicitamente em um tipo
de Essa é a penalidade do boxe. Também é algo que devemos
considerar fortemente, especialmente ao criar aplicativos de
grande escala. Existe uma
maneira melhor de fazer isso? Talvez você deva considerar sobrecarregar o método em vez disso Como quando temos a linha direita
do console, temos todos esses cabeçalhos de
métodos diferentes aqui Podemos obter uma matriz de caracteres, um decimal, um duplo flutuante Mas uma vez que temos todos esses valores
possíveis,
sim, existe
a opção de absorver um objeto. Mas isso não é obrigatório. Há coisas de design a
serem consideradas ao usar objetos
aqui, dessa forma, quando você enquadra certos tipos de dados, podemos encaixotar uma string, podemos encaixotar um caractere,
mas, em princípio, esse
processo é chamado de boxing Agora, o oposto disso, como você deve ter
adivinhado, é o unboxing O que é unboxing? Bem, o unboxing é
praticamente o oposto. E isso é converter
um tipo de referência, como objeto armazenado na pilha,
lembrando a área da
memória da pilha novamente em um tipo de valor e, em
seguida, armazenada na Isso é o oposto do
boxe, e isso é unboxing. Está fazendo o
processo ao contrário. Vamos dar uma olhada em um
exemplo de unboxing agora. Agora vou desembalar
esse objeto aqui. Lembre-se de que o processo
de unboxing é converter um tipo de referência em um
tipo de valor Vamos dar uma
olhada nisso. Agora, quero convertê-lo
novamente em um número inteiro Se eu convertê-lo em
um tipo diferente
, haverá um erro. Teremos um problema de conversão de
tipos. Eu quero um número inteiro de toda
essa operação. Esse é o objetivo de encaixotar o objeto de volta ao
seu tipo original Eu configurei um número inteiro
chamado result. Agora, o que eu quero fazer é converter o objeto no tipo de dados
esperado. Esse é o
tipo esperado que eu quero, essa é a conversão. Eu quero converter esse
objeto em um número inteiro. E esse é o processo de desembalar objetos
armazenados na pilha Eu quero
convertê-lo em um tipo de dados simples, e agora ele vai ficar
na pilha aqui Este resultado é inteiro aqui. Agora, se eu enviar o resultado
para a janela do console, vamos dar uma olhada no resultado. Você pode ver como eu tenho meu valor
original aqui, 1234. Agora, talvez você note uma coisa sobre esse tutorial,
que é: ei, estou introduzindo essa palavra-chave de
objeto aqui, esse tipo de dados de objeto, mas você não deveria realmente
usá-la muito. Sim, eu entendo que esse é o tema geral
deste tutorial, mas é bom
estar ciente disso. Nos primeiros dias do C Sharp, era bastante comum converter vários tipos de dados dessa forma. Então, nós o convertemos em
um tipo de referência e novamente em um tipo de valor. E isso nos permite passar diferentes tipos de dados como o melhor tipo de objeto de classe
base. Então, foi muito útil, mas então coisas
como genéricos e outras coisas foram introduzidas, o
que meio que tirou toda essa
notação de objetos do boxe e do
boxe da prática
e da moda Mas é algo que você deve
conhecer,
ou seja, porque talvez
você esteja trabalhando com sistemas
mais antigos ou esteja trabalhando com sistemas
que se relacionam com os seus. Como se chama
interoperabilidade, que seu software se vincula
a outro
software e você encontrará
esse tipo de dados de objeto Como você pode ver, ele
ainda está em uso hoje. linha direita do console
usa
um objeto como parâmetro e
muitos outros métodos e classes também o usam. Mas é bom conhecer
o princípio do tipo de dados do objeto e
o caro processo
de encaixotamento e desembalagem, que consiste em
converter implicitamente tipos de dados e tipos de
valor em tipos de referência
e depois novamente em tipos de e depois novamente Portanto, há uma
grande sobrecarga com boxe e unboxing
67. 16-2. A palavra-chave dinâmica e a verificação dinâmica de tipo: Neste tutorial,
veremos a palavra-chave dinâmica. E a palavra-chave dinâmica
é mais ou menos assim. Mas antes de falarmos sobre
a palavra-chave dinâmica, vamos
recuar algumas etapas. Se você assistir meus tutoriais
anteriores onde falei sobre C Sharp, o fato de ser uma linguagem fortemente digitada e também
estática Então, deixe-me falar
sobre isso por um segundo. Uma linguagem de tipagem estática
é onde os tipos de variáveis,
por exemplo, um
número inteiro, por exemplo, são conhecidos em tempo É quando eu clico neste pequeno botão
verde de reprodução aqui. O software compila. E se houver algum problema, o compilador me alertará, o software não compilará E essa é uma linguagem de
tipagem estática, como C sharp. Esse processo é chamado de verificação de tipo
estático. Verificação estática de tipos, no entanto, se eu
dissesse que também existe algo chamado verificação
dinâmica de tipos? O que é verificação dinâmica de tipos? É aqui que os tipos de
variáveis, por exemplo, são
conhecidos em tempo de execução. Se houver algum problema com os tipos ou algo parecido, podemos compilar o
software perfeitamente No entanto, se houver um erro, não
saberemos até que o
software esteja realmente em execução. O que eu quero dizer com tudo isso? Bem, vamos dar uma
olhada em um exemplo aqui. Aqui eu tenho um número inteiro de amostra. Estou inicializando
com o valor de 55. Então, estou apenas enviando para
a tela. Na verdade, não está fazendo muita coisa. No entanto, e se eu
quiser talvez agora atribuir um valor de string
a esse número inteiro Se eu apenas digitar olá, por exemplo, você pode ver que
há um erro óbvio aqui. Ele não pode converter implicitamente
a string em um int. Isso porque o tipo
dessa variável é um número inteiro. Mas o que estamos tentando fazer aqui é colocar uma corda nela. Não vai para cartas. Não só isso, mas nosso
programa não compilará. Você pode ver que há
um erro aqui. Este é um exemplo da verificação de tipo
estático. Ele sabe que é um número inteiro, então é um tipo inteiro Mas agora estamos tentando
colocar uma corda lá dentro. Mas, na verdade, estamos alertados sobre esse problema no
momento em desenvolvimento Portanto, isso é conhecido como verificação de tipo
estático. No entanto, com algo
como a verificação dinâmica de tipos
, você não será
alertado sobre esse erro Tudo ficará bem, o software
compilará perfeitamente Mas, a menos que você faça algo sobre esse
erro específico aqui, você será alertado sobre
esse erro durante o tempo de execução Então, existem outras
linguagens de programação disponíveis,
por exemplo, Python ou Agora, essas são linguagens
digitadas dinamicamente. Isso significa, por exemplo, que
podemos fazer isso e o software compilará
perfeitamente, sem problemas No entanto, você será
alertado sobre esse erro durante o tempo de execução enquanto
o software estiver em execução Isso é chamado de tempo de execução e
é aqui que o erro pode se apresentar
em tempo de compilação É aqui que o C Sharp pode detectar esses possíveis erros relacionados
aos tipos, e isso é chamado de verificação
estática de tipos No entanto, em tempo de execução em
linguagens como Python, Ruby, você será alertado
sobre Por exemplo, durante o tempo de execução, e isso é chamado de verificação
dinâmica de tipos. Agora eu falei sobre verificação de tipo
estático e verificação
dinâmica de tipos
e as diferenças. será mais fácil
explicar a Agora será mais fácil
explicar a palavra-chave dinâmica. Portanto, nos bastidores,
a palavra-chave dinâmica se comporta de forma semelhante
ao tipo de dados do objeto Se você assistiu meus
tutoriais anteriores, onde falei sobre o tipo de dados do objeto e seu canal, considerado
a classe base para
todos os tipos,
por exemplo, a classe base do bolen
inteiro duplo Mas não só isso,
mas coisas como listas, objetos personalizados
e coisas assim. Então, se você se lembrar
e entender detalhes sobre o tipo de dados do
objeto, você vai começar a trabalhar com a palavra-chave
dinâmica. Agora vamos dar uma
olhada em um exemplo. Então, o que vou
fazer agora é fazer um exemplo com o tipo de dados do
objeto. Então, essa variável
aqui chamada teste, será um objeto de tipo. O que estou fazendo é
armazenar um valor aqui,
35,5, que pode ser o dobro Por exemplo,
parece um duplo para mim, mas não há
problema aqui porque objeto é como uma classe
base aqui, ele aceitará
esse valor perfeitamente. Mas agora estamos tentando
incrementar esse valor de teste, que é objeto de tipo de dados 7,5. Parece que estamos
adicionando a a a um duplo O que deveria ser bom quando o
tínhamos em dobro antes. Funcionou sem problemas. Então você pode ver aqui, não
há problema. Mas agora que transformei isso em um tipo de dados de objeto,
há um problema. Então, se eu destacar
isso, diz que o operador plus
não pode ser aplicado ao objeto e o double ao
trabalhar com o objeto Falamos sobre
boxing e unboxing O que estou fazendo aqui é que tenho
um tipo de dados simples aqui,
35,5, que é como um duplo, e estou
inserindo isso em um tipo de dados de objeto Agora, se você se lembra de antes, esse é um tipo de referência, então ele é armazenado na área de
aquecimento da memória. O que estamos fazendo é colocar
o valor aqui em teste. Quando tentamos incrementar o valor, há
um problema aqui Não podemos adicionar 7,5 a
esse valor aqui. O que precisamos fazer aqui ao incrementar o
valor, por exemplo, é converter explicitamente
esse tipo de dados de objeto em um tipo com o qual possamos trabalhar O que estamos tentando fazer é
adicionar 7,5, que é um duplo, então eu tenho que converter
isso em um duplo. Podemos
convertê-lo em um duplo usando a
classe de conversão estática que
sempre usamos nos tutoriais anteriores E isso vai
funcionar muito bem. O que estou fazendo aqui é
desembalar o valor aqui. Estou boxeando aqui, estou fazendo unboxing. Há um pouco de carga útil de
desempenho aqui quando fazemos o boxe e o
unboxing , como falamos Mas funciona muito bem ao converter
o objeto em um duplo. Então eu estou adicionando um duplo a ele, depois estou armazenando o valor de
volta no objeto,
então eu o reencaixoto novamente e, em seguida, estou
produzindo o Se eu executar o programa, agora você verá que tenho o valor 43, que parece correto. Você pode ver que
funciona. Não tem problema. Na verdade, posso somar
valores. Posso até adicionar cinco aqui, por exemplo, e
vai funcionar muito bem. Essa é uma pequena
vantagem de usar algo assim em relação a tipos de dados
individuais, mas há um custo de desempenho. Mas o que estou
tentando dizer é que quando você usa o tipo de dados do objeto e
deseja modificar os valores, você precisa fazer esse
unboxing Você precisa fazer uma conversão
explícita aqui. Agora, com a palavra-chave dinâmica
que estou prestes a apresentar, eu disse que ela está intimamente ligada
ao tipo de dados do objeto. Ele se comporta de forma muito semelhante. Mas não precisamos fazer essa
conversão explícita aqui E essa não é a
única diferença. Uma das principais diferenças
é que ele fornece verificação
dinâmica de tipos em
um ambiente C Sharp. Então, vamos começar com
a palavra-chave dinâmica. Então, a primeira
coisa que vou fazer,
para que você entenda
um pouco melhor, é converter esse exemplo
usando a palavra-chave dynamic. Então, o que eu faço aqui, eu defino essa variável
como dinâmica aqui. E como não é
o tipo de dados do objeto e não precisamos converter nada
explicitamente, não
precisamos dessa
conversão ali mesmo Então, se eu executar o programa agora você pode ver que ele está funcionando
exatamente como antes. Não está reclamando de adicionar um valor a um tipo de dados de
objeto Então você pode ver que há uma
vantagem considerável aqui. Não precisamos
converter explicitamente nossas variáveis, por exemplo Então, isso é muito bom. E,
como mencionei antes, funciona como o
objeto sob o capô. Então, é quase como, você sabe, a classe base principal
que trabalha com números inteiros, bouleenes e todas as
coisas Então essa é a primeira
vantagem de usar a dinâmica. Não precisamos converter nada
explicitamente, então não precisamos
dizer explicitamente:
ok, faça disso um Portanto, agora podemos adicionar um número inteiro a ele ou
torná-lo duplo Então, podemos adicionar um duplo a ele. Não precisamos fazer nada disso. Parece perfeitamente bom. Olha, então nós o
definimos como um duplo, agora estamos adicionando
um número inteiro a ele Toda a conversão do
casting, do
boxe e do boxe feito, é feita nos
bastidores Não temos nenhuma
visibilidade disso. Tudo está feito para nós. Então essa é uma vantagem disso, que a complexidade é
tirada de nós. Veja o que Als também pode fazer. Por exemplo, inicializamos, isso é como um duplo
e, em seguida, queremos
adicionar um número inteiro a Agora, e se eu disser que teste
é igual a olá, por exemplo? O que você acha que vai acontecer? Agora vamos executar o aplicativo, o que parece,
estamos emitindo hello Então, o que vou
fazer é
adicionar alguns pontos de interrupção aqui Vamos entrar no modo de pausa quando executarmos o aplicativo. E então vamos analisar esse teste de variável aqui embaixo. Então, vamos trazer isso à tona para
que possamos dar uma olhada melhor. Agora, você pode ver que temos um objeto dinâmico
aqui, que é teste. E ainda não tem um
valor porque
não executamos essa linha de código. Depois de passar por cima disso, podemos ver que o teste é agora, porque colocamos um valor
duplo nele, agora estamos incrementando
o valor em cinco, o que parece muito bom Então você pode ver que
ainda é um duplo. Agora, tentando colocar um valor de
string aqui, se superarmos isso, você pode ver que agora temos
uma string dinâmica aqui. Então, você pode ver que é bastante
flexível na forma como funciona. Isso praticamente descarta todo
o conceito de tipos ou, pelo menos, esconde de você o conceito
de tipos de variáveis Portanto, ao desenvolver
aplicativos, pode
parecer que
toda essa complexidade foi
tirada de você. Você não precisa se preocupar se
é uma string, se é um número inteiro Talvez programadores de Python, ou se você já fez
algum script Java, possam
achar isso Porém, erros podem
ocorrer durante o tempo de execução, e é nesse momento que o
aplicativo está realmente em execução. Portanto, há alguns
problemas associados
à palavra-chave dinâmica com os quais você
precisa ter cuidado. Então,
a palavra-chave dinâmica provavelmente soa
muito bem para você. Não precisamos nos
preocupar com tipos, não
precisamos converter
para tipos diferentes. Podemos simplesmente usá-lo
para tudo. Você sabe, por que não? E talvez haja um pequeno
desempenho aqui,
mas, por outro lado, parece
muito bom, certo? Bem, vamos falar sobre a desvantagem de usar a
dinâmica agora Mas primeiro vou apresentar um exemplo em que trabalhamos
com alguns objetos personalizados. Então, o que eu tenho aqui, eu tenho uma aula de videogame,
é bem simples. Ele tem quatro campos privados, um construtor, um método de amostra e apenas uma amostra de
propriedade pública aqui que acaba de receber o
título do videogame. Não faz muita coisa. Eu instanciei a classe. Aqui eu tenho um
objeto de videogame chamado Game One. Se você já seguiu meus 00
tutoriais anteriores, quando usamos essa
instância Aqui podemos ver várias coisas. Podemos ver nosso método get
publisher. E podemos ver nossa propriedade
aqui, o título. Podemos ver isso quando essa
janela aparece aqui, é como se o Visual
Studio nos ajudasse E outra palavra disso
é chamada de Intellisense. E o que o Intel Sense faz é apenas nos fornecer alguns recursos interessantes de
preenchimento automático Isso nos salva de digitar. Por exemplo, podemos
clicar duas vezes nisso e então temos acesso ao
método número um. Sabemos que o método existe. Número dois, sabemos que
podemos acessar o método, ele não é privado nem
nada parecido. Número três, se clicarmos
duas vezes nele, não
precisaremos nos
preocupar com a verificação
ortográfica de erros de digitação , então
é muito bom Ele também nos fornece os tipos de
parâmetros que
podemos usar e também nos
informa sobre os tipos de retorno. Portanto, o Intel Sense, também
conhecido como Visual Studio, nos
ajudar é um recurso
muito bom e eu recomendo fortemente usá-lo. No entanto, ao usar
a palavra-chave dinâmica, Intellisense não está disponível Agora, há uma boa
razão para isso, mas é uma das
grandes desvantagens relação ao uso da palavra-chave dinâmica. Vamos dar uma olhada nisso agora. No momento, estou apenas
montando um jogo aqui. Então eu quero obter
o editor, por exemplo, vamos
armazenar isso em uma string. Vou armazená-lo em uma
string chamada Pub. E então eu só quero
enviá-lo para a janela. Não está acontecendo muita coisa aqui. Deve produzir
Blizzard, por exemplo. Vamos executar o software agora e podemos ver a Blizzard Parece que está
funcionando muito bem. Agora vamos
transformar isso em um tipo dinâmico. Agora eu tenho um
objeto dinâmico chamado Game One. Ela tem o valor
da nova instância
da classe de videogame. Como eu disse, não
precisa ser o dobro de um inteiro. Pode ser um tipo complexo,
pode ser uma matriz, uma lista ou até mesmo uma classe personalizada, como a classe de videogame. Absolutamente, não há problema em
fazer isso. Totalmente suportado
pela palavra-chave dinâmica.
E, novamente, é como o
objeto nos bastidores. Está tudo bem até agora. E se eu executar o aplicativo, obteremos exatamente o mesmo
resultado, sem nenhum problema. Mas veja o que acontece. Agora eu coloco um ponto depois do primeiro jogo. Você pode ver que perdemos tudo
isso no sentido contábil. O Visual Studio agora se
recusa a nos ajudar. Não sabemos quais
métodos temos disponíveis, a menos que,
você sabe, analisemos isso e talvez os copiemos e
colemos. No entanto, ele tem muitos problemas
dessa forma. O fato é que ele depende
da Terra para não cometer erros. Número um, como eu disse antes, talvez esse seja um método privado, então nem podemos
acessá-lo fora dessa classe. Portanto, você sabe, poderíamos criar um
grande problema aqui. Então, se eu executar o aplicativo, agora ele está dizendo que está inacessível devido ao
seu nível de proteção Bem, e se eu cometesse um erro de digitação? E se eu colocar F aqui? Você pode ver que não está
destacando em vermelho. Execute o aplicativo e ele
não contém uma definição. Bem, isso é porque eu escrevi errado e foi um acidente Mas eu não tenho o Visual
Studio me ajudando. Eu tenho zero Intellisense. Portanto, essa é uma das desvantagens de usar a palavra-chave dinâmica Você não tem absolutamente nenhum
senso de inteligência. E o intellisense
é realmente útil, e muitas pessoas
consideram isso garantido Mas ele fornece
todos os métodos e propriedades que você pode
realmente usar em um objeto. Então você pode estar se perguntando o que
era aquela feitiçaria antes que você escrevia incorretamente o editor
e não havia Por que foi isso? O que está
acontecendo aqui? Por que o programa foi
capaz de executar você? Isso normalmente não é permitido. Bem, sim, isso é
verdade porque se eu transformar isso de volta em
um objeto de videogame, você pode ver que obtemos a linha vermelha. E isso porque,
no início deste vídeo, eu disse que C Sharp era uma linguagem digitada
estaticamente E isso significa que tudo
é capturado em tempo de compilação. Então, eu nem consigo compilar o aplicativo porque
é aqui que os erros são detectados No entanto, ao usar
a palavra-chave dinâmica
, tudo isso desaparece. Nada que seja dinâmico
é capturado em tempo de compilação. Então, o erro desapareceu. O programa pode compilar. O programa compila quando a janela preta aparece,
como você pode ver Mas agora o erro foi
realmente detectado em tempo de execução. E esse é o erro
que é gerado. É chamada de
exceção de fichário de tempo de execução, aqui. Portanto, exceção do fichário de tempo de execução. Portanto, isso acontece em tempo de execução , enquanto o software
está realmente em execução. Então, em poucas palavras,
quando você usa uma palavra-chave dinâmica como essa, o Visual Studio simplesmente
lhe dá rédea solta Literalmente diz, ok, faça o que quiser. Se algo for dinâmico,
chame qualquer mensagem que você quiser, ligue para qualquer propriedade que você quiser. Você sabe, isso não importa. Não vou
te dar linhas vermelhas. Vou deixar você
compilar seu software, você pode fazer o que
quiser Você pode introduzir o erro humano, basicamente. Você tem liberdade. Então, essa é uma vantagem, ou talvez uma grande desvantagem, de usar a palavra-chave dinâmica Portanto, a escolha é
sua nesse sentido. Mas linguagens de programação
como Python, Ruby até Java Script são linguagens de tipagem
dinâmica No entanto, C Sharp é uma linguagem de digitação
estática. Então você pode estar se perguntando, bem, por que uma linguagem
digitada estaticamente suporta isso em primeiro lugar Sabe, por que ainda
temos isso? Achei que fosse uma linguagem digitada
estaticamente. Bem, e se você quiser criar um software que funcione
com o software Python Por exemplo, se Python e Ruby são linguagens digitadas dinamicamente, talvez meu software
precise E uma maneira elegante de dizer
isso é chamada de interoperabilidade,
ou interrupção, ou interrupção Se eu quiser criar um
software que funcione com o software de
outra pessoa, mas eles usarem uma linguagem
diferente
, é aqui que a
palavra-chave dinâmica é realmente bastante útil, mesmo trabalhando com
o modelo de objeto de documento. Agora, isso é algo que
HTML e XML usam ao usar coisas assim. Você simplesmente não sabe
quais métodos e propriedades estão disponíveis
até o momento da execução. É por isso que é muito útil. Nem tudo é conhecido
no momento do compilador. Quando seu software é compilado, às vezes ele só é
disponibilizado para você em tempo de execução É por isso que a
palavra-chave dinâmica é realmente útil. Então, algumas terminologias
sofisticadas para você. Se temos nosso objeto simples de
videogame, como falamos antes,
e gostaríamos de dizer, chamar um método chamado
get publisher, esse é um exemplo do
que é chamado de vinculação antecipada. E isso significa que, ok, esse método está disponível para nós,
nós o estamos usando aqui. Qualquer erro será
detectado em tempo de compilação. Quando clicamos nesse
pequeno botão cinza e a encadernação é feita mais cedo, tudo funciona, não
há erro. Por exemplo, se eu fiz isso
, há um
exemplo de erro de vinculação antecipada. No entanto, se isso fosse dinâmico e tentássemos
fazer isso agora, não
temos ideia se esse
método está disponível. Não temos ideia
se esse método é público, privado, protegido
internamente. Não temos ideia se eu
escrevi corretamente. No entanto, quando executo
o aplicativo
, a vinculação é
feita durante o tempo de execução. Agora mesmo, ok? Sim, o método está disponível. Acabamos de ligar,
temos um resultado. Este é um exemplo
de vinculação tardia, vinculação antecipada antes da
vinculação tardia durante o tempo de execução. Algumas coisas que você
pode ouvir no futuro, mas pensei em
mencioná-las agora. Outra coisa que eu não
mencionei foi dinâmica. Se você definir uma variável, por exemplo, um número inteiro simples
ou algo parecido,
o que você realmente quiser,
o tipo não é importante Você não precisa inicializá-lo. Você pode, se quiser. Não há mal nenhum em fazer isso, mas não é obrigatório. Você não precisa dizer,
ok, isso é igual a cinco. Você pode resolver isso mais tarde. Isso é outra coisa que você pode
fazer com a palavra-chave dinâmica. Outra coisa que você pode
fazer com a dinâmica é até mesmo passá-la para métodos e
retorná-la a partir de métodos. Acabei de configurar um
método de amostra chamado Echo. Isso só vai ecoar o
valor da editora. Por exemplo, eu sei que fato,
uma editora de jogos
que comprará isso para mim, eu não tenho Intellisense Eu suponho que esteja escrito corretamente. Em seguida, vamos apenas
enviar isso para a tela. Vamos comentar isso e, em seguida, chamaremos
o método real. Isso parece muito bom. Estamos passando o objeto do
jogo, que é dinâmico, como parâmetro para o método e
ecoando o resultado
do método get publisher.
Vamos executar o programa. Parece que está funcionando. Você pode ver aqui, mas não
só como mencionei, também
podemos retornar a palavra-chave
dinâmica. Então, aqui estou chamando o método aqui que agora
não usa parâmetros. Estou inicializando um novo objeto de
videogame e o estou devolvendo instantaneamente Mas estou retornando
a palavra-chave dinâmica porque não quero
um objeto de videogame. E então eu estou pegando
o resultado aqui em um novo objeto de jogo dinâmico, e então eu estou comprando
o editor Assim, você pode ver igualmente que também funciona como um retorno, dinâmico. Você pode passar por aí
sem nenhum problema. Então, vamos resumir a palavra-chave
dinâmica agora mesmo. A palavra-chave dinâmica,
não precisamos nos preocupar com os tipos, não
precisamos nos
preocupar com os tipos de elenco. Toda a
conversão do boxe e do boxe é feita para nós. Isso é ótimo. No entanto,
há um impacto no desempenho. Novamente, precisamos nos
preocupar em soletrar nossos métodos corretamente, se eles estiverem
realmente acessíveis Muitas coisas diferentes. Em poucas palavras, a dinâmica não é usada em um aplicativo C
Sharp típico Se você está apenas
criando uma calculadora ou algo bem simples, não deveria realmente usar
a palavra-chave dinâmica. No entanto, se você estiver trabalhando com talvez outros softwares desenvolvidos
em linguagens dinâmicas, ou talvez algo
chamado objeto com ou modelo de objeto de documento para HTML. É aqui que a palavra-chave
dinâmica brilha e é aqui que
você deve usá-la, porque em casos
como esse, você não tem acesso a esses métodos
em tempo de compilação Você só pode ter acesso
a eles em tempo de execução. Então é aqui que você usaria a palavra-chave dinâmica
nesse sentido. Portanto, ele não é usado em aplicativos
comuns de lojas. Portanto, é um daqueles
cenários que você nunca
realmente se pergunta se devo usar a palavra-chave
dinâmica. Geralmente é apresentado a você. Ok, sim, definitivamente
parece que eu deveria usar
a palavra-chave dinâmica. E isso é o que geralmente
acontece quando você está arquitetando um novo software
, por exemplo Portanto,
a palavra-chave dinâmica oferece verificação dinâmica de tipos e é basicamente
o tipo de dados do objeto, mas com esteróides.
Obrigado por assistir. Espero que tenha sido útil.
68. 16-3. A palavra-chave var e a inferência de tipo: Com base em tudo o
que aprendemos até agora. E se eu dissesse que
não precisamos mais de tipos de dados? Por exemplo, não precisamos de um tipo de dados de objeto de
videogame. Não precisamos de um tipo de dados de lista. Não precisamos de um tipo de dados de
matriz de strings, nem mesmo de um Interble
ou de um caractere E está tudo bem e
o software será compilado. Que diabos está acontecendo aqui? Bem, deixe-me apresentar
algo completamente diferente. Agora, neste tutorial,
vou falar sobre
a palavra Varki em C sharp Parece algo assim. Se você ainda não assistiu aos
meus tutoriais anteriores sobre a palavra-chave dinâmica, onde
falei sobre verificação dinâmica de
tipos e também verificação estática de tipos, todas essas coisas boas
, recomendo fortemente que você os assista antes de
continuar com Caso contrário, você terá
mais dificuldade entender os conceitos
destacados neste tutorial. Então, qual é a
palavra-chave Var? Como isso funciona? Bem, podemos usar a palavra-chave Var ao definir algo
como uma variável. Por exemplo, temos
uma variável inteira aqui e a definimos como 55 Também poderíamos
definir isso como v, o que parece ser um tipo de dados Var. No entanto, Va não é um tipo de dados. A palavra-chave Var é uma
abreviatura de ok. Descubra que
tipo de dados isso realmente é quando você compila seu
aplicativo, por exemplo Portanto, todas as verificações usando a palavra-chave Var são
feitas em tempo de compilação Agora, lembre-se de que, em nosso último
tutorial, falamos sobre a palavra-chave dinâmica e como tudo relacionado a
uma palavra-chave dinâmica foi descoberto em tempo de execução Por exemplo,
os métodos existem? As propriedades existem? E então meio que o
une em uma encadernação tardia. Em tempo de execução, bem, o Va é feito em tempo de compilação Por exemplo,
se eu tentar chamar um método em uma variável var, por exemplo, ocorrerá erro
se o
método não existir. Mas vamos
abordar isso mais tarde. Vamos dar uma
olhada em um pequeno exemplo usando a palavra-chave var e
depois partiremos daí. Vamos dar uma olhada em alguns exemplos
simples agora. Aqui eu tenho uma
variável local chamada teste. Mas em vez de fornecer, digamos, um número inteiro ou uma string
ou algo parecido, estou usando a palavra-chave var aqui E, como mencionei antes, cabe ao Visual Studio e ao compilador descobrir
qual tipo de dados é esse Eu digo Visual Studio porque acabei de definir
a variável aqui. E se eu passar o mouse sobre
ele aqui, você pode ver que ele pensa que
é um número inteiro Se eu mudar isso para uma string, realmente não importa o que está lá. Ela pode estar vazia. Eu passo o mouse sobre o teste e agora é um tipo de dados de string O que ele faz é determinar
o tipo de dados com base no
que você os inicializa Eu o inicializei em uma string. Aqui você pode ver quando
eu passo o mouse sobre ele, é um
tipo de dados de string, assim como antes Pode ser um número inteiro
ou até mesmo um duplo, por exemplo, agora é um duplo Agora, quando eu realmente
compilo o aplicativo, é
aqui que ele
descobre se algo é válido ou inválido com
base no que você fez Esse é o processo de compilação
e é aqui que ele realmente
descobre qual tipo de dados é o tempo de compilação Esse é um exemplo simples como Var não é um tipo de dados. Mas você pode ver
que, na verdade, ele baseia seu tipo de dados no que
você os inicializa O que acontece se eu
não inicializar? Bem, isso não é possível. Na verdade, você não pode
definir algo com a palavra-chave var e
não atribuir um valor ,
porque o
sistema não pode calcular um tipo de dados
a partir
disso, sempre que usar a palavra-chave var sempre
deve
inicializá-la para
descobrir qual tipo de dados é, por exemplo, uma string O processo de calcular o tipo de dados com base
no valor de inicialização,
bem, há uma
palavra chique para
isso e se chama inferência de tipo Você pode ouvir isso no futuro. É chamado de inferência de tipo, e é aí que adivinhamos o tipo de dados com base
no valor inicial aqui Agora, nossa variável local
aqui, o tipo, é uma string porque ela
é baseada no
valor de inicialização aqui O que não podemos fazer então
é simplesmente converter isso em um
tipo totalmente diferente. Você pode ver aqui. Não é possível converter o tipo em string
depois de inicializado. Por exemplo, agora
é uma string. É praticamente uma
corda para toda a vida. Não podemos então, ok, torná-lo um número inteiro,
torná-lo um booling Não podemos fazer isso
com a palavra-chave Var. Vamos dar uma olhada em um exemplo com alguns objetos mais
complicados. Agora, por exemplo, vamos
definir um objeto do jogo. Esta é nossa classe de
videogame, na qual apenas
passamos
alguns valores de amostra. Aqui, você pode dar uma olhada
na aula aqui.
Não há muita coisa acontecendo. Campo privado, um construtor
e um método de amostra. O que vou fazer é
chamar esse método de amostra aqui chamado get publisher
back out here. Estou configurando um novo objeto de
videogame, mas estou armazenando isso
em um jogo aqui, que usa a palavra-chave Var. Agora, usando esse objeto de jogo, você pode ver que eu tenho o Intellisense
completo aqui tenho a ajuda completa do
Visual Studio Ao contrário da palavra-chave dinâmica, porque lembre-se de que,
no último tutorial quando falei sobre dinâmica, tudo é
descoberto em tempo de execução Portanto, não temos nenhum
Intellisense,
porque tudo isso é
descoberto em tempo de Então eu tenho acesso total
ao Intellisense. Portanto, não vou cometer erros de
digitação, métodos de adivinhação, chamar métodos que talvez sejam privados e vou
chamá-los fora
da classe atual Não vou cometer
esses erros como talvez faria usando
a palavra-chave dinâmica. Então, se eu executar o aplicativo, agora você pode ver que estou recebendo
o editor sem problemas e tenho acesso total
ao Intellisense disponível Então, vamos falar sobre
algumas armadilhas do uso da palavra-chave Var O que eu não posso fazer com isso? E por que isso é ruim? Por exemplo? Bem, ao contrário da palavra-chave
dinâmica, Var realmente não tem
muitas desvantagens ou muito impacto negativo No entanto, existem
algumas desvantagens. Por exemplo, não podemos usar
a palavra-chave var com métodos. Então, aqui eu tenho um método
de teste aqui. Se eu tentar devolver
algo do tipo var, ele não vai me deixar. Da mesma forma, se eu usá-lo como um parâmetro e apenas
dar um nome a ele, novamente, ele também não vai me
deixar. Isso ocorre simplesmente porque Visual Studio não
tem informações suficientes disponíveis para adivinhar o tipo com base em um retorno
ou em um parâmetro. Ou pelo menos é nisso que
sou levado a acreditar. Mas você não pode usar
a palavra-chave var como parâmetro para um método, nem mesmo retornar um
v de um método. Simplesmente não é possível. Mas com a
palavra-chave dinâmica, por exemplo, você pode, você não pode
com a palavra-chave var. Vamos dar uma olhada em
mais uma possível desvantagem de usar a palavra-chave Var Agora vamos limpar algumas
dessas coisas aqui. O que eu vou
fazer, digamos, por exemplo, eu quero criar algum software
financeiro. Quero que calcule dinheiro, mas quero um alto grau
de precisão decimal Não quero
perder dinheiro porque meu software não permite casas decimais
suficientes É muito fácil de fazer. Em uma instância como essa, preciso de um tipo de dados decimal Se você se lembra do
meu tutorial inicial onde falei sobre decimais, falei sobre flutuadores e
falei sobre Se você se lembra, o decimal tem o maior
grau de precisão,
portanto, muitas casas decimais As duplas estão em algum lugar
no meio. E os carros alegóricos têm a
menor precisão, o menor número
de casas decimais Quero um decimal porque
estou trabalhando com dinheiro, não
quero que nada
se perca Vou criar
uma nova variável. Ele vai usar
a palavra-chave var e eu
vou chamá-la de dinheiro. Agora, vou
inicializar isso. Talvez não importe realmente
qual valor, por exemplo, mas vou colocar talvez
algo assim. Na verdade, não,
vamos fazer com que seja zero. Então, eu o inicializei como zero e agora, se eu me
debruçar sobre isso, você pode ver que presume-se que
o tipo de dados é duplo Agora, o dobro é como um grau médio de precisão,
mas não há erro. Você sabe,
não há nada de errado com isso sintaticamente.
É perfeito. O aplicativo é executado. Estou produzindo zero aqui. Agora o sistema não sabe minha intenção, o
sistema não sabe. Quero criar um
aplicativo baseado em dinheiro. Na verdade, eu quero um alto
grau de casas decimais. Eu quero que isso seja um
decimal nos bastidores. Então, como eu faço isso? Bem,
ao definir um decimal, você precisa simplesmente
colocar m ali E se eu gastar dinheiro, você pode ver que agora é um
decimal, não um duplo Mas você pode ver que isso é
apenas um erro humano. Eu poderia facilmente esquecer de
escrever isso e agora
tenho um duplo. Então, talvez se eu
compilar meu software, entregá-lo aos meus clientes, eles comecem a usá-lo, por exemplo Em seguida, eles percebem que falta um
pouco de dinheiro devido ao arredondamento, porque se supõe que
seja um dobro Então, estou perdendo muito grau de precisão ao cometer
esse pequeno erro. Este software é responsável
por perder dinheiro, e isso não é bom. E, novamente, você pode
não estar perdendo dinheiro. Você pode estar ganhando dinheiro, mas o fato é que está errado. Então, eu poderia facilmente esquecer de usar esse M aqui e obter um decimal Portanto, é algo que você
deve ter muito cuidado ao fazer. Então, vou destacar isso
para você agora, se eu definir esse valor monetário com um alto
grau de precisão decimal, porque estamos
trabalhando com dinheiro, quando executo o aplicativo, você pode ver que toda essa
precisão foi truncada, então muitas
informações estão faltando E isso é apenas pelo fato
de usar um m aqui. Então, você sabe, é
muito fácil de fazer. Por outro lado, se eu encontrasse isso como um decimal, para começar E então eu faço
algo assim, então você pode ver que
há uma linha vermelha, então o software nem mesmo
compila. Há um erro. E está
basicamente dizendo, ok, se você precisa de um decimal, você tem que
usar o sufixo M aqui Eu nunca vou cometer esse erro. Se eu definir explicitamente esse dinheiro variável como
um tipo de dados decimal, é um cenário
específico em
que uso de uma palavra-chave Var
pode criar problemas No futuro, quero
mostrar outro exemplo agora relacionado à palavra-chave Var e uma possível desvantagem
de usá-la Aqui eu tenho minha aula de
videogame aqui. Tem vários
campos aqui. O que vou fazer é
copiar esses campos e movê-los para copiar esses campos e movê-los o método principal
aqui
para que eu possa
ilustrar algo O que eu tenho, eu tenho esses
vários tipos aqui. Eu tenho números inteiros, sequências de caracteres, lista de números inteiros e também
um objeto de jogo O que vou fazer, em
vez de ter esses tipos de dados aqui, vou substituí-los
todos pela palavra-chave Var. E você notará algo quando eu altero as informações do jogo
para usar a palavra-chave Var, agora temos que atribuir um valor a ela antes de deixá-la assim. O que é chamado de nulo
, não tem valor, e falaremos sobre nulo
em um tutorial posterior Mas agora ele realmente precisa um valor porque
precisa calcular o tipo de dados
a partir do momento em que você
instancia o objeto Então, agora não podemos deixar
isso vazio assim. Precisamos dar um valor a isso. Essa é uma
coisa importante a ser observada. Ao usar a palavra-chave var, precisamos inicializá-la O que vou fazer é
transformá-las na
palavra-chave Var. Então, também podemos ver
mais uma coisa. Agora, a outra desvantagem, talvez uma desvantagem potencial, ou pelo menos a consciência, é que ao analisar
as variáveis declaradas aqui, é
difícil dizer quais são esses tipos de
dados Talvez possamos
descobrir que o console é uma string e o título é
uma string, etc Mas podemos ver o zero
e saber que é um número inteiro. Mas usando isso, especialmente em
qualquer outro lugar
do aplicativo, teríamos que passar
o mouse sobre a variável a cada vez e descobrir que é um número inteiro observando apenas esse nome Obviamente, há
var próximo a ele, então também não vemos o tipo de dados
int vista, não está claro primeira vista, não está claro que tipo de
dados é esse Talvez possamos ser
mais cuidadosos com os nomes de
nossas variáveis e
talvez chamá-las de rating int, ou talvez de rating number. E então sabemos à primeira vista que, ok, é um número É especialmente útil
na depuração, mas é apenas algo a ser
observado ao usar a palavra-chave var,
especialmente ao
declarar as especialmente ao
declarar Aqui, esse tipo de informação
explícita
com relação ao tipo de dados
desapareceu Na verdade, só podemos ter o valor
inicial para analisar. Temos que passar o mouse sobre cada um deles apenas para ter clareza
sobre o tipo de dados Então, quando você tem um software grande e
complicado e está
tentando depurar centenas de variáveis, pode ser muito
demorado descobrir qual é
o tipo da variável, e talvez haja um problema de tipo Talvez você esteja tentando alimentar uma string em um
número inteiro, por exemplo Se isso for um bug em potencial, pode levar, você sabe, um pouco mais para resolvê-lo quando não temos tipos
explícitos aqui E estamos meio que
passando o mouse sobre cada um para
descobrir qual é o tipo E de forma alguma isso é
um obstáculo, apenas força você a adquirir o bom
hábito de nomear
suas variáveis corretamente Por exemplo, uma variável chamada número de
avaliação pode ser um nome
melhor do que apenas classificação. Ele fornece um pouco mais de informações sobre os dados que você está
armazenando nessa variável. Na verdade, ele ensina você
a ser um desenvolvedor melhor. A última coisa sobre a
qual quero falar
é sobre quando devo usar
a palavra-chave Var? Devo ignorá-lo
completamente e apenas
mantê-lo como um pouco de conhecimento ou
devo usá-lo o tempo todo? Há alguma queda? Há alguma razão prática? Bem, muitas pessoas realmente usam a palavra-chave Var
para tudo. Eu examinei softwares e eles nem usam tipos de dados, ou pelo menos quase nunca
tudo tem a palavra-chave Var. Quero dizer, não há nada
realmente errado com isso, especialmente se você usar tipos de variáveis
descritivas Você é muito
cauteloso ao
definir decimais e
flutuantes Portanto, não há nada realmente errado em usar
a palavra-chave Var. Você pode usar a palavra-chave Var
para praticamente tudo ou usar tipos de
dados padrão. Depende de você. Mas há algumas
situações em que a palavra-chave Var
tem algumas vantagens. Então, deixe-me mostrar esses agora. Então, vamos esclarecer alguns
desses exemplos aqui. Digamos, por exemplo, estamos criando um
software que gerencia várias lojas
de videogame. Temos nossa aula de
videogame aqui. Cada loja que
vende videogames terá uma lista de
videogames em sua coleção Vai ficar mais
ou menos assim. No entanto, queremos
gerenciar várias lojas. Cada loja terá uma
lista de videogames, mas talvez queiramos
catalogar o que
cada loja tem. Em uma situação como essa, teríamos
uma lista de videogames. E isso será como a Ultimate Game
Collection, por exemplo. Então, nesse caso,
veja esse tipo de dados aqui. É muito longo, é
muito chato de escrever, até mesmo
é muito complicado de
ver Você pode até mesmo expandir
isso dizendo: “ Eu tenho uma lista de
uma lista de uma lista”. Então você sabe o tipo de
situação que acontece. Você pode ver o quão grande isso é. Mas em uma situação como essa, você pode usar a palavra-chave var. E isso simplesmente
simplifica tudo isso. Isso economiza muita digitação. E você pode ver que tem um bom atalho útil
nos casos em que você tem tipos de dados
muito grandes aqui e
não quer
digitar tudo e, por qualquer motivo,
a Intell Sense não está
oferecendo isso para você não quer
digitar tudo e, por qualquer motivo, Intell Sense não está
oferecendo isso para Ou talvez você queira fazer um
loop sobre ele e não queira gravar todo
esse tipo de dados. É muito fácil
usar a palavra-chave Var. Você sabe, não tem
problema nenhum. E, você sabe, em casos como
esse, você não está definindo decimais ou duplas e existe o risco
de talvez perder a precisão
decimal, então algo
assim É uma maneira bem fácil de fazer isso. E você pode ver como foi
rápido digitar apenas três caracteres
no teclado versus
tudo isso aqui. Apenas um exemplo, também
há mais alguns
exemplos, que ainda não abordamos, mas
abordaremos um deles. Então, um dos dois exemplos é algo chamado de consultas de links E outro exemplo é a
criação de objetos anônimos, sobre os
quais
falaremos em breve. E a palavra-chave var é muito boa para criar objetos anônimos. Mas, para resumir,
a conclusão deste tutorial é que var não
é um tipo de dados Var é apenas uma boa
maneira de dizer, ok, vamos descobrir o tipo de dados com base na inicialização E esse processo é
chamado de inferência de tipos. Então essa é a
palavra-chave var em C sharp.
69. 16-4. Tipos anônimos: Neste tutorial,
falarei sobre tipos anônimos na loja C. Se você ainda não assistiu ao meu
tutorial sobre a palavra-chave Var
, recomendo fortemente
que assista primeiro antes de assistir a
este tutorial. Então, tipos anônimos,
o que são? Vamos dar uma
olhada em um exemplo aqui. Aqui eu tenho uma classe
chamada videogame e estou criando quatro objetos. Realmente não
importa o que está aqui, mas há um construtor, alguns campos, várias propriedades
e coisas assim Então, você pode ver neste exemplo que estou configurando quatro
objetos aqui prefixando-os com nossas
classes como um tipo de dados Em seguida, estou instanciando
um novo objeto com todos esses parâmetros Mas para fazer isso, eu tenho que criar uma classe. Agora, minha classe precisa
ter um construtor. Bem, não
precisa ter um, mas eu tenho um
e quero um. Tem todos esses campos privados, alguns métodos, propriedades
e coisas assim. Então, tem todas essas
coisas nesta classe aqui, só
para criar objetos aqui. Mas com algo
chamado tipos anônimos, não
precisamos definir uma classe. Você vê essa classe aqui
onde definimos videogame. Não precisamos de nenhuma
dessas definições. Não precisamos desse arquivo. Não precisamos dessa classe em si. Então, como isso funciona? Por que seria benéfico
não ter uma aula, mas precisarmos
instanciar a partir da Isso não faz sentido para mim. Explique os tipos anônimos, eles são úteis por
alguns motivos. Um dos principais motivos
é algo chamado Link. Agora, não
falamos sobre Link, então não vou falar sobre isso agora. Mas outra situação,
por exemplo, digamos que você esteja prototipando
um software Você quer fazer um
software rápido para garantir que
algo funcione. Ou talvez você não
queira criar uma classe inteira com
muitos métodos e outras coisas. Porque o que você está criando é algo bem
simples e rápido. Então, na verdade, existem alguns
motivos. Mas um dos
benefícios é a velocidade, e outro benefício
é que, se você não está criando algo
particularmente complicado, talvez ele tenha apenas duas propriedades e você não esteja
fazendo muita coisa com isso. Depois, você pode usar o que é
chamado de tipos anônimos. Então, como faço para criar uma instância de uma classe
que não existe? Bem, essa é uma pergunta muito
boa. E começa com
a palavra-chave var. Então, o que vou
fazer é
simular esse objeto de
videogame aqui, mas em vez de usar
a classe de videogame, vou usar
um tipo anônimo Então,
excluímos
todos eles e vamos usar
esse como exemplo. Como posso instanciar uma classe que não existe
usando tipos anônimos Bem, como a
classe não existe, portanto é
anônima, não podemos realmente iniciá-la com
um nome de classe aqui. É aqui
que
usamos a palavra-chave var sobre a qual falamos
em um tutorial anterior. Agora que queremos dar um nome a ele, vou
chamá-lo de game on. Agora precisamos instanciar
um novo objeto anônimo. Como fazemos isso?
Usamos a nova palavra-chave, mas agora usamos colchetes. Agora, dentro desses colchetes encaracolados, vamos configurar nossas
propriedades para nossa classe Essa linha aqui praticamente
imita essa linha aqui. A única diferença é que
não precisamos definir uma classe. Essa classe não
precisa existir. Podemos chamá-los do
que quisermos. Não importa porque
é do tipo anônimo. Se eu usar meu objeto aqui, se eu colocar um ponto aqui, você verá que posso acessar todas
as propriedades que
eu defini aqui. Eu os escrevi usando personagens
malucos como Gampd, mas você pode ver
que isso aparece
na lista e eu posso realmente
acessá-lo como uma propriedade Aqui temos um console
aqui, editor e classificação, você pode ver que não
importa como eu os chamo, não
importa
quais valores eu forneça. Isso é puramente anônimo
porque não tem nome, não tem classe Por ser anônimo, nós o
armazenamos usando a
palavra-chave var em um objeto. Aqui, você pode ver que
isso é muito poderoso. Não precisamos de uma classe, ela é completamente
anônima e, para fazer isso, basta usar
a nova palavra-chave aqui. Mas há algumas
exceções com isso. Quando criamos um tipo anônimo como esse aqui, só
podemos criar propriedades somente para
leitura. Não há construtor, não
há métodos, há campos privados Imagine se essa
classe aqui chamada videogame fosse um objeto
anônimo, então a única coisa que
você pode ter aqui são propriedades somente para leitura, título, por exemplo, classificação do
editor
e somente para leitura. Você só pode obter os valores, só
pode defini-los uma vez. E é aí que você
define o tipo anônimo, aqui mesmo, o objeto
anônimo, mas nos bastidores, isso é o que seria gerado quando você cria
um tipo anônimo. Portanto, leia somente propriedades, sem construtores, sem
campos, sem métodos Então, elas são as limitações de
usar algo assim. Na verdade, não para por aí. Ao criar tipos anônimos. Aqui, o que podemos
realmente fazer é colocar um tipo anônimo dentro de
outro tipo anônimo. Podemos criar uma variedade
de tipos anônimos. Então, muitas coisas diferentes
podemos fazer com eles. Deixe-me mostrar um
exemplo agora. Neste exemplo, eu tenho
um tipo anônimo
aqui dentro de outro tipo
anônimo. Se eu usar meu tipo de animal
aqui e for para ponto, posso ir até
uma espécie
que também é anônima e acessar o ruído que
o animal pode fazer. A espécie poderia ser um cachorro, em que o nome do
animal seria um cachorro, e então o barulho
seria um bar. Por exemplo, você pode ver que eu
realmente tenho tipos
anônimos em cascata Eles são muito poderosos
nos quais trabalham. E você pode ver, assim como usando a palavra-chave Var, como antes, que
você tem controle total
sobre o Intel Sense. Você pode ver claramente tudo o
que especificou aqui. Isso é muito legal. Uma coisa
que você realmente não deveria fazer, mas pode fazer é passar esses tipos
anônimos para métodos. Vamos dar uma olhada em um exemplo. Agora, quando falei sobre
a palavra-chave var antes, você não pode ter var como parâmetro para um
método, ela não funciona. O que você precisaria é da palavra-chave dinâmica na
qual isso funcionaria. Se eu então chamar o método de
teste
aqui, passo nosso animal aqui mesmo. E então podemos
acessá-lo de dentro daqui. Mas como estamos usando dinâmica, se você assistir meu
tutorial dinâmico, não
temos acesso
ao sensor da Intel aqui, mas podemos usá-lo No entanto, novamente, não devemos realmente usar a dinâmica
quando não precisamos. Na verdade, só é
recomendável usá-lo quando for
absolutamente necessário. Não vejo muita
situação em que você possa estar passando um
tipo anônimo para um método. Realmente, eles devem ser usados apenas dentro dos métodos,
eles estão definidos. Mas se você precisar fazer isso, sim
, você pode usar
a palavra-chave dinâmica
para contornar esse problema. Então você pode ver agora
que estou usando a dinâmica. Não tenho acesso
ao Intel Sense, mas agora posso passar isso
para esse método aqui. Então, vamos
verificar se funciona. Então você pode ver aqui
saindo uma casca, parece que
funciona muito bem Este é um exemplo de tipos
anônimos na loja
C porque é um
tipo anônimo e não tem nenhum tipo. Portanto, é quando você
usaria a palavra-chave Var. E você pode ver aqui que você
pode passar dois métodos, mas você teria que usar a palavra-chave
dinâmica para passá-la. Mas eu não
recomendo fazer isso. Por fim, ao criar tipos
anônimos, são apenas propriedades
e, uma vez definidos, são
considerados somente para leitura E você não pode modificá-los, como você pode ver aqui, esses são
tipos anônimos na loja C.
70. 17-1. A palavra-chave nula: Neste tutorial,
falaremos sobre a palavra-chave null A palavra-chave nula é mais
ou menos assim. O que é a palavra-chave nula
e como ela também é usada? Por que devemos usá-lo? Se você assistiu ao meu tutorial
anterior, quando falamos sobre memória de pilha
e pilha, tipos de referência
e tipos de valor
, entenderá esse tutorial muito rapidamente Aqui estão alguns objetos do
tipo de referência, como listas, strings, matrizes, objetos de
videogame, por É uma aula personalizada. Todos esses são tipos de
referência e são armazenados na pilha,
que é a área da memória da pilha Em contraste, esses
são tipos de valores simples, ou
seja, números inteiros, boolings e
caracteres Agora, você já se perguntou
quando declara uma variável, então não a inicializamos, não
estamos dando valores a ela não
estamos dando Você pode ver o
software compilar, funciona, não tem problema Nós os declaramos,
tudo parece muito bom. Mas você já
pensou em quais seriam os valores padrão
para eles? Se na verdade não
atribuirmos a eles um valor, qual seria o
valor padrão? Seria zero? Seria, o que seria? Bem, vamos dar uma olhada. Vou adicionar um
ponto de interrupção no final daqui
e, em seguida, vou dar uma olhada
na janela dos habitantes locais. Vamos executar o aplicativo. Agora, se chegarmos até
a guia de locais aqui, podemos ver várias
coisas relacionadas às nossas variáveis que
acabamos de definir Aqui você pode ver nossos tipos de
referência. Temos nossa lista aqui, temos nosso objeto personalizado aqui, nossa matriz de strings aqui,
você notará algo. O valor atual é não. Mas se você observar esses tipos de
valor, como o inteiro, booleano e
o caractere, ou se seus valores padrão
forem um pouco Normalmente, um tipo de valor
terá um valor padrão de zero. Se você representar Bolen como
zero, então seria falso. Um boolen como um seria verdade. Você pode ver que Bolen também tem
um valor padrão de zero. Até mesmo essa variável de caractere aqui tem um
valor padrão de zero. Você pode ver um padrão aqui. Parece que os tipos de
referência têm um valor padrão nulo ou qualquer que seja nulo, os tipos de valor têm um valor padrão
que parece Neste exemplo aqui, o que está acontecendo aqui? Lembra quando falamos
sobre tipos de referência? Quando temos um tipo de referência, um ponteiro na
pilha é criado Mas a verdadeira essência
da operação, os dados, vivem na pilha O ponteiro na pilha aponta
para os dados na pilha. Agora, declaramos um tipo de
referência aqui. Por exemplo, essa lista e
seu valor padrão são nulos. Agora, o que null está dizendo aqui
é que é uma referência nula. Temos nosso ponteiro
na pilha de chamadas. Isso está na
área de pilha da memória, mas ainda não temos
nada na pilha, não o instanciamos Isso significa usar
a nova palavra-chave. Quando instanciamos algo
usando a nova palavra-chave, estamos criando algo na área
da pilha da Nesta parte, estamos criando
o ponteiro na pilha. Nesta parte, estamos realmente
criando os dados na pilha e, portanto,
o ponteiro aponta para No entanto, não estamos instanciando
nada no momento. Temos nosso ponteiro
na pilha, mas ele não está apontando para Não há referência aos dados
na memória da pilha. Portanto, o
valor padrão é null, que significa
uma referência nula Não vai a lugar nenhum. No entanto, assim que
usarmos a nova palavra-chave
, o valor mudará de nulo e apontará
para os dados na pilha Pense em nulo
como nada ponteiro nulo
ou uma referência nula Na verdade, não vai a lugar nenhum, mas talvez mais tarde chegue. Por exemplo, você pode ver aqui isso só se aplica a objetos do tipo
referência, objetos
complicados, como
falamos antes. Ela não se aplica a objetos
do tipo valor. No entanto, há uma pequena
condição aí. Ela se aplica a objetos
do tipo valor se
eles estiverem marcados como anuláveis Agora, falaremos
sobre anulável mais tarde. Não se preocupe com isso. Mas, para o propósito deste exemplo, null se aplica ao declarar objetos do tipo de
referência porque precisamos de um ponteiro, mas não
temos O valor inicial é
nulo, o que não é nada. Vamos dar uma olhada em alguns exemplos agora trabalhando
com a palavra-chave null Então, o que vou fazer é gerar uma propriedade, ou talvez tentar usar um desses métodos aqui
desses tipos de
referência. Vou apenas
escrever na janela do console, vou gerar uma
propriedade aleatória dessa lista. Por exemplo, vou dizer contagem
de pontos da lista. Vamos dar uma olhada no
que está acontecendo aqui. Agora eu tenho uma linha vermelha. Você pode ver o uso da lista de variáveis
locais não atribuídas. Nem está me deixando usar esse objeto porque
ele não está atribuído Mas espere, achei que
era nulo por padrão. Bem, nulo por padrão
acontece em tempo de execução,
não em tempo de compilação Esse é o tempo de compilação. Na verdade, estamos fazendo o
desenvolvimento aqui. Esse é o tempo de compilação. Nem está me deixando
compilar o aplicativo. O que temos que fazer
em tempo de compilação é apenas inicializar
isso Dessa forma, o erro
desaparece e podemos realmente
executar o programa. Mas o compilador está nos
ajudando aqui. Está dizendo, olha, isso é nulo. Você realmente não deveria usar
propriedades em um valor nulo,
caso contrário, isso
cairá Mas, ao enganá-lo, fizemos com que esse erro desaparecesse. Então, posso mostrar um exemplo de uso de algo
que é nulo Agora, a lista é nula. Estou tentando acessar uma
propriedade aqui chamada count na lista de objetos nulos Vamos ver o que acontece. Agora, um erro apareceu aqui e diz referência nula, referência objeto de
exceção, não definida como uma instância
de um Agora você verá muito esse
erro em
seus empreendimentos no futuro com a C Sharp É apenas uma dessas coisas. Mas, basicamente, você pode ver aqui nosso tipo de referência é nulo Se algo for nulo, não
podemos usar métodos nele Não podemos usar propriedades
nela porque ela não tem valor, não
tem memória
armazenada na pilha É praticamente apenas
um ponteiro vazio de um objeto. Não há
nada lá. É nulo, não podemos usá-lo. Tudo o que precisamos fazer é instanciá-lo e realmente
dar algo a ele Agora, se eu executar o aplicativo, você pode ver aqui que o erro
desapareceu porque
instanciamos o objeto
e ele não é mais nulo Isso é algo com que se deve ter muito cuidado ao
trabalhar com Eu acho que você entendeu
o ponto de nulo. Agora, por exemplo,
se eu tiver uma string, vamos excluir algumas
dessas coisas aqui. Se eu tiver uma string,
vou chamá-la de test. Vou
inicializá-lo em uma string vazia. E o que estou tentando
dizer é que uma string vazia, por exemplo, não é
o mesmo que null Já falamos sobre nulo. Sabemos que é uma referência nula. O que muitas pessoas fazem, elas se confundem um pouco com nulo Eles acham que é apenas
um valor vazio, como uma string vazia. Isso não é verdade de jeito nenhum. E eu posso provar isso para você se eu apenas configurar um bolen, por exemplo E eu tenho uma condição
que compara essa string vazia
aqui com o valor nulo, e você verá
que é falsa O que estou dizendo aqui é que
se test for igual a null, se uma string vazia
for igual a null, posso até escrevê-la assim, nem
preciso de uma variável Em seguida, imprima o valor
verdadeiro se for o mesmo,
caso contrário, falso se não for. Então você pode ver que null não
é uma string vazia. Um erro de principiante,
talvez pensando assim. Mas pensei que tinha
mencionado que null não é o mesmo
que uma string vazia Null é simplesmente uma referência nula. Uma string vazia é exatamente
isso, uma string vazia. Espero que isso
esclareça o que é
nulo como ele pode ser usado
e por que No nosso dia a dia fazendo desenvolvimento
de software.
Obrigado por assistir.
71. 17-2. Tipos de valores nuláveis: Neste tutorial,
falaremos sobre tipos anuláveis O que são tipos anuláveis? Em nosso último tutorial, eu recomendo fortemente que
você assista isso. Quando falamos sobre
a palavra-chave null, mencionei brevemente
que
objetos do tipo de referência , como listas,
objetos e coisas, se você não os inicializar,
eles obtêm o
valor padrão de null,
que é um ponteiro nulo que é um No entanto, para tipos de valor, eles tendem a ter o valor
padrão de zero. Mas se tentarmos usar
a palavra-chave null com
um objeto de tipo de valor, isso não
funcionará porque não
podemos realmente dar a ela
um ponteiro de referência Por ser um tipo de valor, ele armazena um valor como
3.456, por exemplo, ou verdadeiro Na verdade, ele armazena o valor de um tipo de valor na área da
pilha da memória Então, o que é um tipo anulável? Bem, um tipo de valor anulável como
esse é
uma instância em que um tipo de valor
pode realmente Então, por que queremos fazer
isso e como fazemos isso? Então, por exemplo,
quando tentei definir isso como nulo antes, não
funcionou No entanto, se eu adicionar um ponto de interrogação após o tipo de
dados aqui, você pode ver que o erro
desapareceu e foi resolvido. O que está acontecendo aqui? Bem, para transformar um
objeto do tipo valor, como um, em uma bola, um personagem, tipos simples. Se adicionarmos um ponto de interrogação
no final aqui, isso
representará um tipo de valor
anulável Agora, essa variável é um tipo de valor
anulável. Agora, ele pode assumir um valor ou a palavra-chave null Por que você pode querer fazer isso? Qual é o objetivo disso? Bem, imagine que você tenha, por exemplo, um registro de turma. Você tem um pouco de
software e ele marca a frequência dos alunos
em sua sala de aula Agora, digamos que tenha um banco de dados anexado
dentro do banco
de dados, você tem todos os nomes dos alunos, nome, sobrenome, todas essas coisas boas. E então você tem um booleano
no banco de dados e o valor
no banco de dados seria chamado algo como está presente Agora, se as crianças
ainda não chegaram
à sala de aula
, não sabemos se
elas estão presentes. Não podemos realmente dizer a verdade
porque não sabemos. Na verdade, não
fizemos o registro, não
verificamos quais alunos
compareceram à aula. Mas se eu armazenar o valor das quedas no
banco de dados por padrão
, posso simplesmente alterá-lo para verdadeiro se elas estiverem
presentes na classe. Bem, quero dizer, isso quer dizer que
eles não estão presentes,
mas na verdade ainda não tenho
certeza porque eles não chegaram
à sala de aula Em casos como esse,
você pode querer um terceiro valor para um
Bolen, por exemplo Você pode querer nulo
se ainda não soubermos. Se o aluno chegar e
estiver aqui, podemos dizer que é verdade. Mas se o aluno estiver ausente, talvez esteja doente,
podemos dizer falso Então, em casos como esse, podemos querer um terceiro valor. E uma palavra-chave como null representa algo
como um valor padrão, como não saber o resultado
ainda, ou algo parecido Então, se não tivermos certeza
se eles já estão aqui, podemos usar algo como um tipo de dados anulável aqui,
que é o Bullen E não sabemos se
eles estão na classe, então podemos simplesmente
inicializá-la como null E no banco de dados para isso talvez esse campo esteja vazio. Ou pode até dizer
nulo. Isso não importa. Mas a questão é que,
quando as crianças começarem a chegar à sala de aula
, podemos
definir isso como verdadeiro e falso. E esse é o tipo de
princípio por trás disso. Isso lhe dá uma terceira
opção, por exemplo. E, novamente, isso é
semelhante com números inteiros. Podemos defini-los como
nulos se não tivermos um valor específico para qualquer
número que desejemos modelar Então, qualquer coisa assim, há
vários motivos pelos quais
podemos querer um tipo de valor
anulável ao trabalhar com tipos de valores
anuláveis basta adicionar um pequeno ponto de
interrogação há
vários motivos pelos quais
podemos querer um tipo de valor
anulável
ao trabalhar com tipos de valores
anuláveis,
basta adicionar um pequeno ponto de
interrogação
após o tipo aqui. Ele oferece mais algumas
opções. E por que isso? Bem, vamos pegar
essa variável aqui, por exemplo. Isso é anulável Agora, se eu colocar um ponto depois, tenho acesso a
algumas propriedades aqui. Se eu remover esse ponto de interrogação, para ter um bolen simples, você pode ver que essas
propriedades
desapareceram . O que
está acontecendo aqui? Por que eu tenho essas propriedades
extras para um tipo de valor anulável Isso porque,
nos bastidores, é uma estrutura muito
semelhante a uma classe. Em vez de ter um
boolene simples como antes, onde podemos simplesmente ter um
boolene e Podemos enviá-lo para a janela, podemos passá-lo para um método,
todas essas coisas boas. Nós temos uma estrutura.
Pense nisso como uma aula. O que a classe
faz nesse caso é apenas expor duas propriedades Um é o valor real do
nosso tipo de dados anuláveis. Agora, o valor de parada de
atendimento
seria o mesmo que ter um tipo de dados
não anulável e, usando isso, podemos usar
a propriedade value aqui
para obter o valor subjacente
que seria Por exemplo, ele
também tem outra coisa chamada tem valor. Agora podemos realmente usar essa propriedade booleana aqui para
descobrir se ela tem um valor O que você normalmente
faria para algo
assim é ter uma
declaração if e dizer, ok, ela tem um valor? Ok, ele tem um valor,
portanto, podemos acessar o valor e imprimi-lo
no console, por exemplo. Então, algo assim, fazer as coisas dessa maneira e
ter essas propriedades disponíveis para nós
evita coisas como exceções de referência
nula ou até mesmo a verificação de nulos,
por É por isso que tem essas
propriedades disponíveis. Queremos verificar se ele tem um valor e, em seguida, podemos
utilizar o valor. É por isso que eles
são muito úteis. E é por isso que, quando você
define um tipo de dados anulável,
ele expõe essas propriedades extras
para você usar,
porque fornece essa
terceira opção que é nula ele expõe essas propriedades extras
para você usar, porque fornece essa
terceira opção que é Se você estivesse
se perguntando se tem um objeto do tipo valor anulável
e não o inicializa
, o
valor padrão seria nulo, não Como é anulável,
o valor padrão é nulo Esse é um exemplo de tipos
anuláveis na loja C.
72. 17-3. Os operadores de coalescência nula: Operadores de coalescência nula em
C nítido soam super complicados.
Mas o que eles são? Bem, um deles se parece com
isso, dois pontos de interrogação, outro parece assim, dois pontos de interrogação
seguidos por n igual Mas quais são esses
caracteres aleatórios que você está digitando? Ouço você perguntar:
Permita-me explicar operadores de coalescência
nula
permitem que você trabalhe com tipos de
referência como esta
lista aqui O que pode ser nulo,
mas pode não ser nulo. Além disso,
tipos de valores anuláveis que podem ser nulos ou podem ser Vamos dar uma
olhada em um exemplo aqui. Então, aqui estou criando uma
lista de strings aqui, e isso é chamado de lista de
compras E isso vai conter todos os itens da
minha lista de compras. Então eu vou fazer compras em seguida, eu tenho esse tipo aqui, que é um número inteiro e esse
é o custo das minhas compras Agora, vou
padronizar isso como nulo porque ainda não
fiz compras Agora posso encontrar
tempo para fazer compras, mas talvez não encontre
tempo para fazer compras. Se eu for às compras, o custo representará
o valor da minha loja. No entanto, se eu não
me dar ao trabalho de fazer compras
, ele
manterá o valor nulo porque eu ainda não Portanto,
não há custo para minha loja. Mais tarde, no aplicativo, se eu fui às compras ou
não, isso realmente não importa. Mas quero enviar
uma mensagem dizendo que meu custo de compra era então
o valor da loja. Em um mundo normal com um tipo de dados
simples como esse, talvez
você o inicialize
com zero e depois, ou ele possa ter outro valor Por exemplo, eu executo o programa, ele me diz o custo da minha loja. No entanto, se eu criar
um tipo de valor anulável como esse e
inicializá-lo como nulo, normalmente uso
a propriedade value para
acessar o valor No entanto, se isso
não tiver um valor, talvez eu não tenha encontrado
tempo para fazer compras,
então, se eu executar o programa, tenho um erro aqui. Já falamos sobre isso antes. O objeto anulável
deve ter um valor. Você pode ver que estou acessando
essa propriedade de valor, mas na verdade não estou verificando se ela tem um valor. O que eu normalmente faço
nesse caso é apenas ter
uma instrução if aqui e verificar a propriedade has value desse
tipo anulável Agora estou dizendo que se
eu tenho um valor
, quero gerar o valor. Parece que isso deve funcionar. Agora parece que
não tenho nada. Mas não está travando Pelo menos parece muito bom. Mas você pode ver que toda vez
que tento acessar esse valor, estou tendo que fazer
uma condição aqui. Estou tendo que fazer uma
declaração if e realmente verificar se há um valor lá antes de
finalmente poder usá-lo. Se eu quiser
enviá-lo para a janela, se eu quiser passar
o valor para um método, ou para um método de uma classe
ou para outro lugar. Então, basicamente, eu tenho
que verificá-lo antes de realmente usá-lo. Mas e se eu dissesse que
há uma maneira combinar essas
duas coisas em uma? Agora é aqui
que eu introduzo um dos operadores de coalescência nula,
que são os dois pontos de interrogação Vamos dar uma olhada em como
eu posso simplificar isso aqui. Vou remover a verificação de valor
tem lá
e, em seguida, vou
remover o valor do ponto aqui. Em seguida, vou
apresentar um dos operadores de coalescência nula,
que são dois pontos de que Vou usar
zero como exemplo aqui e vou colocar
parênteses ao redor tudo para que
não gere um erro O que você acha
que isso vai fazer agora? Ou talvez você não saiba, porque eu não
expliquei o suficiente. Vamos executar o software e
realmente ver o que acontece. Eu executo o software agora, ele diz que o
custo de compra foi zero. Você pode ver, bem,
o custo é nulo, mas por alguma razão, ele está produzindo esse zero aqui No entanto, se eu alterar o custo de 4567 e executar o aplicativo, agora ele está realmente
gerando 4567 O que está acontecendo aqui? Bem, esse
operador de coalescência nula basicamente diz que, se for nulo, então não há valor, calcule o que está no lado direito desses dois
pontos de No entanto, se isso tiver um valor, qualquer coisa que não seja nula Por exemplo, avalie esse lado dos pontos de interrogação e
ignore esse lado completamente. Nem mesmo avalie esse lado. Então é assim que um dos operadores sem
coalescência funciona. E você pode ver que não
precisamos dessa condição lá. Está embrulhado em uma pequena
declaração organizada de dois caracteres aqui, que são dois pontos de interrogação Então, deixe-me ilustrar
isso um pouco melhor, caso você não tenha
entendido da primeira vez Então, deixe-me criar um método aqui. E eu vou
chamá-lo de obter custo padrão. Então, o que esse método
vai fazer é retornar
um valor padrão para o custo se nenhum
valor for especificado. Só vai retornar
zero com esse operador aqui. Estou apenas anexando uma string ao resultado de qualquer
avaliação. Ele será
avaliado para o lado esquerdo, que é o custo, ou para o lado
direito, que é zero. No entanto, não precisa ser
apenas um zero ou uma variável simples. Pode ser o resultado de um método
inteiro, por exemplo. Agora, se isso for
nulo, o que é, ele avaliará o
que estiver desse lado Pode ser um tipo simples, pode ser um método. Você vê que há
muitas opções aqui. Isso se chama avaliar. Se eu executar o aplicativo, agora ele está produzindo zero E só para provar
que ele está realmente executando o método,
vamos executá-lo. Novamente, você pode ver que
o lado direito está sendo avaliado porque
o lado esquerdo é nulo Esse é o poder dos
dois pontos de interrogação aqui, também
conhecido como operador de
coalescência nula Aqui está a sintaxe aqui, os dois pontos de interrogação aqui O uso é
que você tem um tipo anulável,
seja um tipo de dados
simples anulável
ou até mesmo
uma lista, por exemplo,
porque os tipos de referência podem ser
nulos, como você pode ver lá E então, no lado direito, temos algo para avaliar
se o tipo anulável,
que está no lado
esquerdo, é nulo que está no lado
esquerdo, Já falamos sobre tudo isso, mas essa é uma boa visualização se você não a
entendeu da primeira vez Este é um dos operadores de
coalescência nula aqui. Quero apresentar mais um operador de coalescência
nula agora que se parece com
isso São dois pontos de interrogação
seguidos por um sinal de igual. E é bem parecido
com o último exemplo, mas também tem a ver com a
atribuição Então, o que tudo isso significa? Bem, vamos dar uma
olhada neste exemplo aqui. Eu tenho uma lista de números inteiros aqui. E essa lista totalizará
todas essas despesas. Então, todas as contas
que paguei este mês, todo o custo das
compras que fiz este mês e todo o custo de gastar meu dinheiro
em coisas inúteis Então, tudo isso
será adicionado a esses totais aqui como itens de linha
separados É uma lista, então eu quero
adicionar cada um desses
totais a essa lista Então, podemos fazer isso com bastante facilidade. Podemos usar o método de anúncio que adiciona isso à lista
e, em seguida, podemos simplesmente colocar os
totais aqui, mas lembre-se que é um tipo anulável, então precisamos usar
o valor aqui, o
que parece bom, mas, espere, não Agora temos que verificar se
ele tem um valor. Temos que fazer uso
dessa propriedade. Ah, sim. Mas isso tem que estar em uma condição aqui para
garantir que tenha um valor. Por exemplo, então
podemos adicionar o valor. Isso deve funcionar, mas lembre-se de quando eu disse que operadores de
coalescência nula são atalhos Não precisamos de tudo isso
de jeito nenhum. Em casos como esse, podemos usar o outro operador de coalescência
nula,
que são os dois pontos de interrogação e o O que isso faz e
como funciona? Digamos, por exemplo, eles sejam definidos como nulos aqui, por qualquer motivo
durante nosso software, não
estamos realmente fornecendo nenhum valor a eles, eles permanecem nulos Bem, talvez um
deles tenha um valor, mas por alguma razão, alguns
deles ainda podem ser nulos Chegamos a
adicioná-los à lista, só
queremos adicionar os
valores onde eles não são nulos porque não podemos adicionar coisas
nulas a uma Mesmo se tentarmos,
não vai virar letras. O que eu quero fazer é se eles
tiverem um valor como esse, por exemplo, então eu
quero adicioná-lo à lista. Este tem um valor de 4567, então eu quero adicioná-lo No entanto, se forem nulos, quero adicionar zero em vez de algum
outro valor padrão Basicamente, não quero
adicionar nulo porque não consigo. Na verdade, existe uma
maneira rápida de fazer isso. O que posso fazer é usar esse
operador de coalescência nula seguido por esse
operador de coalescência nula seguido por um zero.
Vamos redefinir isso. O que isso faz, se essa
variável aqui for nula, então ele atribuirá
zero a essa variável adicionará isso à lista Se for, se o lado
esquerdo desse operador for
avaliado como nulo, o que acontece porque é nulo, essa variável receberá o valor do que
estiver no lado Lembre-se, isso pode
ser um valor simples, pode ser um método
que tem um retorno. Basicamente, pode ser qualquer
expressão que possa ser avaliada. Então, vamos colocar zero aqui. O que podemos fazer, podemos fazer
isso por todos eles. Queremos adicionar todo o nosso custo
das contas, por exemplo. Queremos, é claro,
adicionar o custo de gastar nosso
dinheiro em coisas inúteis Agora veja o que acontece se eu executar o programa e adicionar
um ponto de interrupção aqui. Agora eu vou até meus totais
aqui e os expando. Você pode ver que a lista
tem todos os zeros aqui, que é o valor padrão,
como você pode ver aqui Além disso, você pode ver isso refletido nas próprias
variáveis, elas agora têm o valor zero. Para ilustrar esse ponto, vou mudar
um para algo assim Vou executar o
software mais uma vez. Se eu for até a
janela local aqui embaixo, você pode ver que essa variável realmente
manteve esse Foi atribuído a
ele, agora tem um novo valor, 4567, e agora isso também
se reflete na lista Esse operador de coalescência nula a pontos de interrogação é igual a igual Se o lado esquerdo for nulo, o lado esquerdo
receberá o valor
no lado direito É assim que esse operador
funciona. Assim como antes. Vou escrever um código de comentários, para que você possa ver isso
ilustrado aqui Se o tipo anulável for
avaliado como nulo,
por exemplo, o custo da compra será nulo e será nulo nesse ponto Em seguida, avalie o que está
no lado direito
desse operador e
atribua-o ao tipo anulável Obviamente, se o tipo
anulável for nulo, ele Esses são dois
operadores de coalescência nula em C Sharp, como eles funcionam e também
por que Não é nada que você já
não possa fazer com uma condição para
verificar o valor, mas é um bom atalho para
minimizar o código e também o tempo de
desenvolvimento.
73. 18-1. Parâmetros nomeados e opcionais: Agora vou apresentar
algumas dicas que você pode fazer ao chamar
métodos em C Sharp. Isso tem a ver com
a passagem dos parâmetros. Vou falar
sobre o que é chamado de parâmetros
nomeados e também parâmetros
opcionais em C sharp. Vamos dar uma olhada nesse exemplo aqui. Realmente não faz muita coisa. Eu tenho um método de amostra, ele usa vários parâmetros, todos de tipos diferentes. Temos um objeto de videogame, alguns números, uma corda e também um booling Dentro do método,
estamos apenas produzindo a propriedade title
desse objeto do jogo, que especificamos aqui
no construtor Em seguida, somaremos
os
dois números e
exibiremos o resultado. Finalmente, temos uma condição. Se o valor dessa variável de
booling for verdadeiro, enviaremos
a mensagem aqui É um pouco complicado
de tarefas. Realmente não tem nenhum
propósito no mundo real. É apenas para o
propósito deste exemplo. Quando chamamos o método, você pode ver que estamos
configurando um novo objeto aqui. E então estamos
chamando o método que
passa esse objeto e também o restante
dos parâmetros quando eu executo o programa Você pode ver que ele
praticamente faz exatamente o que diz até agora ao
chamar métodos. Estamos chamando
esses métodos com os parâmetros na ordem em
que aparecem. O objetivo do jogo é Primeiro,
passamos primeiro no jogo, seguido pelo número
um. Número um. Número dois, você pode ver
todos na ordem em que foram especificados usando algo
chamado parâmetros nomeados. Não precisamos especificar
os parâmetros em ordem. Vamos dar uma olhada em um
exemplo disso agora. Digamos que eu queira mudar a posição desses
dois parâmetros aqui,
Olá, e também
o booleano verdadeiro Agora eu quero especificar
o bolen primeiro. O que fazemos é pegar o
nome do parâmetro aqui e prefixá-lo com
dois pontos, sem mais nem menos Vamos
especificar isso primeiro, agora vamos
especificar a mensagem. Depois, fazemos
exatamente a mesma coisa. Pegamos o parâmetro, adicionamos os dois pontos
e depois seu valor Agora eu troquei a ordem
desses dois parâmetros. Para fazer isso, preciso especificar
o nome
do parâmetro apenas para dizer
ao sistema qual deles
pertence a qual. Nós apenas consertamos isso
com dois pontos aqui. Quando executo o aplicativo, agora temos exatamente
o mesmo resultado. Esses são parâmetros nomeados. Você pode ver que alteramos apenas a ordem dos dois
últimos parâmetros. Os três primeiros permanecem
na mesma ordem. Que não precisamos
dar um nome eles
porque estão
na mesma ordem. No entanto, se eu quiser nomear meu primeiro parâmetro e colocá-lo em algum lugar
totalmente diferente
, terei que
nomear cada parâmetro. Caso contrário, receberemos
um erro aqui. Nesse caso, não
preciso nomear os
três primeiros porque eles estão exatamente
na mesma ordem
desde o início. Mas se eu mover esse jogo até o
final, por exemplo, e der a ele um nome
parecido com este
, vou
receber esse erro. E isso é porque eu preciso
prefixar todo o
resto com o nome Agora você pode ver que
o erro foi resolvido porque o jogo
foi movido para fora da posição. E essa foi a primeira. Portanto,
não há nenhum pedido. Então, todos precisarão de um nome. Nesse caso, esse é o
poder dos parâmetros nomeados. Mas por que isso é útil? Bem, você poderia argumentar que
melhora a legibilidade. Você poderia dizer que, pela
própria chamada,
supondo que esse método esteja
bloqueado em uma classe
ou arquivo diferente, você só tem essa
visibilidade do seu lado, você pode ver claramente que a
aparência número um tem o valor
desse número dois, pois isso fornece um pouco mais de informações
sobre a chamada No entanto, ele cria um pouco mais de código em
seu aplicativo. Outro motivo,
talvez um desenvolvedor esteja trabalhando nesse método. Aqui, o método
ainda não está concluído. Eles têm talvez cinco
parâmetros, por exemplo, mas talvez em
breve adicionem mais alguns. Seu trabalho como testador
é testar o método. Você está testando o método
com esses cinco parâmetros, mas não sabe
se o desenvolvedor adicionará
mais deles posteriormente. Então, o que você pode fazer é usar parâmetros
nomeados aqui para realizar qualquer teste
que desejar fazer. Quando o desenvolvedor
adiciona mais dois em qualquer ordem, isso realmente não importa Então você sabe que seus
parâmetros não serão passados
para
outros por acidente. Por exemplo, se
o desenvolvedor
adicionar mais dois parâmetros
inteiros
, saberemos que o número um e o número dois serão
5,3 nesse Se o desenvolvedor adicionar
3.4, por exemplo, não
colocaremos acidentalmente esses números nesses slots Em casos como esse, é muito útil quando você
não
passa acidentalmente parâmetros
do mesmo tipo para parâmetros
diferentes Você está literalmente dizendo, ok, esse parâmetro chamado assim
receberá esse valor. Isso é muito útil. Não são só métodos. Você também pode fazer isso em construtores e em algumas outras
coisas Se eu for para essa classe de
videogame em que
especificamos esse parâmetro
para o construtor, você pode ver que o construtor
usa apenas um argumento,
que é o Assim como ao chamar
métodos, por exemplo, posso prefixar isso com título e ele vai
compilar perfeitamente Não estamos limitados
a chamadas de método com parâmetros nomeados
como esses. Também podemos usá-los em construtores e outras
coisas desse tipo Então, vamos falar sobre parâmetros
opcionais agora.
O que isso significa? Se você tiver um parâmetro
opcional, poderá atribuir ao parâmetro um valor padrão se nenhum
parâmetro for especificado. Por exemplo, vamos ver
essa mensagem de exibição Bolen. Aqui, estamos transmitindo
o valor de true. Digamos que não
precisamos passar um valor. Mas podemos, se quisermos, o que podemos fazer aqui,
podemos dizer, ok, se esse parâmetro não for passado para essa mensagem de
exibição do método, então vamos defini-lo como
um valor padrão verdadeiro. Se o parâmetro for
omitido, ele não estará lá. Então, quando esse método
for chamado, ele apenas
inicializará isso como verdadeiro Se isso for verdade aqui, ele
exibirá a mensagem. Podemos dar uma olhada nisso agora para ver se funciona. Você pode ver as
mensagens sendo enviadas. Da mesma forma, se eu alterar esse valor
padrão para
false, não
veremos essa mensagem de jeito nenhum. Não vai dizer olá,
o que não acontece. Ao especificar
parâmetros opcionais em C Sharp, eles precisam seguir
os parâmetros necessários Por exemplo, se eu tornar a mensagem
um parâmetro opcional, eu apenas a inicializo com um valor padrão de uma string
vazia como essa Você pode ver que tenho
um pequeno erro aqui quando tento
compilar o aplicativo Por exemplo, se eu
definir isso como verdadeiro, você verá que há um erro. Se viermos até aqui, podemos ver esse erro aqui. Os parâmetros opcionais devem aparecer depois de todos os parâmetros obrigatórios. Todos os parâmetros opcionais
devem vir no final. Aqui você pode ter
quantos quiser. Por exemplo, podemos tornar a
mensagem um valor padrão como uma string vazia e também exibir a mensagem como um valor
padrão verdadeiro. Então, podemos realmente
remover esses valores. Podemos até dizer, ok, vamos inicializar
esses dois números para zero se eles
não forem especificados Então você pode ver lá, então não
precisamos deles, por exemplo. Mas isso realmente depende do
seu propósito e do que você pretende alcançar se
executarmos o aplicativo Agora podemos ver a soma dos
dois números, um zero porque os estamos
inicializando com zero, porque não estamos
especificando os parâmetros Praticamente a única coisa que estamos fazendo é mostrar o título
do videogame aqui quando, na verdade, chamamos
esse método aqui Se olharmos a lista de
parâmetros agora você pode ver que há
mais informações extras aqui. Requer um videogame porque esse é um parâmetro
obrigatório. No entanto, você pode ver que os parâmetros
opcionais agora têm esses
colchetes ao redor Também fornece o valor
padrão 00, uma string vazia e também verdadeira. Ele também fornece alguns
comentários sobre o que é necessário ao tentar
chamar esse método. Você pode ver como esses parâmetros
opcionais são representados
ao tentar chamar seus métodos. Novamente, você não está
limitado às chamadas de método. Com isso, assim como antes, você pode usá-los em
construtores e, novamente, outras coisas Delega índices. Se eu definir meu parâmetro para o construtor como
um valor padrão, como uma string vazia
, não precisarei mais desse
valor porque ele é opcional Quando executamos o aplicativo, obteremos apenas uma string vazia. Você pode ver que não
há título de jogo porque o valor padrão
é uma string vazia. Esse é o poder dos parâmetros
nomeados e também dos
parâmetros opcionais em C sharp. Isso abre as coisas para um
novo reino de possibilidades. Espero que este tutorial tenha ajudado
você e tenha gostado de programar.
74. 18-2. A palavra-chave: Vou falar
sobre a palavra-chave out em C sharp e por que ela é útil. Considere este
exemplo aqui. Esse método, o que ele
faz, tem quatro parâmetros. O que eu quero fazer
é somar esses dois juntos e depois subtrair
esses dois juntos Você pode ver que estou fazendo isso aqui. Estou obtendo o resultado
da adição
nessa variável e o resultado da subtração
nessa Mas como faço para devolver
os dois? Quando falamos sobre
retornos em métodos, podemos retornar um tipo aqui, mas só podemos
retornar um valor. Como eu faria talvez 235 coisas diferentes de
um método? Isso é possível? Bem, resumindo, sim, podemos usar a palavra-chave
out para fazer isso. E você vê a palavra-chave out
usada em muitos casos. Por exemplo, um método pode realizar algumas operações e
retornar um resultado. Mas também queremos retornar
talvez se o método foi bem-sucedido ou talvez um registro de quaisquer erros que
ocorreram ao longo do caminho. Não precisamos apenas do
resultado do método, mas talvez precisemos de
mais informações sobre como ele lidou com as coisas, você sabe, quais erros ocorreram ou praticamente
qualquer coisa parecida Então, vamos dar uma olhada
na palavra-chave out e
como ela é útil. Agora, a palavra-chave out
sobre como ela se comporta é muito semelhante
à palavra-chave ref Se você não assistiu ao
meu tutorial sobre a palavra-chave ref ou a passagem
de tipos por referência a métodos
, eu recomendo fortemente que
você dê uma olhada. O que vou fazer aqui definir duas variáveis
locais aqui,
resultado, adição e subtração de
resultados, e as inicializei com
zero No momento, estou
enviando-os para a janela. Dentro do método, estou fazendo praticamente a
mesma coisa, mas quero que esses
resultados
reflitam nessas variáveis para reflitam nessas variáveis que eu possa
enviá-los para a janela, porque no momento não consigo
extrair esses dois valores desse método. Como eu faço isso? Vamos dar uma olhada no uso da palavra-chave out, o que posso fazer na lista de
parâmetros aqui. Para esse método, posso adicionar um parâmetro extra
com a palavra-chave out. O que
eu quero fazer é retornar esses
dois valores
do método. Vou ter duas variáveis de
saída aqui. O primeiro será
o resultado da adição. O segundo será
o resultado da subtração Agora, como eles estão
sendo passados para o método com seus
próprios tipos e nomes, não
posso dar a eles um tipo totalmente
novo. Eu os removo. É
basicamente assim que funciona. Agora você pode ver que um erro
apareceu aqui. E quando eu passo o mouse sobre isso
dizendo que não há
nenhum argumento que
corresponda ao parâmetro necessário, basicamente preciso especificar
dois parâmetros extras O número de parâmetros
corresponde à definição. Aqui, eu preciso de mais dois. Quando você tem a palavra-chave out na declaração do método aqui, você também precisa especificar
a palavra-chave out ao
chamar o método. Isso é o que eu
vou fazer aqui. Se você assistiu ao meu vídeo
sobre a palavra-chave ref e a
transmissão de tipos de valor e tipos de
referência para métodos, você saberá que quando
passamos algo para um
método por referência, algo para um
método por referência, podemos modificar os valores
dentro do método e estamos referenciando a área da memória onde
essas variáveis estão. É isso que a palavra-chave
out faz. Mas há uma
diferença sutil entre
a palavra-chave ref e
a palavra-chave out aqui. Ou seja, as variáveis
não precisam ser inicializadas antes de
passar uma variável com a palavra-chave out O que eu quero dizer com isso? Bem, vamos realmente ver se
esse exemplo funciona. Primeiro, antes
de nos anteciparmos, estou passando 20 valores
como parâmetros de palavra-chave. Eles estão entrando no método
e, na verdade,
definindo os valores aqui. Vamos dar uma olhada. Você pode ver que obtemos o resultado esperado. Dois mais dois é 4,6
menos quatro é dois. Isso funciona. E, na verdade,
estamos obtendo os
dois resultados
retornados do método. Mas não está realmente
retornando do método, está apenas modificando
esses dois objetos de valor à medida que são passados por
referência para esse método e, em
seguida, estamos apenas
produzindo os resultados Eu disse antes que havia uma diferença
sutil entre
a palavra-chave out e
também a palavra-chave f. E isso é que, ao
usar a palavra-chave out, as variáveis passadas
não precisam ser inicializadas, que significa que elas
não precisam de um valor Ainda funcionará
quando eu executar o software. Agora você pode ver
que eles têm valores. E isso porque
quando as coisas são passadas para um método aqui, precisamos dar a elas um valor. Se não fizermos isso, estamos passando uma variável. Aqui você pode ver que há um
erro que diz que o
anúncio resultante deve ser atribuído
antes que o método seja concluído Então, precisamos realmente fazer algo com esses
parâmetros externos aqui. Precisamos fazer
algo com eles, dar a eles um valor,
inicializá-los, fazer algo que seja a diferença sutil
entre out e ref Mas, geralmente, a
palavra-chave out permite que você, de certa forma, retorne mais de um
item de um método, e esse é seu principal poder. Na verdade, outra coisa, não
precisamos definir nossas
variáveis aqui. Na verdade, podemos
defini-los todos em uma linha. Se eu remover essas
variáveis completamente entre a palavra-chave out e
a variável, basta digitar
int, por exemplo,
para o tipo de dados. Agora, na verdade, estamos definindo nossas variáveis em uma
linha de código aqui. E você pode ver que
parece muita ideia. Então, nós os estamos definindo aqui, depois
os estamos transmitindo tudo em um. E então está fazendo alguma coisa, expulsando-os de volta. E então estamos
produzindo os resultados. Então você pode ver que obtemos os
mesmos resultados aqui. Então esse é o poder da palavra-chave
out em C sharp.
75. 18-3. A palavra-chave na: Eu vou falar sobre
a palavra-chave em C Sharp. Agora, eu tenho um exemplo muito
simples. Aqui estou chamando um método que
soma dois números. Quando o método é chamado, estamos colocando o resultado
deles em uma variável e produzindo o resultado
adicionando dois mais dois, obtemos a saída Como a palavra-chave
entra nisso? Bem, quando usamos a
palavra-chave em um método aqui, podemos especificar isso antes de
qualquer parâmetro que desejarmos. Por exemplo, número um, o que a palavra-chave faz nos impede de
modificar esse valor Então, se tentarmos
definir um valor como esse, por exemplo, você verá que o
software nem mesmo compilará Quando destacamos isso
e passamos o mouse sobre ele. Ele diz que não é possível atribuir variável int
porque ela é somente para leitura. Na verdade, isso nos impede de fazer qualquer coisa com
essa variável. Aqui, novamente, podemos colocar isso em qualquer número de
parâmetros que desejarmos. Esses são
tipos de valores simples, números inteiros simples. Vamos dar uma olhada em como
isso funciona com objetos. Por exemplo, você pode ver aqui que eu tenho um exemplo
com um objeto aqui, como um videogame, por exemplo, estou definindo o título do
jogo por meio do construtor
para o Minecraft e apenas
exibindo o título do jogo Mas se eu tentar
modificar esse objeto de
alguma forma ao especificar
a palavra-chave in
, isso gerará um erro
semelhante somente de leitura Você pode ver aqui que estou apagando o título
configurando-o como uma string vazia Mas está dizendo que não pode ser
atribuído, é somente para leitura. Da mesma forma, se eu tentar criar uma nova instância completamente a partir
disso
, terei exatamente
o mesmo erro. Esse é o poder
da palavra-chave em C sharp. Isso evita que coisas como
métodos
modifiquem acidentalmente qualquer um dos parâmetros que você deseja transmitir Se você sabe que esse método não
é
responsável por modificar seus
parâmetros de forma alguma, considere
especificá-los com a palavra-chave in para proteger seus dados e evitar que
métodos alterem seus dados e aconteçam coisas
inesperadas, o
que pode acontecer bastante
, acredite Mas a beleza
da palavra-chave é que sim, você pode passar uma constante ou uma variável somente para
leitura
aqui, por exemplo. Mas talvez seus objetos não sejam somente de
leitura ou constantes, mas você só queira
que eles sejam
lidos temporariamente apenas durante o
período do método. Esse é o objetivo
da palavra Q na loja C.
76. 18-4. Palavra-chave params: A palavra-chave Perms em C sharp. É exatamente assim e
é a abreviação de parâmetros. Mas o que isso significa
e o que isso faz? Vamos dar uma
olhada nesse exemplo. Aqui eu tenho um método que soma alguns
números inteiros simples Ele usa quatro parâmetros
, soma todos eles e gera o resultado O método os extrai
do que quer que o esteja chamando. Estamos adicionando 224,5. Vamos
gerar o resultado. Aí está lá. Por exemplo, se eu quiser somar dois
números, talvez eu queira somar
três números. Ou talvez 17 números juntos. Mas eu quero o mesmo, só
quero um método. Eu quero o mesmo método e um método para somar todos
esses números. Como faço para conseguir isso? Bem, talvez eu pudesse
criar um objeto personalizado, por exemplo, alimentar
todos os números. Ou talvez crie uma lista e adicione todos os números à lista. Então eu posso passar a
lista para esse método. Essencialmente, é isso que
a palavra-chave prams faz. Nesse caso, quando eu
uso a palavra-chave Prams, eu digito Prams aqui na assinatura
do método Aqui está um parâmetro em si. Em seguida, coloquei o tipo de dados. O tipo de dados pode ser
praticamente qualquer coisa nos bastidores. Ele usa o tipo de dados do objeto, qual todos os
tipos de dados derivam, de qualquer forma Mas estamos usando números inteiros. Podemos usar
objetos personalizados, se quisermos. Instâncias personalizadas,
isso realmente não importa. Vou chamar essa lista
porque essa lista porque essa lista conterá todos os nossos números que estamos passando
para esse método. Agora, ao trabalhar com listas, vamos usar
algo como um
loop para percorrer cada
item dessa lista. Assim, podemos somar todos os
números . Vamos fazer isso agora. Inicializamos uma
variável com zero. Isso manterá um registro de todos os números que
estamos somando. Isso deve funcionar ali mesmo. Estamos examinando
todos os números da lista. Estamos mantendo uma contagem contínua, adicionando tudo a
esse resultado aqui
e, em seguida, gerando a saída Vamos obter
o mesmo resultado. Aqui, você pode ver 13. Agora, esse é o poder
da palavra-chave params. Veja isso. Ok, eu modifiquei o
argumento de chamada aqui para adicionar muito mais
parâmetros a essa lista, mas você pode ver que ele não
causou nenhum problema. Esse é o poder
da palavra-chave params. Se fôssemos criar
uma lista, por exemplo, e passá-la para o método
, teríamos que modificar
a lista dessa forma também. Mas você pode ver como isso não
causa nenhum erro. Podemos compilar o software
e executá-lo,
e temos o resultado esperado aqui Esse é o poder
da palavra-chave params. Ele nos permite usar
um método para aceitar um número variável de
parâmetros do mesmo tipo
e, em seguida, trabalhar
com essas informações Agora, existem algumas regras
associadas a isso. Só pode haver
uma palavra-chave params por declaração de método,
por exemplo Não podemos ter dois desses, então não vai funcionar. Em segundo lugar, a palavra-chave params deve vir no final
de tudo aqui Se eu tiver mais de
um parâmetro aqui, os parâmetros devem estar no final Não pode estar no começo, não pode estar no meio. Então você pode ver que um erro
ocorreu aqui, porque ele deve estar
no final da lista. E, por fim, os parâmetros aqui devem ser uma matriz
unidimensional Não pode ser uma matriz
bidimensional
, não pode ser nada
estranho assim Portanto, há algumas das regras associadas à palavra-chave
params Então esse é o poder da palavra-chave
params em C sharp. Sim, existem outras maneiras de
alcançar os mesmos resultados, mas quanto mais ferramentas você
tiver em sua caixa de ferramentas, melhor desenvolvedor
você se tornará Então essa é a
palavra-chave params em C sharp.
77. 19-1. Enumerações: o tipo enum: Eu quero falar sobre
enumerações em C Sharp, também
conhecidas como E a palavra-chave é mais ou
menos assim. Mas o que é um enum e
por que devo usá-lo? Bem, eu tenho um
exemplo aqui. Aqui estou configurando quatro objetos
de videogame. Eles aceitam vários parâmetros. Vamos dar uma
olhada na aula agora. Então, você pode ver que é
preciso um console, um título de videogame, uma editora de videogame
e uma classificação. Então, vamos prestar atenção a essa sequência de
classificação aqui. O que eu quero fazer é
permitir apenas determinadas classificações
para todos. Dez mais adolescente, maduro, 17 mais, etc., etc Eu só quero que esses
valores sejam passados e eu só quero
lidar com esses valores. Mas ao
configurar esses objetos, você pode ver que eu os estou
colocando aqui. Mas é muito
fácil cometer um erro. Eu poderia cometer um erro ortográfico, talvez uma letra minúscula,
algo assim Se esse aplicativo estiver
conectado a um banco de dados
, haverá alguns problemas. Vou armazenar valores
incorretos e todo o
sistema pode ficar confuso Se alguém quiser pesquisar
um jogo, por exemplo, e a classificação estiver errada
porque está escrito incorretamente, talvez, se estiver
pesquisando por classificação, esse videogame nunca
apareça na Muitos motivos pelos quais precisamos que nossos dados sejam
concisos e precisos Uma maneira de resolver esse
problema é garantir que não haja erros de
ortografia para essa variável de string Classificação, por exemplo, é usar algo chamado enumeração ou
enumeração Como faço
para configurar isso e como faço para
integrá-lo à minha aula de
videogame aqui? Bem, vamos dar uma olhada. Vamos para
o lado direito aqui, onde temos nosso projeto. Vamos escrever Clique, Vá para Adicionar e depois vá para a aula. Vamos chamar isso de algo que
represente nossa classificação. Agora, se tivermos um software muito
grande, talvez
queiramos ser realmente
descritivos com isso Acho que talvez a classificação dos
videogames seja boa. No entanto, às vezes, ao
criar uma enumeração, você pode ter uma classe com
exatamente o mesmo nome e não pode criar uma
classe com o O que muitas pessoas fazem ao
criar uma enumeração é adicionar
a palavra estado
ou Então, toda vez que eles criam um, ele termina em estado ou tipo. Depende realmente de você
, não importa. Mas vou
chamá-lo de algo assim. Então, preste atenção aqui, você percebe que é uma classe
aqui quando eu clico em Adicionar, então se virmos para a esquerda, agora temos um tipo de classificação de
videogame de classe interna. Bem, não queremos uma
aula, queremos uma enumeração. E não havia
um modelo para isso, então agora temos um enum. É tão simples quanto
mudar a classe para enum. Temos uma enumeração aqui. Então, como isso funciona? Bem, vamos para
nossa aula de videogame aqui e obter nossas classificações
permitidas. Vou colocá-los aqui como um comentário para que eu possa me
referir a eles. E eu quero criar um item
na enumeração para
cada uma dessas classificações Então, eu quero que todos tenham mais de
dez anos
, mais adolescentes , 17, etc Então, eu quero todos esses
itens nesta enumeração. E a enumeração
é como uma lista. Então, como uma lista de valores. E essa lista não é apenas uma lista, mas é como uma lista somente para leitura. Não podemos modificar
essas informações. É praticamente somente para leitura, então nós o usamos para nos
referir a esses valores. Tudo ficará
claro momentaneamente. O que vou fazer é criar alguns valores para cada uma
dessas classificações. Na enumeração, vou
começar com o que
significa todos Depois de criar um valor, coloco uma vírgula e
depois uma nova linha Agora eu posso fazer o próximo.
Agora há um problema. Depois de digitar dez,
é porque nas enumerações,
seus itens não podem conter
números ou certos caracteres, seus itens não podem conter como esse Nós vamos ter que
digitar isso. Nesse caso,
podemos dizer mais dez, e isso funciona muito bem. Vamos continuar. Eu
digitei uma enumeração aproximada
aqui, você pode ver que temos todos esses valores refletidos
na enumeração Podemos adicionar mais em uma data
posterior, se quisermos. Agora, como isso funciona? Como podemos colocar isso
em nossa classe? Bem, agora é
como um tipo de
dados em que antes tínhamos uma classificação de
string. Podemos usar essa
enumeração aqui. Se formos para nossa
aula aqui, substituiremos string pelo tipo de classificação de
videogame. Também o substituímos
no parâmetro e também em quaisquer métodos que possamos
ter aqui. Também está lá. E parece
que temos um problema, devido à acessibilidade. Por padrão, nossa
classe é interna, mas como nossa classe de
videogame é pública, precisamos tornar a
enumeração pública Agora, todos esses erros
desapareceram. Agora, na verdade, alteramos o parâmetro para
nosso construtor, para um tipo de enumeração Vamos dar uma olhada em como
construímos esses objetos agora. Agora você pode ver que há erros em tudo isso aqui. Vamos tentar mudar esse adolescente
para usar nossa enumeração. Se eu colocar uma vírgula aqui, você pode ver o intellisens, o preenchimento automático
escolheu Vamos apenas clicar
duas vezes nele. Então vamos colocar um ponto. Agora você pode ver que há
uma boa lista aqui. Se alguém quiser
construir esses objetos. Agora eles não podem simplesmente
colocar qualquer valor. Olha, isso requer um tipo de classificação de
videogame. Você pode ver na lista de
parâmetros. Mas agora simplesmente não
podemos colocar nada. Temos que escolher
algo dessa lista. Se não o fizermos,
o aplicativo nem mesmo compilará
porque há um erro Você pode ver como essa enumeração nos
força a escolher um
item dessa lista Agora podemos dizer
adolescente, por exemplo. Agora, se substituirmos cada um
deles pela enumeração, você pode ver quando estamos
construindo esses objetos, agora vai ficar Você pode ver que essa
é uma ideia bloqueada. Mas não só isso,
força pessoas, softwares
ou qualquer
outra coisa a não
cometerem erros em nossas informações. Você realmente não usaria
isso para algo como talvez a Blizzard ou o
World of War Crafts porque eles são únicos No entanto, talvez o
console possa representar uma enumeração porque há
apenas um número finito
de apenas um número finito Você sabe, você tem a caixa
Playstation X ou PC. Então, novamente, isso pode ser
representado por uma enumeração, mas para algo como classificação, parece um
candidato perfeito para se ter como
enumeração ao trabalhar enumerações Por exemplo, talvez
esses videogames estejam armazenados em um banco de dados. Agora, esse banco de dados
terá o nome do videogame, o título, e talvez não tenha o
nome completo da enumeração no Pode ter um
número inteiro como 01 ou dois. Cada um desses
números inteiros pode representar uma classificação diferente
na enumeração Por exemplo, cada um
seria 010 mais seria um, adolescente seria dois, etc Quando você define enumerações
no Visual Studio, há um tipo subjacente
que significa em Por padrão, cada um
deles tem um valor
que é um número inteiro E vou te mostrar
o que quero dizer com isso. Isso gera uma
dessas enumerações na janela
do console Vou apenas produzir uma classificação de
videogame do tipo adolescente. Provavelmente só
vai dizer que
na própria janela,
diz apenas adolescente. Mas veja o que acontece se eu
converter isso em um número inteiro. Então, se eu executar o aplicativo, agora você verá que ele tem
o valor de dois. Por padrão, há um número inteiro
subjacente aqui. Isso porque, por padrão,
o primeiro item é 012345. Isso é feito por padrão. É um comportamento padrão, mas você pode realmente alterá-lo,
se desejar. Você pode especificar seus
próprios valores para eles. Por padrão, é
algo parecido com isso. Todo mundo tem o valor zero. Este tem o valor de 12345. Isso é o que
parece nos bastidores. Eles têm esses valores inteiros. Você pode referenciá-los com o número ou com o nome. A escolha é sua. Mas, normalmente, quando você armazena algo assim
em um banco ou está passando esses valores de dados
ou está passando esses valores
para um
software diferente, talvez esteja enviando o número inteiro só porque é
menor e é mais fácil trabalhar com ele É por isso que as enumerações
têm um tipo subjacente. Considere isso como
um índice, por exemplo. Mas, como eu disse,
você pode configurar seus próprios tipos, mas
também seus próprios valores. Por exemplo, eu quero que
esse seja dez, aquele seja 2030, 40, 50. Realmente não importa, a escolha depende totalmente de você. E agora, se enviarmos isso
novamente para a janela do console, você pode ver que dez agora
tem um valor de 22, e isso é porque
atribuímos a ele o valor 22. Não sei por que fizemos isso, mas você pode ver que é
assim que o princípio funciona. Então, basicamente, nos bastidores, ele usa um número inteiro, mas você pode alterá-lo para um tipo de dados
diferente, se desejar, como um byte, um longo
ou algo parecido A escolha é realmente
sua, mas por padrão. Parece algo assim. Se quiser alterar o tipo, você pode adicionar dois pontos depois
e colocar o novo tipo aqui Quando você tem um tipo aqui
, todos esses valores devem seguir o
tipo especificado. Talvez isso seja algo que você não use imediatamente, mas é sempre bom
ter esse conhecimento em mente para quando quiser
aplicá-lo posteriormente. Mas essas são as possibilidades e coisas que você pode fazer
com as enumerações O que também é bastante comum é se
você tiver uma enumeração, Todas essas são classificações
de videogames. Talvez você não
queira especificar uma classificação, mas o usuário pode
escolher entre seis opções. Mas e se for opcional? Então, o que muitas
pessoas tendem a fazer definir um item chamado não e geralmente atribuem a
ele um valor zero. Ou eles podem atribuir um valor de 999 e colocá-lo no
final, por exemplo Mas esse é apenas um exemplo de como você pode torná-lo opcional. Não seria o
campo opcional nesse caso. Se não for obrigatório,
caso contrário, você pode selecionar
uma classificação aqui. Novamente, isso se reflete apenas na
escolha do que não é
item da lista. Não há classificação para este jogo;
nesse caso, é opcional. Agora, enumerações. Há muito mais
nas enumerações, e você pode fazer
muito mais com elas Há uma classe estática
chamada enum aqui. Você pode usar vários métodos
para fazer com suas enumerações Você pode obter o tipo subjacente como o número inteiro sobre o
qual falamos antes E você pode fazer várias coisas. Então, nós meio que
arranhamos a superfície aqui. Mas o que vou mencionar
é uma coisa para manter seus projetos
um pouco mais organizados. Se virmos até a direita aqui e
clicarmos com o botão direito do mouse em nosso projeto, o que costumo fazer é adicionar
uma nova pasta aqui, e geralmente chamo isso de enums Dentro dessa pasta, coloquei todas as minhas enumerações apenas
para que fiquem mais organizadas Dessa forma, como eles têm a mesma
extensão de arquivo de uma classe
, você
realmente não fica confuso. Você pode ocultar
todas as suas enumerações
em uma pasta de enumeração Se você se lembra de quando
falamos sobre interfaces no tutorial de
interface, como elas têm a palavra-chave
interface e não a palavra-chave class
, você também pode criar uma pasta
para suas interfaces. Isso é bastante comum.
Ele apenas mantém as coisas organizadas simplesmente porque elas têm a mesma extensão de arquivo. Se você tiver um aplicativo muito
grande com centenas de classes, poderá encontrar facilmente suas enumerações só porque elas estarão todas em um
diretório chamado enums,
uma boa organização ao trabalhar com interfaces
. Além disso,
enumeração com centenas de classes,
poderá encontrar facilmente
suas enumerações só porque
elas estarão todas em um
diretório chamado enums,
uma boa organização ao
trabalhar com interfaces
. Além disso,
enumeração é muito útil. Isso evita erros ortográficos
ou algo parecido. E é muito útil
quando você tem uma lista finita de itens,
por exemplo, consoles ou classificações. Talvez ao trabalhar com
naipes em um baralho de cartas ou representar meses do ano ou
algo parecido. Mas lembre-se de que os itens de enumeração são lidos apenas como constantes,
portanto, você não pode atribuir
nada a eles.
Portanto, considere-os como lidos
somente ao trabalhar com eles Então, essas são as enumerações na loja.
78. 19-2. Recorrência e manipulação de arquivos (IO de arquivo / System.IO): Vou falar sobre
um conceito totalmente novo agora. E esse conceito é
chamado de recursão. Se você está familiarizado
com ciência da computação, ou talvez tenha feito outras linguagens de
programação, ou mesmo matemática. Talvez você já tenha ouvido essa palavra antes, mas talvez não tenha. Então, por que estou no Google?
Eu ouço você perguntar. Bem, quando comecei meus empreendimentos de
programação, recursão era algo
que realmente me confundia Você já viu
o filme Inception, onde o cara vai dormir
e depois está em um sonho, mas depois ele vai
dormir no E meio que brinca com sua mente e você meio que
se pergunta, ele está sonhando Em que camada de sonho
ele está ou está acordado novamente? Você sabe, é muito confuso. E os sonhos aninhados
neste filme sempre me
lembraram do conceito de recursão e você verá Mas espero que neste tutorial eu o divida em etapas
simples para que você o
entenda com
muito mais facilidade do que
quando
comecei a aprender. E
eu vou te mostrar o porquê. Se você pesquisar no Google o
termo recursão, obterá uma descrição aqui O processo de
definir um problema ou uma solução em termos de uma versão
mais simples de si mesmo. Por exemplo, você pode
definir uma operação, encontrar o caminho de casa como
se estivesse em casa. Você entende o que eu quero dizer aqui? Não está muito claro, não é? E quanto mais você rola, mais confuso fica. É apenas uma daquelas
coisas que você meio arranca o cabelo e
quando olha as imagens, bem, as imagens também não
ajudam. Você acaba de ver esse tipo
de imagem aqui de algo dentro de outra coisa e ela se repete para sempre. Então, deixe-me explicar para
você o que é recursão. Isso ajuda ao analisar a
recursão em C Sharp no Google e fornece uma explicação
melhor do que é em
termos de C Sharp Recursão é um conceito no
qual um método chama a si mesmo, e é exatamente isso No mundo do C sharp, você define um método e o
método então chama a si mesmo. Agora, por que um método
gostaria de se chamar? Bem, se você tem funcionalidade dentro de um método para fazer algo, talvez
queira reutilizar esse código Por que não? Programar tem
tudo a ver com a reutilização de código Isso economiza tempo, é
mais fácil de manter e há muitos outros
motivos para fazer isso. Isso é o que vamos
ver hoje, recursão em C sharp, e vamos definir um
método que chama a si mesmo Estamos aqui
no Visual Studio. Agora, o que eu quero fazer é configurar um método
que chame a si mesmo. Se você assistir a outros
tutoriais sobre recursão, provavelmente
verá
algo em que precisará
calcular o fatorial
de Fatorial é um vezes dois, vezes três vezes quatro. E então você configura
um método para fazer isso. Acho que esse é um exemplo muito
fraco e chato. Acho que podemos usar algo que
talvez possamos aplicar
no mundo real. Acho que um recurso de pesquisa
é muito bom para isso. O que eu quero fazer é
apresentar a vocês minha coleção de músicas muito
ruins. Aqui você pode ver
que é bastante eclético. Temos todos os gêneros
diferentes aqui. O que eu quero fazer é especificar um termo de pesquisa e
isso pode ser qualquer um, pode ser o nome de uma banda, pode ser o nome de uma
música, qualquer coisa assim. Quero devolver todos os arquivos de música que
correspondam a esses critérios. Então, vamos pedir ao
usuário um termo de pesquisa, o usuário o digitará. O resultado serão
os caminhos completos de todos os nossos arquivos de música. Agora, essa coleção de músicas
está muito desorganizada, por
isso precisamos de um recurso de
pesquisa aqui Eu tenho uma pasta de músicas aqui, e dentro dela eu tenho uma pasta chamada Ainda Mais Música. Eu tenho todas essas pastas novas
e, em seguida, tenho músicas
espalhadas por toda parte Acho que um recurso de pesquisa pode ser algo bom
para esse exemplo. O problema é que eu preciso de
algo para colocar os diretórios
dentro de um caminho de arquivo que eu forneço ao software Então, se eu fornecer o software, esse caminho de arquivo aqui, eu preciso dele para obter
os diretórios A segunda coisa que
preciso fazer é fazer com o software coloque todos
os arquivos em um diretório
e verifique, por sua vez, cada um
desses arquivos para ver se eles
correspondem aos critérios de pesquisa. Ele precisa fazer dois trabalhos. E por que esse cenário é um
bom exemplo de recursão? Como posso aplicar um
método recursivo a esse exemplo? Bem, eu quero obter
os diretórios e os arquivos de cada
diretório aqui Eu quero fazer a
mesma lógica aqui. Eu quero obter esses
diretórios, esses arquivos. E então, dentro desses
diretórios, eu quero verificar isso. Há mais diretórios e
, em seguida, obtenha os arquivos. A lógica dos métodos
se aplica praticamente a qualquer
diretório aqui. Quero reutilizar
a funcionalidade. Eu quero usá-lo aqui inicialmente. Então eu quero
vasculhar essas pastas. Continue pesquisando até que não
haja mais
e, em seguida, verifique os arquivos aqui A recursão será um exemplo
muito bom de algo que podemos usar para esse cenário
específico aqui Vamos dar uma olhada em
como podemos fazer isso. Estou aqui no
Visual Studio agora. O que eu preciso fazer
é criar um método. E o método
vai se chamar sozinho. E o trabalho do método é
essencialmente pesquisar um arquivo
que o usuário especifica Vamos configurar isso agora. A primeira coisa
que quero fazer é pedir
ao usuário um
termo de pesquisa. Vamos fazer isso. Então eu quero aceitar
a entrada do usuário. Agora eu tenho o
termo de pesquisa do usuário. Eu quero chamar um método. Vamos configurar um método que realmente faça
a pesquisa. Vou chamar
o método search. Acho que é um nome
muito adequado. Agora, preciso definir
alguns parâmetros. Quais parâmetros devem ser usados? Bem, o primeiro,
precisamos saber onde a música está localizada
no sistema. Precisamos de um caminho de arquivo. Acho que esse é um primeiro parâmetro muito
bom. O segundo, provavelmente,
o termo de pesquisa. Precisamos do método para saber o que realmente estamos
procurando. O último, talvez
um parâmetro de referência e talvez seja uma
lista ou uma matriz. Isso coletará
todos os nossos resultados. Quando você pesquisa algo, você pode ter um resultado, você pode não ter nenhum resultado. Mas você também pode
obter dez resultados, como dez correspondências
para sua pesquisa. Não podemos simplesmente retornar
um tipo simples, precisamos retornar algo
como uma matriz ou uma lista. Por exemplo, acho que usar uma coleção como uma lista
aqui será bastante adequado Vou chamar isso de
resultados porque ele
conterá todos os resultados
que encontramos em nossa pesquisa. Agora temos o caminho
onde está a música. Temos o termo de pesquisa do
que estamos procurando. Agora temos uma coleção aqui que
armazenará nossos resultados. Uma coisa que você pode
se perguntar é, bem, por que não temos isso
como valor de retorno? Por que precisamos de um parâmetro que seja um tipo de referência
como aqui, por exemplo? Bem, a verdade
é que realmente não
importa se eu definir isso
como o tipo de retorno. Acho que isso pode complicar um pouco mais
esse exemplo. O que eu quero dizer a
você é como a recursão funciona, onde um método chama um método, também
conhecido como
método recursivo Se eu configurar um tipo de retorno
, terei que retornar
o valor de cada chamada para o
método em si. Acho que isso pode complicar um pouco
o exemplo. Vou usar um
parâmetro por enquanto e
, quando eu realmente
desenvolver a solução, vou mudar isso para
um tipo de retorno para que eu
possa mostrar esse exemplo também. Esse é o raciocínio
por trás disso aqui. Ele só vai
armazenar os resultados. Ao desenvolver
métodos recursivos como este aqui, é sempre bom obter primeiro a funcionalidade
básica E é isso que
ele foi projetado para fazer, ignorando completamente a recursão. É aí que o
método se chama. O que eu quero fazer é usar o caminho que nos
foi fornecido e usar
o termo de pesquisa para ver se podemos realmente obter alguns resultados
da pasta raiz aqui. Por enquanto, vamos ignorar
a busca por pastas e
tudo mais O que eu quero fazer é
obter esses arquivos aqui, obter todos os arquivos para o diretório fornecido
e, por sua vez, quero verificar cada arquivo para ter
certeza de que ele contém
nosso termo de pesquisa. Se isso acontecer, quero adicioná-lo
à lista de resultados que
acabamos de criar. Vamos dar uma olhada em como
podemos realmente obter esses arquivos para um
diretório e, em seguida, verificar cada título para
garantir que ele contenha nosso termo de pesquisa
no Visual Studio. Agora, se quisermos trabalhar
com arquivos, diretórios, caminho de
arquivo ou
algo parecido, na verdade
existe um
namespace que podemos usar Isso é fornecido para nós. Usamos a palavra-chave using
e, em seguida, digitamos system e , em seguida, O significa entrada e saída. Tem praticamente qualquer coisa
a ver com arquivos registrados em arquivos de texto lidos de
arquivos, coisas assim. É um
namespace muito útil que podemos usar. Ele não está incluído por padrão. Por exemplo, antes, em um tutorial
anterior, em que usamos a classe matemática estática e dentro da matemática, podemos fazer
várias funções matemáticas. Isso é incluído por padrão porque é uma biblioteca
bastante popular. Ao criar um aplicativo, talvez
você queira fazer
muitas coisas relacionadas à matemática, por exemplo, e muitas
outras coisas também. No entanto, nem todo
software que você criar
funcionará com arquivos. É por isso que precisamos incluir essa biblioteca de
forma explícita e manual incluir essa biblioteca de
forma explícita Isso é só um pouco de
informação aí. Se você quiser usar qualquer outro
namespace, você pode adicioná-lo abaixo no namespace system
I aqui Há muitas
coisas que você pode fazer. Você pode fazer tudo
isso aqui. Muitas e muitas e
muitas coisas. Mas há
algumas classes estáticas que você
talvez queira conhecer. A primeira, por exemplo, é Directory, e essa
é uma classe estática. Usando isso, podemos
criar diretórios em nosso sistema apenas fornecendo
um caminho como parâmetro Podemos excluir diretórios. Podemos obter arquivos em um
diretório que fornecemos. Podemos fazer muitas coisas
com diretórios. Esse diretório,
classe estática, é muito útil. Outra é uma
classe estática chamada file. Com o arquivo, podemos criar arquivos. Por exemplo, se quisermos
criar um arquivo de log, podemos excluir arquivos. Podemos verificar se os arquivos existem, podemos mover e abrir arquivos. Então, muitas
coisas diferentes para fazer com arquivos. A última que é bastante útil é a classe path static. O Path é muito útil
para trabalhar com caminhos. Se estivermos fornecendo nosso caminho de arquivo, podemos obter o
nome do arquivo a partir do caminho. Talvez possamos obter a
extensão de um arquivo. Na verdade, podemos trabalhar com um caminho completo e
também podemos unir caminhos. Isso é muito bom para
trabalhar com caminhos de diretório. Há três classes
estáticas que você achará muito
úteis daqui para frente. E vamos
utilizar alguns deles hoje quando desenvolvermos nossa pesquisa de função
recursiva Aqui, mencionei antes
que queremos que nosso método obtenha os arquivos no diretório de rotas
apenas para começar, apenas para ter certeza de que está
realmente funcionando, o que queremos fazer é obter todos os arquivos em um
determinado diretório. Conhecemos essas informações
porque esse é o caminho que é
passado para o nosso método. Quero obter todos os arquivos desse
diretório aqui. Para fazer isso, usamos a classe estática
do diretório e há um método
chamado get files. Obter arquivos usa
um parâmetro e esse é o caminho em que
os arquivos estão localizados. Agora, o retorno desse
método é uma matriz de strings. Agora, essa matriz conterá os caminhos completos de cada
arquivo nesse diretório. Se formos ao
nosso canal de música, ele vai ter todos
esses arquivos aqui. Cada item na matriz
conterá o caminho completo do arquivo. O caminho completo no sistema, que será o retorno desse método, get files. Vou armazenar isso em
uma variável chamada files. Serão todos os
arquivos no diretório fornecido. Agora, o que eu quero fazer
é percorrer todos esses arquivos aqui e
verificar o nome do arquivo, não necessariamente o caminho inteiro. Queremos apenas verificar
o nome do arquivo para verificar se o nome do arquivo
contém nosso termo de pesquisa. Aqui, precisamos de um loop aqui. Acho que para cada loop
pode ser suficiente. Nesse caso, o Visual Studio gentilmente nos deu alguma ajuda de
preenchimento automático Vou pegar agora. Nesses quatro ciclos, quero
verificar cada arquivo por vez e verificar se o nome desse arquivo contém
nosso termo de pesquisa. Como eu faço isso? Bem, quando eu quero verificar,
preciso de uma condição. Eu sei que vou precisar de
uma declaração if aqui. Agora, qual condição eu
preciso na declaração? Bem, eu preciso obter o nome do
arquivo desse caminho. Não quero a letra da unidade, não
quero os nomes das pastas, só
quero o nome do arquivo
ao trabalhar com o path. Como mencionei antes, uma classe estática chamada Path
é muito boa para isso. Existe um método chamado
get file name without extension que obterá o nome
do arquivo, digamos três. Há também um
chamado get file name. Você pode escolher qual deles
deseja , dependendo se
deseja que os usuários também pesquisem extensões de
arquivo. Eu só vou usar esse. Ele usa um parâmetro e
esse é o caminho a partir disso, esse código destacado aqui. Isso obterá o
nome do arquivo sem a extensão
chegue à nossa música. Essa seção será
destacada aqui, o que é ótimo. É isso que queremos verificar
novamente no Visual Studio. Agora eu sei que esse
é o nome do arquivo sem a extensão
e sem o caminho. Quero tentar ver se
alguma delas contém
nosso termo de pesquisa. Em um tutorial anterior, abordei o trabalho com strings onde fizemos várias
coisas com strings, substrings e
coisas Como essa é uma string aqui, path get file name sem a extensão
retorna uma string. Portanto, isso
representará uma string. Quando coloco arte
depois daqui, temos todas essas coisas diferentes que
podemos fazer com cordas. Há um método aqui
chamado contains. Contém. Recebe um parâmetro, que
é um caractere, uma string ou, na verdade,
vários parâmetros. Um personagem e um tipo de
comparação. Mas nós só queremos usar
essa sobrecarga de strings aqui. Queremos verificar se
ele contém nosso termo de pesquisa. Eu acho que é uma condição
muito boa. Agora, há uma pequena
pegadinha aqui, que vou revelar
um pouco mais tarde, mas por enquanto
vou deixar Agora, estamos verificando se
cada
arquivo, por sua vez , contém nosso
termo de pesquisa. Isso é muito bom. Agora, se ele realmente
contém nosso termo de pesquisa
, queremos adicionar
esse caminho aqui, que é arquivo, à nossa
lista de resultados. Vamos fazer isso agora. Usamos o
método add para fazer isso. Nós adicionamos o arquivo lá. Se você não sabe
nada sobre listas
, fiz um
tutorial sobre isso. Eu recomendo que você confira isso. Agora parece que estamos
fazendo algo muito bom. Estamos examinando todos os
arquivos no diretório fornecido. Se ele contiver o termo de pesquisa, nós
o adicionaremos à lista de resultados aqui Como esse é um tipo de
referência, ele lembrará
o que adicionamos quando a execução desse método
for
concluída Isso porque está
armazenado na pilha, é um tipo de referência Agora, o que eu quero fazer é
realmente chamar esse método. Forneça parâmetros para
ele. Vamos fazer isso. Agora. O primeiro parâmetro que eu preciso é o caminho onde
a música está localizada. Vamos pegar isso. Agora,
coloque isso de volta aqui. Este é o diretório de rotas onde todas as músicas estão localizadas. O próximo parâmetro que
configuramos é o termo de pesquisa, que extraímos
da entrada do usuário. Na última, precisamos fornecer uma lista de onde realmente
vamos armazenar nossos resorts. Vou definir um
local aqui no Maine. Configure uma nova lista aqui. Eu não dei
nenhuma capacidade porque não
sabemos quantos resorts
existirão. Acabei de criar uma lista MT aqui. Vou passar
isso para o método. Quando a execução do método
terminar, teremos acesso a esses
resultados aqui embaixo Isso porque, como mencionei, é um tipo de referência. Agora, o que queremos fazer é apenas exibir os resultados para o usuário. Talvez pudéssemos usar um quatro para
cada um para isso também. O que eu quero fazer, toda vez que
tivermos um resultado em resultados, vou dizer que vamos
apenas gerar o resultado. Então, eu poderia acrescentar uma declaração
if dizendo que se não houver resultados, talvez eu imprima o
fato de que não há resultados. Ok, então parece
algo assim. Agora eu entendo que existem maneiras
mais elegantes de fazer praticamente tudo
no desenvolvimento de software, mas tento escrever isso de uma
forma que você entenda que
é mais fácil de entender é mais fácil porque é
assim que o cérebro funciona Talvez, no final, possamos
organizar o que é opcional, mas o que eu quero transmitir é o princípio dos métodos
recursivos Temos algumas funcionalidades básicas aqui ao desenvolver software, podemos testar, apenas para
garantir que funcionem, não
precisamos
concluir completamente o desenvolvimento do software. Acho que agora pode ser um
bom momento para testar isso, só para ter certeza de que funciona. Vamos executar o aplicativo agora. Agora, insira um termo de pesquisa. Vamos tentar pesquisar
por Aba, por exemplo. Por que não entro no meu aplicativo?
Digito que o Abba diz que não
há resultados para
minha pesquisa. Por que isso acontece? Vamos tentar descobrir isso. Eu volto para o software agora, não
estou obtendo nenhum
resultado daqui, mas claramente estou
adicionando um resultado aqui. O que está acontecendo aqui? Vamos ver se podemos
descobrir isso. Vamos colocar um
ponto de interrupção aqui e executar o software. Digite Ab. O que temos aqui? Parece que estamos recebendo
todos os nossos arquivos aqui. Estamos realmente atingindo esse
ponto de ruptura em que estamos
agregando valor?
Parece que não estamos. Então, há algo errado aqui. Parece que não conseguimos
obter o nome do arquivo corretamente ou algo bem
diferente está acontecendo aqui. Parece que eu acidentalmente coloquei o caminho aqui quando
deveríamos ter um arquivo No momento, estamos
pesquisando apenas o
caminho do arquivo em que a música está localizada e não
o nome do arquivo que
está dentro do loop. Se isso resolver o problema, tudo bem,
parece que está funcionando Agora, como você pode ver,
ninguém é perfeito. Erros acontecem,
mas se você assistir meus tutoriais sobre depuração
e tudo mais,
você também saberá como resolver os problemas sozinho Então parece que está funcionando. Vamos tentar
outra coisa bem rápido. Eu fiz alusão a uma
pegadinha anterior, seja, se eu
pesquisar por Aber, onde aparece em minúsculas e diz que não há Mas é claro que temos
uma música chamada Abba. O que você pode ver aqui é que
há um problema com distinção entre maiúsculas e minúsculas. Isso porque Aber no
NP três está em maiúsculas, mas estamos usando um termo de pesquisa em
minúsculas Então, como podemos contornar isso? Bem, arquivo é uma string e
o termo de pesquisa é uma string. Quando usamos strings, temos muitas coisas
disponíveis para nós O que podemos utilizar é esse
método aqui chamado de abaixar. O que isso faz é converter
tudo isso em minúsculas. Da mesma forma, podemos fazer
isso no termo de pesquisa. Agora estamos comparando todo o nosso termo
de pesquisa, tudo em minúsculas, com o nome do arquivo, tudo em minúsculas. Agora, não devemos ter problemas com distinção entre
maiúsculas e minúsculas. Se eu executar o aplicativo
agora e pesquisar por Aber, você pode ver agora
que tenho o resultado Agora estamos ignorando o caso.
Isso é muito bom. Vou fazer mais uma
pesquisa e pesquisar
talvez a letra E apenas para talvez a letra E apenas para garantir que obtenhamos
vários resultados. Voltando,
parece muito bom. Parece que estamos
recebendo todos os nomes dos arquivos que contêm a letra. Isso é muito bom. Agora, acho que estamos prontos para a recursão. Temos a
funcionalidade básica funcionando. Estamos felizes que esteja funcionando
para o diretório base. Agora podemos introduzir a recursão. O problema é que
quando você introduz recursão desde o início, especialmente se você
não é proficiente,
então, se você tiver um erro, pode
ser apenas com
sua É muito bom
fazer isso funcionar antes de introduzir
a recursão nisso Isso torna as coisas muito mais fáceis. Vamos introduzir um pouco de
recursão nesse método. Agora, eu agradeço que você
não entenda isso da primeira vez, mas não se preocupe, você
acabará por conseguir. Há algumas maneiras de
resolver esse problema. O que eu quero fazer é que eu tenho esse método de busca
que obtém os arquivos, que é muito bom. Mas também quero
dar a esse método o próximo diretório
no diretório atual. Aqui, por exemplo,
temos nosso diretório de músicas. Já estamos
verificando os arquivos, mas também quero obter todos
os diretórios aqui Então, dentro de cada diretório, eu quero fazer a funcionalidade
principal, que é obter os arquivos, mas eu ainda quero obter
os diretórios também. Então, aqui dentro, eu quero fazer a mesma coisa, pegar os arquivos. Há algum
diretório aqui? Claramente, preciso de alguma
função para obter todos
os diretórios no
diretório atual. Vamos fazer isso. Agora, eu vou
colocar isso aqui. Há uma coisa útil que
podemos fazer para obter diretórios usar
a classe estática de
diretórios Existe um método chamado get directories e ele segue um caminho Qual caminho faz isso? Ele
segue nosso caminho raiz. E, assim como antes, ele retorna uma matriz de strings e cada item dessa matriz será o caminho completo dos diretórios
nesse caminho aqui Então, vou chamar isso de
DR para diretórios. E como sabemos que queremos entrar em
cada diretório, precisamos percorrer isso
também sem nem
pensar em nada. Sabemos que precisamos de
diretórios e sabemos que precisamos verificar
cada um deles sem nem mesmo nos preocupar com o
problema de recursão,
início ou o que você quiser Sabemos que precisamos dessa
funcionalidade agora. Depois de implementarmos essa
funcionalidade, precisamos descobrir como
realmente lidar com esse problema. O que colocamos aqui? Precisamos de alguma coisa aqui? Precisamos de alguma coisa
aqui? E assim por diante. Mas agora temos um
pequeno modelo. Vamos dar uma olhada em como
abordar esse problema. Estou fornecendo o
diretório raiz para o método. O que eu poderia fazer
nessa situação é obter todos os diretórios E com o primeiro
diretório eu entro nele, então eu chamo o método novamente O que ele vai fazer é
exatamente a mesma coisa. Ele pegará todos
os diretórios e entrará no primeiro Isso fará com que todos
os diretórios apareçam
no primeiro E agora estamos
na pasta final. Não há mais diretórios, então não podemos entrar no primeiro Então, a última coisa que precisamos
fazer é pegar os arquivos. Então,
o que estamos fazendo aqui é fazer com que os diretórios estejam
sempre no primeiro, sempre no primeiro Até chegarmos
ao final, pegamos os arquivos, saímos um, entramos no próximo, pegamos todos os diretórios,
entramos no primeiro, pegamos todos os diretórios, entramos
no primeiro, etc Então é isso que estamos fazendo aqui. Estamos mergulhando até o fundo, que é a primeira
coisa que estamos fazendo. Vamos para dentro, para
dentro, para dentro, até o maior
beco sem saída que está aqui. E então estamos
verificando os arquivos. Então é isso que vamos
replicar em nosso método. Agora, na primeira execução disso aqui,
o método
de pesquisa,
estamos passando o caminho que é
o diretório
raiz da nossa música aqui. O que eu quero fazer é obter todos
os diretórios, como acabei de
mencionar, na pasta raiz São todos aqueles que estão aqui. Isso é o que esse loop de
quatro está fazendo. A primeira iteração
do loop de quatro será
esse diretório aqui Agora, queremos realmente
entrar nesse diretório. O que podemos fazer, podemos passar
esse método para si mesmo. Podemos chamar o
método a partir de si mesmo. Até o que eu quero fazer
é chamar o método. Vamos simplificar isso.
Os resultados nunca mudarão. Não estamos definindo
nenhum resultado novo, estamos simplesmente
adicionando aos resultados quando temos um resultado,
quando temos uma partida Na verdade, estamos inicializando
e definindo resultados aqui toda vez que
divulgamos resultados Só queremos simplesmente
distribuí-lo. Quando chamamos esse
método dentro de si mesmo, queremos apenas passar
esse valor para dentro. A única razão pela qual queremos
fazer isso é apenas adicionar algo a isso. Nós realmente não
precisamos fazer nada especial com isso aqui. O mesmo se aplica
ao termo de pesquisa. Não estamos alterando o termo de
pesquisa aqui, estamos basicamente pedindo
ao usuário um termo de pesquisa. No que nos diz respeito, ele é praticamente lido
apenas dentro desse método. Novamente, estamos apenas passando por
isso também. Assim como os resultados, a única
coisa que realmente difere aqui é o caminho dentro do
nosso primeiro diretório. Na verdade, queremos o diretório em
que estamos acessando. Vai ficar mais ou
menos assim. Se eu remover isso um pouco, é assim que
vai ficar. Não sei se você consegue
entender isso,
mas na primeira vez que isso é executado, estamos obtendo os diretórios Estamos percorrendo
esses diretórios. Então, no primeiro diretório, estamos chamando esse método novamente. Agora, esse método está
sendo chamado com o primeiro diretório
no caminho original. Uma vez dentro desse
diretório, novamente, estamos recebendo os
diretórios novamente até chegarmos ao
final, que está aqui Imagine que esse é o caminho
que está sendo percorrido no
Now, agora não há diretórios Isso vai ter
uma contagem de zero. Isso para cada loop
nem mesmo será executado porque, se não houver
diretórios nesse resultado, isso será totalmente ignorado Agora, quando isso for ignorado, esse método não se
chamará porque
essa é a única vez em que o método chama
a si essa é a única vez em que o método chama
a O que ele fará então
é obter todos os arquivos. Em seguida, ele obtém esses
arquivos aqui e verifica se temos uma correspondência
e o método termina. Quando o método termina, voltamos para a chamada anterior, que está dentro desse loop. Em seguida, ele
se chamará novamente no
próximo diretório, na próxima iteração
do loop Em seguida, termina, vai
para o próximo diretório. Aqui, ele verifica os diretórios
e arquivos. Isso funciona? Vamos dar uma olhada, por que
não inserir um termo de pesquisa? Então,
o que vou fazer fornecer um
termo de pesquisa para um arquivo como este. Por exemplo, olá, olá. Agora, olá, olá está
localizado nesta pasta, dentro desta pasta, e olá, olá não está no diretório
base. Ao pesquisar por hello, sei que ele está verificando muitas pastas
para encontrar esse arquivo, esse é um
teste adequado
que eu poderia usar. Vamos executar o programa. Por favor,
insira seu termo de pesquisa. Vamos digitar olá aqui. Parece que o encontrou. Você vê esse resultado,
procurando por subdiretórios, ele entrou em dois diretórios e
finalmente encontrou o arquivo Aqui,
parece que está realmente funcionando. Este é um exemplo aqui
de um método recursivo, que é apenas um método
que chama a si mesmo. Estamos apenas inserindo os resultados em um parâmetro que é um tipo de
referência, é uma lista Vamos fazer mais um teste
para ter certeza de que está funcionando. Vou pegar
o arquivo Hello, que está aqui, e
colá-lo em mais alguns lugares. Eu vou colocá-lo aqui. Eu vou colocá-lo aqui. Eu vou colocá-lo aqui. Agora devemos obter
muito mais resultados. Vamos executar o programa,
digite hello. E agora você pode ver que
encontrei todas essas instâncias
desse hello P three, então parece que está funcionando. Então, isso é uma notícia muito boa. Agora, ao escrever métodos
recursivos, você precisa de uma maneira de
escapar da recursão A recursão não será interrompida a menos que você introduza
algo como uma condição, talvez uma declaração if Ou talvez, no nosso
caso, tenhamos um loop que percorre
diretórios e arquivos Não temos diretórios
infinitos, não
temos arquivos infinitos Então, eventualmente, esse método
recursivo será interrompido. No entanto, é muito fácil fazer com que um método se chame indefinidamente, como neste exemplo Se eu fizer com que esse método
se chame com os mesmos parâmetros, não
há como isso sair. Esse é o perigo
de usar a recursão. Ao escrever métodos recursivos, sempre
verifique se você tem uma condição ou alguma cláusula de
escape Caso contrário, seu aplicativo
travará e você terá muitos comportamentos
inesperados.
Veja, se eu executar o programa, agora que eu digito qualquer termo de pesquisa, você pode ver que temos
um estouro de pilha Ele tentou se chamar
24.000 vezes antes finalmente travar porque a pilha está cheia da área de memória da
pilha Sempre tenha cuidado com isso ao escrever métodos recursivos Então, no início do
tutorial, eu disse, oh, poderíamos facilmente ter essa
coleção aqui como um retorno. Não precisamos disso como parâmetro. Agora eu expliquei a recursão, isso pode modificar esse código
e ter isso como um retorno Em vez disso, eu configurei o valor de
retorno aqui. Eu defino isso aqui em cima. Vamos remover essa parte. Vamos armazenar os resultados
em uma lista de resultados aqui, porque esse
será nosso retorno aqui. Não preciso mais
passar esse parâmetro e não preciso mais
dele como parâmetro, mas preciso definir
um resultado aqui. Vamos fazer isso agora. Ok,
o que eu fiz aqui, eu adicionei um retorno
aqui para pesquisar, que é uma lista de uma string. Eu defini a lista
de resultados da string dentro
do método aqui. Agora, há algumas coisas
a serem observadas. A primeira coisa que preciso fazer é realmente devolver isso
do método. Eu vou fazer isso. Agora
, a próxima coisa que preciso fazer sempre que
chamo recursivamente esse mesmo método aqui Também preciso armazenar a devolução toda vez que a chamo
recursivamente Caso contrário,
perderemos essas informações. Se estamos nos
aprofundando em nossa estrutura de pastas, encontramos alguns arquivos, por exemplo, como aqui. Bem, precisamos passá-los para fora da
chamada interna do método,
porque, por exemplo,
não estou armazenando um retorno aqui. O que eu preciso fazer toda vez
que eu chamo isso recursivamente, eu preciso armazenar
os resultados aqui Agora você pensa, ok,
parece que está funcionando. Eu defini a lista, toda vez que eu me
chamo recursivamente, estou me lembrando desses
valores e os definindo Então, toda vez que temos uma partida, eu a adiciono à lista
e, eventualmente, a devolvo e imprimo os resultados. Vamos dar uma olhada e ver o que
acontece. Vamos dizer olá. Parece que temos
um pequeno problema. É aqui que a depuração
é muito útil, mas posso dizer
o que está acontecendo aqui O problema é que
encontramos alguns arquivos nas profundezas de
nossas chamadas recursivas,
por exemplo, esses arquivos Agora, isso tem duas pastas de
profundidade, você pode ver aqui. Agora, o que está acontecendo é que eles
não estão sendo lembrados, porque quando isso
finalmente sai, estamos redefinindo esse valor toda vez que chamamos
esse método recursivo E isso é um pouco problemático. Estamos adicionando o material aqui, mas também o redefinindo Essencialmente, nada está sendo
lembrado, mas na verdade estamos adicionando
informações aqui. Se eu colocar um
ponto de interrupção do tipo Hello, na verdade
existem arquivos aqui, mas o problema é que ele está
realmente sendo reiniciado. Se eu olhar minha guia
Locais aqui embaixo, posso monitorar os
resultados aqui Estabeleci um ponto de interrupção na
volta, acertei um cinco. Agora você pode ver que eu tenho um
resultado se eu sair daqui. Agora você pode ver os resultados
como redefinidos para zero. Assim que eu saio daqui, nada está sendo lembrado. O que está acontecendo aqui. O problema é
que, bem, é um problema bem simples, mas talvez seja muito difícil entender quando
falamos recursivamente O que precisamos
realmente fazer é adicionar os resultados dessa
pesquisa a essa lista Não podemos simplesmente substituir a lista pelos
resultados da pesquisa,
caso contrário, estamos
esquecendo tudo o que aprendemos até agora O que precisamos fazer é adicionar tudo, desde os resultados
da pesquisa recursiva E há um método
chamado add range. E o que isso faz é adicionar um ou mais itens à nossa lista. E essa é a
vantagem de usar uma lista em vez
de uma matriz simples. Temos esses métodos
disponíveis para nós. Então, vamos dar uma olhada nisso agora e ver se isso
funciona melhor. Então eu executo o aplicativo, digito olá e agora temos todos
os nossos resultados. Eles não estão mais sendo criados por meio de nosso método recursivo Chamar isso é o motivo pelo qual
ter um retorno adiciona um pouco mais de
complexidade às coisas. E é por isso que eu apresentei o exemplo com um
parâmetro primeiro. Como isso não é redefinido toda vez que
temos um retorno,
sim, estamos definindo o retorno aqui e inicializando-o
em uma nova área da memória Mas precisamos lembrar de adicionar nossos resultados de
cada chamada recursiva,
toda vez que chamamos nosso
método recursivamente Agora, eu entendo que
isso é muito difícil de entender, é
super complicado. Mas eu, eu o dividi
em termos simples para você. Se você assistir a este tutorial,
talvez duas ou três vezes. E talvez forneça seus
próprios exemplos também. Você acabará
descobrindo e um dia ele simplesmente
clicará. Eu prometo que isso é recursão em C Sharp.
Não só C Sharp. A recursão está em muitas linguagens de
programação e até mesmo em matemática
e coisas assim Espero que você tenha gostado desse tutorial e obrigado por assistir.
79. 20-1. Projeto final (jogo de simulador de Top Trunks): Então, o projeto final. Qual é o projeto final? Bem, vamos dar uma olhada. O projeto final é opcional, mas eu recomendo que
você aplique todo o conhecimento que
aprendeu
até agora e faça uma tentativa sólida. Então você
ganhará oficialmente o título,
o título não oficial de C
Sharp Computer Programmer ou C Sharp Software Parece muito bom, não é? Então, para o projeto final, vamos simular
um jogo de melhores trunfos Agora, se você não está
familiarizado com os melhores trunfos, é basicamente um baralho de cartas E o baralho de cartas tem
como tema o que você quiser, na
verdade, o que você quiser comprar Por exemplo, você pode
ter dragões com criaturas
místicas
onde você tem magos, reis, dragões
e coisas assim Cada carta tem um personagem, este se chama
Dragon, por exemplo. E ele tem várias estatísticas,
como força, habilidade, poder
mágico sobre o fator medo. No entanto, se você comprar um
baralho com super-heróis, eles podem ter
algo totalmente diferente com nomes de
personagens diferentes Mas geralmente cada baralho
de cartas tem um tema. Ao criar sua
versão disso em C sharp, você pode escolher o
tema que quiser. O céu é o limite, basta usar sua imaginação para
saber como o jogo funciona. Bem, eu incluí uma especificação
completa que explica como
o jogo funciona, mas também algumas suposições que você pode adotar ao desenvolver
essa solução Vou
mostrar uma demonstração agora, mais ou menos sobre como funciona. Então, aqui está a
especificação aqui, não se preocupe, eu a incluí
em formato de texto, então consulte-a algumas
vezes ao
planejar seu projeto e como você vai
lidar com o cenário. Eu dou uma breve descrição
do que é. Eu forneci alguns links para que você possa fazer
mais pesquisas. Agora, este é um jogo para dois jogadores. Vamos assumir que há apenas dois
jogadores jogando E eu coloquei uma lista de
suposições que você pode fazer ao criar este projeto
apenas para torná-lo muito Eu realmente não quero que você
passe semanas e semanas nisso. Você pode, se quiser
, não tem problema algum. Mas acho que usando
essa especificação, você sabe, algumas horas
por dia durante mais ou menos uma semana, acho que é uma boa quantidade
de tempo para treinar seu conhecimento recente
e desenvolver um bom software
para mostrar a seus amigos, familiares ou quem você quiser
consultar a especificação sobre
como começar com isso Agora vou mostrar minha
solução sobre como
resolvi o problema para que
você tenha uma ideia de como ele funciona Então, quando o software
é executado pela primeira vez, presumimos que o
jogador 1 seja o primeiro O jogador 1 pode pressionar Enter
para começar seu turno. Agora é a vez do jogador 1. O jogador um tem cinco cartas e o jogador dois tem cinco cartas. Então, eles têm cinco cartas cada. Para que as cartas representem um personagem como um
dragão ou um rei, por exemplo,
algo assim. Aqui eu tenho personagens totalmente
aleatórios. Isso é, você sabe, o quão
boa é minha imaginação. Uma carta
ou personagem selecionado aleatoriamente da
minha mão é jogada,
e esse é o ursinho de pelúcia Agora, o ursinho de
pelúcia tem altura, peso, poder mágico
e fator medo Porque é um ursinho,
é bem pequeno, não
é muito pesado,
não tem habilidade mágica nem fator
de medo Então, na verdade, é
uma carta muito ruim. Agora, a ideia é
escolher a estatística mais alta aqui, e espero que meu oponente tenha uma estatística menor que
a Então, se eu escolher a altura, digamos 1 metro e 45. Então eu escolho o número
um aqui. Eu pressiono Enter. Em seguida, o jogador,
o outro jogador defende com Harry
Houdini, que é mágico Mas ele tem uma altura de 5,7, então o ursinho de pelúcia não é
mais alto Então, o ursinho de pelúcia perde porque a
altura do ursinho de pelúcia é de apenas 145 Mas Harry Houdini tem 57 anos.
O jogador dois vence. Mas como jogador contra um,
jogador dois pega a carta do
ursinho de pelúcia, o
jogador dois retém sua carta de
Harry Houdini E agora é a vez do jogador
dois. Então, se eu acertar Anton, agora você pode ver que o
jogador dois agora tem seis cartas porque
ganhou o ursinho de pelúcia Agora é a vez do jogador dois. O
personagem selecionado aleatoriamente é Picchu. Agora Picchu tem um poder
mágico muito bom, mas muito curto. E também é muito leve. E não há
muito fator de medo. Então, eu quero jogar o poder mágico porque é muito alto e
espero poder vencer a carta defensora do agora
jogador Então, vamos dar uma
olhada nisso. O outro jogador defende
com Darth Veda. Mas eu escolhi o
poder mágico, que era 75. No entanto, Darth Veda só tem um poder mágico de dois. Então eu ganhei. Eu ganhei novamente. Agora,
porque eu ganhei de novo, ainda
é minha vez. Então ainda é a vez do jogador dois. Agora você pode ver que eu
tenho sete cartas. O vencedor do jogo é a pessoa que tem todas as dez
cartas neste exemplo, porque há apenas dez cartas. Se você criar 20 cartas
, obviamente o vencedor ficará
com todas as 20 cartas. Agora, há muitas
suposições aqui. Você pode ver que estou selecionando
aleatoriamente personagens do baralho que
cada jogador tem Já quando você realmente
joga este jogo pessoalmente, você pega aquele que está no
topo do baralho. Então, estou usando muitas
suposições apenas para
encurtar o tipo de
vida útil Sabe, eu não, eu
realmente não quero que você trabalhe
nisso por 34 meses e
arraste seu cabelo Eu não acho que
será um primeiro e último
projeto muito divertido para você. Portanto, há
muitas suposições,
você sabe, não é
realmente obrigatório Adicione seu próprio toque.
Adicione seu próprio sabor. Depende muito de
você, obviamente, acabei de jogar Picature, e Piccature
foi selecionado novamente Então, você sabe, não é
um aplicativo perfeito, então não
se preocupe em ser perfeito. É só para treinar seu
conhecimento e coisas assim. Então, é um pouco
divertido e acho que você vai se
divertir muito com isso aqui. Temos o minidiabo, somos o fator quatro do medo. Estamos indo muito bem.
Temos nove cartas agora temos o poder mágico de Harry
Houdini E parece que
ganhamos o jogo. O jogador dois teve todas as dez cartas totalmente destruídas, o jogador um. Queremos jogar de
novo? Sim ou não? Se eu pressionar não,
agradeço por jogar. Pressione Enter para sair. Esse é o projeto final. Novamente, não é a solução, é apenas uma solução. Você pode fazer o que quiser com
os personagens que quiser, mas tente aplicar muitas
das coisas que realmente
abordamos no curso. Então, aqui eu criei, no lado direito aqui, eu criei quatro classes
personalizadas. Aqui, eu os coloquei em
um projeto separado. E quando eu abro o método principal aqui na classe do programa, você pode ver que não há
muito código aqui. Isso porque nós o
separamos em,
você sabe, contêineres lógicos. Eu tenho uma classe de
controle de jogo que gerencia tudo o que tem a ver com
o jogo, os turnos e
tudo mais. Eu tenho uma classe de jogadores agora, os jogadores, ela
modela os jogadores. E um jogador tem
vários personagens ou cartas. E o personagem
ou classe de cartas é responsável por todos os
personagens do jogo. Assim, você pode ver como estamos usando o conhecimento que
aplicamos. Onde fazemos uma aula
e essa turma é responsável por tudo o que tem
a ver com o que é chamada. Portanto, a classe do personagem
lida com os personagens, o controlador do jogo
lida com o funcionamento do jogo, etc Então é assim que realmente funciona. Estamos pegando todo
o conhecimento que
adquirimos e o estamos aplicando agora. Então essa é basicamente a minha solução para o projeto final. Você sabe, Planet Planet. Use alguns blocos de notas.
Use um pouco de papel. Use uma caneta. Pense bem em como você vai
resolver o problema, como você vai
organizar o problema e quais técnicas
você vai usar, quais ciclos, condições
e coisas assim Espero que você se divirta com isso. O projeto final testa
seu conhecimento sobre muitos conceitos das coisas que
abordamos até agora. Portanto, classes, objetos,
instanciação, instruções
if, instruções
switch, condições booleanas e Quatro loops, laços de arame, muitos loops,
métodos diferentes e Portanto, é uma ótima maneira de
pegar todo esse conhecimento e aplicá-lo a um único
software. Quanto tempo levará o projeto
final? Bem, se você gosta de programar e quer ser programador
, isso não deve
ser uma preocupação, porque a prática é
sempre uma coisa boa Se você é totalmente iniciante
quando começou este curso, talvez passe
algumas horas por
dia durante mais ou menos uma semana,
algo assim Como qualquer outro idioma,
francês, alemão, espanhol. Você não vai absorver todas as informações
de uma só vez. Simplesmente não é realista. Mas use os materiais do curso
como ponto de referência para
o projeto final. Se você está desenvolvendo
seu projeto final e não consegue se lembrar de
como fazer um loop de arame, por exemplo, basta assistir novamente
ao tutorial
do loop de arame para relembrar Até mesmo programadores de
computador profissionais usam o Google e vários outros
sites como ponto de referência
e, às vezes, fazem isso A programação diária
consiste em pensar fora da caixa e aplicar o pensamento lateral e
lógico. Não se trata de lembrar a sintaxe e regurgitar a sintaxe,
então não se deixe intimidar então não se deixe intimidar Por isso, incluí minha solução
para o projeto final, mas recomendo fortemente
que você simplesmente não a use. Não olhe para ele até
terminar o seu. Então você pode usá-lo
como um ponto de referência para talvez, talvez, melhorar o seu. Ou veja as diferenças entre minha solução
e sua solução. Lembre-se de que não há uma
solução para um problema. Pode haver várias soluções e todas elas estão corretas. Mas use-o apenas como
um ponto de referência ao concluir
seu projeto final. Envie para seus amigos.
Envie para sua família. Faça o upload para o Youtube, por
exemplo. E me mande o link. Eu adoraria ver seus projetos
finais e como você interpretou essa
especificação e deu seu próprio toque A última coisa que quero dizer é: boa sorte com o projeto
final e boa sorte para seus futuros empreendimentos de
programação Finalmente, obrigado. Muito obrigado por
assistir Take care.
80. 20-2. Resumo do programa (de onde eu vou a partir daqui?): Agora, todas as coisas boas
devem chegar ao fim. Mas se você chegou até aqui
, obrigado por assistir. Se você tiver alguma dúvida,
problema, imperfeição dúvida sobre qualquer conteúdo de todo o curso, deixe uma mensagem no conteúdo em si ou me
envie Ficarei mais do que feliz em ajudar também
a revisar os
arquivos de projeto anexos, se você ainda não o fez A maioria das aulas deste
curso inclui arquivos de
projeto e
sinta-se à vontade para expandi-los, aprender com eles, mas também
adicionar seu próprio toque a O limite é sua imaginação. A grande pergunta que muitas pessoas geralmente têm depois
de terminar um curso é onde eu vou a partir daqui? Bem, eu não vou
deixar você esperando. Muitas pessoas fazem isso, mas eu
vou te dar algumas ideias. Depende de quais são
seus objetivos. Quais são seus objetivos? Eles são exclusivos para você, eles são
pessoais para você. Por exemplo, talvez você esteja
procurando emprego. Você quer ser contratado por alguém. Ou talvez seja um hobby. Talvez você queira criar um aplicativo de telefone
para ganhar dinheiro. Ou talvez você queira
criar videogames no Unity ou apenas experimentar
um novo desafio. Algo totalmente novo.
Então, isso depende. Mas o segredo e o
terreno comum com tudo isso é prática,
prática, prática. C sharp não é muito
diferente de uma língua falada real, como francês, alemão ou
português, por exemplo Quanto mais você o usar, melhor você se tornará. É simplesmente natural.
E da mesma forma, quanto menos você
o usar, mais você esquecerá. Portanto, em seu tempo livre,
recomendo criar pequenos
aplicativos de software para resolver seus problemas diários e
facilitar sua vida. Além disso, também é
muito divertido. Eu criei vários softwares
diferentes
apenas para facilitar minha vida. Por exemplo, eu fiz um renomeador de música quando
tenho o iTunes, por exemplo Às vezes, ele não
usa o nome do arquivo, mas uma tag oculta dentro
do MP três, por exemplo. Então, criei um software
para injetar essa etiqueta
no MP três para que meu iTunes tenha uma aparência muito boa
e tudo seja automatizado Eu não preciso, você sabe, renomear cada música para
dar a ela o
artista ou título correto Por exemplo, isso é
muito fácil
de fazer com muitas das ferramentas
e técnicas que
abordamos neste curso. Coisas como quando itens gratuitos aparecem no Craigslist
ou coisas assim, eu posso tocar Então, sempre que alguém está dando
algo de graça, meu laptop começa a tocar música E então eu sei que algo
novo está na seção gratuita e posso entrar em
contato instantaneamente com o comprador e, você sabe, providenciar a
coleta disso. Você sabe, o limite
é sua imaginação. E, por fim, criei
um carregador em massa do Youtube. O que acontece é que, se você tem
talvez dez ou 50 vídeos, deseja fazer o upload para o Youtube, mas não quer digitar todos os títulos, descrições
e coisas assim. Então, criei um aplicativo
em que posso gravar 50 vídeos, por exemplo, arrastá-los e
soltá-los no software. E preenche o
título e a descrição do vídeo e até mesmo as tags do
nome do arquivo de vídeo E isso economiza muitas horas. E isso é na verdade um
software comercial agora. Portanto, ele não apenas pratica
minhas habilidades de programação, mas também ganha
dinheiro extra Portanto, há muitas ideias
que você pode, você sabe, adotar e aplicar em
seus próprios cenários específicos. Outra coisa que você pode fazer,
que é muito, muito boa, é fazer testes de codificação on-line, como pequenos desafios de codificação Então, por exemplo, há
dois sites que você pode usar. Um se chama Hacker Rank e o outro se
chama Lite Code Eu vou te mostrar esses agora. Agora, cada um deles tem muitos desafios
de codificação diferentes, assim como eu apresentei projeto final com
o melhor simulador de trunfos Mas, normalmente,
eles são muito mais fáceis. Por exemplo, desenhe uma pirâmide, que abordamos
neste curso, ou desenhe um quadrado ou encontre a
rainha, coisas assim Desafios tão rápidos que
testam seu pensamento lateral, que é pensar
fora da caixa. Portanto, eles não apenas testam seu
conhecimento de C Sharp e talvez sua memória da
sintaxe, mas, mais importante, sua aplicação de um Sharp Quando você
enfrenta um problema, ele testa como seu cérebro funciona, como você entende o
problema e encontra uma solução Normalmente, esses desafios são muito únicos e muito específicos. Você realmente não pode pesquisá-los no Google e encontrar uma solução, por exemplo. Portanto, se você pratica
muito esses desafios de
codificação e
aprimora sua capacidade de resolvê-los, melhorando seu pensamento lateral
, isso o tornará muito atraente para
potenciais empregadores Os empregadores não
procuram pessoas que possam regurgitar e
lembrar a sintaxe Eles procuram pessoas e
incentivam o pensamento lateral. E esses
testes de codificação on-line são perfeitos para isso. Além disso, esses dois
sites que eu sugeri rastreiam quais exercícios
você já resolveu. E eles criam um perfil
como um pequeno quadro de líderes. Você sabe quais
resolveu. E não vejo nenhum
problema em imprimir isso ou enviá-lo
para um potencial empregador. Então, eles podem realmente ver
quais desafios você enfrentou. E eles podem ver que, você sabe, não
é apenas uma carreira que você pode querer ou um emprego que você realmente
goste de fazer isso. E é isso que
eles procuram e é
isso que separa
você das outras pessoas E, novamente, não se
trata apenas de conseguir um emprego. Até mesmo pessoas amadoras adoram
esses desafios de codificação. Você sabe, isso realmente
funciona no seu cérebro. É um
exercício de treinamento muito bom para sua mente, então eu recomendo testes de codificação
on-line Mais uma coisa que você pode fazer é praticar exemplos de perguntas da
entrevista de emprego, mesmo que não esteja planejando
se tornar empregado. Porque eles realmente testam seus
conhecimentos e
o irritam quando você remove este
curso do seu laptop,
por exemplo, digamos que você o cubra mão ou com um livro e realmente se pergunte:
o que é polimorfismo Você pode responder a essa
pergunta sem consultar
este curso ou pesquisá-lo no Google, por
exemplo? Isso é possível? E se eu perguntasse a você, o que é
sobrecarga de métodos ou o que quero dizer quando digo classe abstrata
ou abstrata E o que é encapsulamento e como isso difere de,
você sabe, outro termo? Você pode responder honestamente a
essas perguntas? Então é assim que você
realmente se testa, se entende
os princípios. É fácil ver
alguém falar sobre
algo e dizer, oh, ok, sim, eu entendo. Mas se você cobrir o material com a mão e
escondê-lo da sua vista, você
pode dizer honestamente,
ok, polimorfismo Então, uma coisa é ler algo e
entendê-lo, mas outra coisa é
recitá-lo com suas próprias palavras E isso é muito importante
não apenas para conseguir um emprego, mas também para realmente entender tudo o que é abordado
neste curso. Então, eu recomendo
fazer isso também. Então, a última coisa que
vou mencionar em termos do que
devo fazer a seguir por que você fez este curso. Algumas pessoas podem ter feito esse curso para
passar para outra coisa. Talvez você quisesse fazer desenvolvimento de
jogos em Unity. Talvez você quisesse
desenvolver sites, então precisasse saber o que é preciso. Então você pode aprender o
Spot Net, por exemplo. Ou talvez você
queira criar formulários para um aplicativo de desktop ou
móvel. Você pode aplicar o sharp a
todos esses cenários, mas eles exigem mais
conhecimento para cumprir com êxito a função ou realizar o que você deseja fazer. Mas em termos de conhecimento,
compreensão e prática em C sharp, este curso será muito
útil para essas aplicações. Posso dizer que 100% se você quiser começar a
criar jogos no Unity, descobrirá que
conhece praticamente
todo o C sharp. Você precisa saber, ou
pelo menos saber como procurar e pesquisar novos métodos
e classes que deseje usar. Qualquer conhecimento necessário para
criar videogames no Unity
evoluirá em torno da compreensão e do aprendizado do motor Unity, por exemplo, o que
é muito diferente Mas em termos de C Sharp, você está novamente preparado para
criar aplicativos móveis. O C sharp já abordado Talvez você só precise aprender algumas coisas gráficas ou de nicho a fazer com aplicativos móveis. Então, novamente, este curso de
loja virtual será a base perfeita para
tudo o que você deseja alcançar Seja qual for seu objetivo final. Então, a última coisa que
vou dizer é, novamente,
muito obrigado por assistir. Não se esqueça de compartilhar seus projetos finais comigo se desejar realizá-los Se você tiver alguma dúvida, me
mande uma mensagem
e deixe um comentário. E me diga como foi
o curso para você. E talvez em cinco
a dez anos,
quando você for um desenvolvedor de
software profissional, talvez você possa me enviar uma mensagem e me dizer
como você está se saindo e me dizer se esse curso o ajudou
a longo prazo. Vou criar mais cursos, então fique à vontade para
conferi-los pela última vez. Muito obrigado por
assistir Take care.