Alura > Cursos de Programação > Cursos de .NET > Conteúdos de .NET > Primeiras aulas do curso Novidades do C# 7.3: igualdade em tuplas, expression variables e refs

Novidades do C# 7.3: igualdade em tuplas, expression variables e refs

Tuples - Introdução

Olá, bem-vindo a mais um curso aqui na Alura e esse é um curso sobre o C#, aqui vamos falar as melhorias e as novidades da versão 7.3 do C# e aqui vamos começar falando sobre tuples, tuples é um recurso já existente e veio uma melhoria aqui nessa versão, que é a operação de igualdade entre tuples.

Que vamos ver com detalhes como que isso funciona, como isso é implementado, qual é o resultado do compilador quando escrevemos um código desse tipo, com igualdade entre tuples e vamos entender também alguns casos de borda onde esperamos um resultado, e na prática acabamos tendo outro, vamos entender certo como funciona isso aqui dentro dessa nova versão da linguagem.

Vamos falar também sobre as melhorias em re-atribuição de variáveis de referência, então se você não se recorda o que é uma variável de referência, aqui vamos lembrar, vamos passar um pouco por cima sobre esse assunto e vamos ver como que esse recurso melhorou aqui nessa versão do C#, vamos falar sobre expression variables, que é um assunto bem interessante também, sobre como eu posso criar variáveis em lugares que o código normalmente espera expressões.

Por exemplo quando eu estou invocando um método, vamos ver como que melhorou aqui no C# 7.3, vamos falar sobre backfield atributes, que é uma forma diferente que tem algumas peculiaridades de como definir atributos para membros de uma classe e vamos terminar o curso falando sobre resolução de sobrecarga, o que é uma resolução de sobrecarga? É quando o compilador sabe qual sobrecarga de um método eu estou querendo invocar.

E existiam algumas inconsistências no C# até a versão 7.3 que houveram algumas melhorias e vamos aprender como que o compilador ficou um pouco mais esperto na hora de escolher a melhor sobrecarga de um método para invocar e como eu tenho mais liberdade para escrever o meu código com esses novos recursos, lembrando e para reforçar que esse daqui é um curso sobre a linguagem do C#, então não vamos trabalhar especificamente em cima do projeto que vamos ficar melhorando ele, vamos ver vários recursos de forma separada.

E vamos contar com apoio do sharplab, com o sharplab eu vou conseguir escrever o código que é o código que vai estar lá no meu repositório, é o código que eu vou escrever lá no meu trabalho, no meu projeto DOT NET e eu vou ver aqui o resultado do compilador eu vou ver o que o compilador vai gerar com base no código que eu escrevi e vamos entender com bastante detalhe, bem refinado, como que o compilador ele vai enxergar o código novo, como que ele vai usar esses recursos que vieram com a versão 7.3

Então temos bastante exemplo para você, vamos ver bastante caso de borda, vamos ver tudo com bastante detalhe. Esse curso aqui na Alura é um prato cheio para você, meu nome é Guilherme e eu espero você na primeira aula.

Tuples - Igualdade entre tuples

Bem-vindo à esse curso e vamos começar, eu já tenho aqui o Visual Studio aberto, estou usando o Visual Studio 2019 e eu já criei um projeto aqui para darmos andamento nele, e o que eu já fiz nesse projeto? Eu não fiz muita coisa, eu criei uma solução chamada “C#73” 73 de 7.3, para vermos os recursos e tem um projeto aqui dentro.

Eu vou abrir aqui o “Csproj” para você dar uma olhada, e esse xml de configuração do Visual Studio, o computador conseguir compilar esse projeto e como eu criei ele? Eu estou usando a versão do DOT NET core 2.1, na versão 2019 do Visual Studio o padrão vai ser DOT NET core 3, aqui eu coloquei 2.1 e o lang version, a versão da linguagem eu coloquei 7.2.

Mas porque você colocou 7.2 se o curso é do 7.3? Eu coloquei aqui 7.2 que é para ficarmos comparando, vamos escrever um código, esse código aqui não está funcionando, como que podemos melhorar ele e vamos trocar para versão 7.3 e ver como que podemos usar dos aprimoramentos feitos nessa versão da linguagem, então, agora que vemos um pouco do ambiente, vamos começar a escrever código?

Esse curso, nessa primeira aula, vamos começar falando sobre tuples, esse recurso nasceu na linguagem na versão 7, então vamos relembrar como que é? Para deixar mais organizado, aqui na raiz do projeto, eu vou criar um arquivo chamado teste tuples, então eu vou criar aqui uma classe, só para ficar organizado, eu vou criar essa classe com estática, static class, não precisamos criar uma instância e vamos lá relembrar como que são as tuples.

Então eu vou criar um método público, um “public static void TestaTuple()” e vamos começar, para mostrar como caso aqui no nosso teste de tuple, vamos pensar que eu sou uma pessoa que eu quero descobrir um trajeto, seja para pegar um ônibus ou um trajeto GPS de um ponto de origem até um ponto de destino, então quero me locomover dentro da cidade, então eu preciso ter uma origem.

Então uma forma de representarmos essa origem que seria o que por exemplo? Seria a rua, seria o número e a cidade, poderíamos criar uma classe e definir essas propriedades, mas se eu tenho um lugar bem pontual no meu código que eu vou usar uma estrutura bem temporária, ou seja, não é uma classe rica de modelo, eu posso usar esse recurso de tuples.

Então vamos relembrar como ficaria o nosso exemplo de origem, o endereço de origem, então eu vou criar uma “var origem =” e eu abro um parênteses e dentro desse parênteses eu coloco os valores da minha tupla, então a minha origem é a avenida paulista, o número 900 e a cidade é São Paulo, e agora quero colocar o meu destino, então “var destino = “ e na verdade eu não vou andar muito, eu vou até copiar e colar aqui, pronto.

Meu destino também é avenida paulista, São Paulo, eu só vou trocar o número para não ser o mesmo lugar, então eu já tenho a origem e o destino e eu estou usando aqui tuples dentro do C#, agora antes de fazer qualquer cálculo de rota, antes de procurar ônibus, antes de procurar mapa para GPS, o ponto de partida natural para começarmos a escrever esse código é ver se a origem e o destino são lugares diferentes.

Então, eu quero fazer essa comparação aqui, “var mesmoLugar = “ e agora vamos comparar origem com destino, então “origem == destino;” e olha só, aqui o compilador não gostou, falou que você não pode comparar 2 tuples, então como que fica esse mesmo lugar? E lembrando aqui eu estou mostrando 7.2, aqui eu não estou mostrando como funciona o C# novo, vamos ver como podemos melhorar esse código.

Mas até a versão 7.2, esse código aqui ele não é valido, o que temos que fazer é colocar “origem.Item1 == destino.Item1 && origem.Item2 == destino.Item2 && origem.Item3 == destino.Item3;”, agora temos um código que compila, mas está ruim, eu posso até tentar deixar um pouco mais bonito esse código, quebrar a linha assim, mas de qualquer forma o código continua estranho.

Eu vou escrever aqui na tela “Console.Writeline(mesmoLugar);” só para vermos rodando e eu vou colocar essa chamada dentro do nosso program, então vou colocar aqui “TesteTuples.TestaTuples()”, salvei, vou executar e o resultado aqui false, como era esperado, afinal o número aqui do nosso destino e da nossa origem são diferentes, 900 contra 300.

Agora vamos usar o recurso do C# 7.3 que torna esse código muito mais legível, então eu vou comentar esse código aqui e eu vou criar essa variável “var mesmoLugar” usando o C# 7.3 que é só “origem == destino;” o compilador não gostou, mas lembra que aqui no projeto eu coloquei LangVersion 7.2? Agora eu vou trocar para 7.3, troquei, salvei e agora no teste tuples o código ele volta aqui a compilar.

E eu executo a aplicação só para provar que está funcionando e está aqui como false, e vamos testar então? Então esse daqui é um melhoramento bem pontual que já deixa o nosso código muito melhor, muito mais fácil de ler e podemos usar tuples com muito mais tranquilidade, porque sabemos que não vamos cair em nenhum caso desse daqui em que eu vou ter que parar item por item e ficar com esse texto gigante aqui na tela.

Vamos aproveitar essa oportunidade, que acabamos de conhecer esse recurso novo aqui da linguagem e vamos ver como que funciona de baixo dos panos, como que o compilador transforma esse código que eu tenho aqui na minha tela, para o código que esperamos, que é a comparação do item1 com o item1 do outro lado, item2 com item2 do outro lado e todos os itens dessa tupla, então eu vou copiar aqui, copiei o código que acabamos de criar.

E para vermos o que o compilador enxerga desse código, eu vou abrir o sharplab.io, o sharplab ele é um projeto desenvolvido para conseguirmos ver essas diferenças do C#, a versão mais nova do C#, compilando código e como que o DOT NET enxerga, então desse lado esquerdo aqui eu tenho o editor de texto onde eu escrevo o meu código C# tradicional e aqui do lado eu tenho ele compilado, mas ele compilado e depois transformado em C# novamente, então nesse lado direito aqui temos o que o DOT NET enxerga do nosso código.

E se você quiser usar mais, eu gosto muito do sharplab.io, aqui em results você pode ver a versão decompilada do C#, em IL que é a linguagem intermediária, aquela linguagem que não é linguagem de máquina, mas é a linguagem da máquina virtual do DOT NET e tem a linguagem de máquina mesmo, que é esse JIT Asm, aqui temos o assembly, voltei aqui para o C#, vamos voltar para o nosso exemplo.

Então eu tenho aqui origem, destino e vamos lá, “var mesmoLocal = origem == destino;” agora vamos ver como que o C# o DOT NET enxerga o nosso código, então aqui está um pouco apertado para vermos, o que eu vou fazer é copiar esse código aqui e colar em um bloco de notas para vermos melhor, então aquele var origem e aquele var destino, o que ele é? Como ele é dentro do DOT NET, ele é esse tipo value tuple, então é um tipo genérico de 3 valores, porque 3 valores?

3 valores porque aqui no nosso código só estamos usando 3 valores para essa tuple, então o tipo do DOT NET que o compilador vai usar é esse com 3 argumentos genéricos, mais esse tipo value tuple, ele já existe dentro do DOT NET, o compilador só transforma o nosso código para fazer uso desse tipo.

Então temos aqui a chamada do construtor, e aqui a comparação que o DOT NET, o compilador está chamando de flag, ele faz exatamente aquele código que escrevemos e que escrevíamos até a versão 7.2, “item1 == item1”, “item2 == item2”, “item3 == item3”, então isso aqui é um açúcar sintático que o C# 7.3 nos trouxe.

Tuples - Igualdade entre tuples nomeadas

Então isso daqui é o código que escrevemos no vídeo anterior, só para melhorar um pouco, eu vou mudar esse nome desse método de “TestaTuple” para “TestaIgualdade” que é o que estamos fazendo aqui, estamos testando a igualdade do C# 7.3 e eu quero continuar com esse exemplo, então eu vou copiar e vou colocar aqui, por enquanto eu vou chamar de “TestaIgualdade2” e vou continuar chamando dentro desse método.

Eu tenho aqui a origem e eu tenho o destino, para o caso da igualdade, tudo bem, eu não preciso me preocupar em como foi construído esses tuples porque eu posso colocar direto, “origem == destino”, agora o que acontece se eu quero saber por exemplo o nome da rua do meu endereço de origem? Então eu vou guardar isso em uma variável, “var ruaOrigem” como eu acesso isso? Vou ter que colocar “origem.” e quando eu coloco ponto o Visual Studio já me sugere, item1, item2 ou item3 ?

Agora é fácil, agora que acabamos de escrever sabemos qual item que está o nome da rua, é o item1, colocamos aqui no primeiro item dessa tupla, mas será que daqui a 2 meses, eu, você, vamos olhar para esse código, vamos ter que dar manutenção, será que vamos lembrar fácil que o item1 é o nome da rua? Ou será que vamos ter que voltar para definição desse origem aqui e ver como ele é construído e lembrar, estou vendo aqui pelo valor, então de fato, item1 parece que é a rua.

Então aqui não é muito legal, mas uma coisa que nasceu no C# 7, é que podemos nomear os itens aqui das nossas tuplas, então eu vou começar de novo, só que eu vou nomear esses campos, só para relembrarmos “var oirgem =” e eu vou criar aqui a sintaxe de tupla, só que eu vou colocar o nome dos campos que a minha tupla vai ter, então posso colocar “(rua: “Avenida Paulista”, numero: “900”, cidade: “São Paulo”)”, nada novo.

Agora eu vou fazer aqui o destino, “var destino”, destino eu quero que seja nomeado, então temos aqui o “(numero: “900”, rua )”, para facilitar eu vou copiar aqui a rua e a cidade, aqui eu coloquei igual, tanto a origem quanto destino são iguais, então vamos ver como que fica dentro do C# 7.3 dentro dessa comparação, já sabemos que até então no 7.2 como faríamos? O “var mesmoLugar” ele seria “origem.item1”, espera, agora não é item1, nós nomeamos o item da nossa tupla, como nomeamos, acessamos pelo nome.

Então fica “origem.rua == destino.rua $$ origem.numero = destino.numero;” enfim, assim por diante, já vimos como que é essa passagem, já vimos como que isso é chato, eu vou usar aqui o recurso do C# 7.3, “mesmoLugar = origem == destino” e aqui estamos vendo que a rua é igual ao outro, o número é igual um ao outro, e a cidade aqui em último também.

Então eu salvei esse arquivo, eu vou fazer essa chamada aqui no program, o que esperamos é que esse “Console.WriteLine” dê true, eu vou executar e aqui o resultado não foi exatamente o que esperávamos, o resultado aqui foi false, mas o que aconteceu? Eu vou até fechar aqui, o que aconteceu? Se todos os itens eles são iguais, a rua é igual, o número e cidade também.

Para vermos melhor isso daqui eu vou copiar esse código e eu vou colocar lá no nosso amigo o sharplab, então voltei aqui no sharplab, colei aqui o mesmo código e vamos ver como que ele é compilado, como que o DOT NET enxerga esse código, tenho aqui o código, vou só copiar e colar dentro do bloco de notas, novamente para criar essas tuples usou-se o tipo do DOT NET “value tuple” de 3 argumentos genéricos.

E aqui o construtor, Avenida Paulista, 900, São Paulo, como esperamos. E a comparação? A comparação ela é feita daquela forma tradicional e aqui não tem nenhuma menção, nenhuma referência para aqueles nomes que nós criamos, não tem “.rua”, não tem “.numero”, não tem “.cidade”, só tem item1, só tem item2, só tem item3, e esses itens eles são definidos de acordo com a ordem que os nossos valores são definidos dentro da nossa tupla.

Então vou voltar aqui no Visual Studio, por mais que eu usei o nome “rua” para definir esse campo, na origem e no destino a posição desse item está diferente, na origem, o primeiro item, o item1 é a rua, agora no destino o item1 é o número, e esses nomes, rua, número e cidade, isso não existe, isso daqui não é representado dentro do código compilado.

O código compilado está usando aquele tipo do DOT NET, esse rua, número e cidade são nomes que utilizamos para ficar mais fácil de escrever o código aqui dentro do Visual Studio, por exemplo, eu coloco ponto e ele oferece para auto completar, número, rua e cidade, mas isso daqui não vai para o código compilado, para o código compilado vai ter item1, item2 e item3, isso daqui é uma consequência do açúcar sintático que estamos usando.

Então temos que tomar um pouco de cuidado quando formos usar esse recurso do C# 7.3, porque essa comparação por mais que estejamos usando o nome “rua” aqui nos dois lugares, quando aplicamos o operador de “==” ele vai comparar de acordo com a posição dos meus valores, então talvez na sua empresa você tenha aquele jeito antigo, que é comparar “origem.rua” “destino.rua”, “origem.numero” “destino.numero” só que na rua de você usar esse recurso do C# 7.3 você pode ter esse tipo de problema.

E aqui, note que eu estou usando o número como uma string, seria mais natural usar esse valor como um inteiro, então eu posso transformar aqui esse valor em inteiro, salvei aqui, e agora que eu mudei o tipo, olha só, a comparação para de valer, porque ele compara de acordo com a posição dos meus itens dentro da tupla e o meu primeiro item aqui na origem é uma string, enquanto que o meu primeiro item aqui no destino é um inteiro e eu não posso aplicar o operador de igualdade entre uma string e um inteiro.

Então aqui só um ponto de atenção, na hora que formos utilizar esse recurso em um código que já está em produção.

Sobre o curso Novidades do C# 7.3: igualdade em tuplas, expression variables e refs

O curso Novidades do C# 7.3: igualdade em tuplas, expression variables e refs possui 130 minutos de vídeos, em um total de 29 atividades. Gostou? Conheça nossos outros cursos de .NET em Programação, ou leia nossos artigos de Programação.

Matricule-se e comece a estudar com a gente hoje! Conheça outros tópicos abordados durante o curso:

Aprenda .NET acessando integralmente esse e outros cursos, comece hoje!

Plus

  • Acesso a TODOS os cursos da plataforma

    Mais de 1200 cursos completamente atualizados, com novos lançamentos todas as semanas, em Programação, Front-end, UX & Design, Data Science, Mobile, DevOps e Inovação & Gestão.

  • Alura Challenges

    Desafios temáticos para você turbinar seu portfólio. Você aprende na prática, com exercícios e projetos que simulam o dia a dia profissional.

  • Alura Cases

    Webséries exclusivas com discussões avançadas sobre arquitetura de sistemas com profissionais de grandes corporações e startups.

  • Certificado

    Emitimos certificados para atestar que você finalizou nossos cursos e formações.

  • Alura Língua (incluindo curso Inglês para Devs)

    Estude a língua inglesa com um curso 100% focado em tecnologia e expanda seus horizontes profissionais.

12X
R$85
à vista R$1.020
Matricule-se

Pro

  • Acesso a TODOS os cursos da plataforma

    Mais de 1200 cursos completamente atualizados, com novos lançamentos todas as semanas, em Programação, Front-end, UX & Design, Data Science, Mobile, DevOps e Inovação & Gestão.

  • Alura Challenges

    Desafios temáticos para você turbinar seu portfólio. Você aprende na prática, com exercícios e projetos que simulam o dia a dia profissional.

  • Alura Cases

    Webséries exclusivas com discussões avançadas sobre arquitetura de sistemas com profissionais de grandes corporações e startups.

  • Certificado

    Emitimos certificados para atestar que você finalizou nossos cursos e formações.

  • Alura Língua (incluindo curso Inglês para Devs)

    Estude a língua inglesa com um curso 100% focado em tecnologia e expanda seus horizontes profissionais.

12X
R$120
à vista R$1.440
Matricule-se
Conheça os Planos para Empresas

Acesso completo
durante 1 ano

Estude 24h/dia
onde e quando quiser

Novos cursos
todas as semanas