Você já codifica .NET 8 de verdade ?

Marcio Nizzola
5 min readJun 6, 2024

--

Você já usa novidades que o .NET nos trouxe? Comece a entregar código usando novas features !

Sempre que novas versões .NET chegam, muitas coisas vem sendo simplificadas ao longo do tempo, algumas já são aceitas na hora, outras aos poucos, mas quem é que gosta de ficar escrevendo à toa?

Trago aqui algumas mudanças que visam simplificar nossa escrita de código no dia a dia e dar maior performance no nosso trabalho, além de simplificar o código que produzimos, facilitando a leitura !

Aqui vão então 4 itens que achei interessantes utilizarmos nos nossos projetos a partir de agora:

Aliases

O uso de aliases (apelidos) no C#12 veio para facilitar a escrita, permitindo que façamos uso não só de namespaces, mas de tipos específicos e métodos.

//declaração
using Point = System.Drawing.Point;
using Point3D = System.Numerics.Vector3;
using GeoPoint = (decimal latitude, decimal longitude);

//utilização
Point p = new Point(10, 20); // Point
Point3D p3 = new Point3D(10, 20, 30); // Point3D
var place1 = new GeoPoint(23.9999m, 28.4444m);

Veja neste exemplo uma utilização prática, onde foram definidos 3 apelidos, sendo dois para tipos de dados, e um para um combinado de dois tipos diferentes.

Isso permite facilitar a utilização, principalmente no segundo modelo, onde não precisamos criar uma classe ou record para agrupar as propriedades de geolocalização.

Arrays inline

“Arrays inline” são um novo recurso do C# 12 que nos permite criar uma matriz sem usar a palavra-chave new ou especificar o tamanho da matriz. Podemos usar a sintaxe [e1, e2, e3, etc.] para criar um array de qualquer tipo. O compilador descobrirá o tipo e o tamanho do array a partir dos elementos.

Nas versões anteriores do C#, você tinha que usar a palavra-chave new e especificar o tamanho do array sempre que quisesse criar um array.

Veja como era antes:

int[] lista1 = new int[3] {1, 2, 3};
string[] lista2 = new string[3] {"a", "b", "c"};
object[] lista3 = new object[2] {a, b};

E veja agora com “array inline”

var lista1 = [1, 2, 3]; // 3 elementos inteiros
var lista2 = ["a", "b", "c"]; // 3 elementos string
var lista3 = [a, b]; // 2 elementos do tipo objeto

Array de 2 dimensões

//definindo as linhas individualmente
int[] linha0 = [1, 2, 3];
int[] linha1 = [4, 5, 6];
int[] linha2 = [7, 8, 9];
int[][] arrayMulti = [linha0, linha1, linha2];

//direto em uma só linha
int[][] arrayMulti2 = [[1, 2, 3], [4, 5, 6], [7, 8, 9]];

Como eu prefiro a simplicidade, creio que esta mudança pode cair no gosto dos desenvolvedores, deixando códigos mais simples e rápidos de escrever !

Construtores primários

Os construtores primários são uma nova propriedade das classes no C# 12, onde podemos declarar parâmetros do construtor diretamente na declaração da classe e assim dispensar a necessidade de criar um construtor tradicional.

Exemplo 1 : propriedades atribuídas com cálculos

public class NotaBimestralModel(decimal nota1, decimal nota2, decimal nota3)
{
public decimal Media => (nota1 + nota2 + nota3) / 3;
}

Um detalhe importante: a atribuição do valor se deu utilizando os parâmetros passados no construtor, utilizando o símbolo “=>”.

Exemplo 2: classe comum

public class ProdutoModel( int codigo, string descricao, string unidade, decimal custo, decimal preco, string imagem, decimal estoque)
{
[Key]
public int Codigo { get; set; } = codigo;
[MaxLength(50, ErrorMessage = "O tamanho máximo é de 50 caracteres")]
[DisplayName("Descrição")]
public string Descricao { get; set; } = descricao;
[MaxLength(2, ErrorMessage = "O tamanho máximo é de 2 caracteres")]
public string Unidade { get; set; } = unidade;
public decimal Custo { get; set; } = custo;
public decimal Preco { get; set; } = preco;
public string Imagem { get; set; } = imagem;
public decimal Estoque { get; set; } = estoque;
}

Exemplo 3: Classes com herança

Classe pai

public class PessoaModel( int id, string nome, DateTime dataDeNascimento)
{
public int Id { get; set; } = id;
public string Nome { get; set; } = nome;
public DateTime DataDeNascimento { get; set; } = dataDeNascimento;
}

Classe filha

public class AlunoModel(int id, string nome, DateTime dataDeNascimento, 
string ra, int serie) : PessoaModel(id, nome, dataDeNascimento)
{
public string RA { get; set; } = ra;
public int Serie { get; set; } = serie;
public int Idade => DateTime.Now.Year - DataDeNascimento.Year;
}

Observa-se que assim como anteriormente era feito, declaramos a classe pai, com a diferença que os atributos do seu construtor são passados já na declaração.

Outro ponto também é que a propriedade “Idade” foi calculada automaticamente utilizando o parâmetro passado no construtor, utilizando o símbolo “=>”.

Mas tem uma triste notícia, não podemos utilizar este recurso em entidades que serão base para a modelagem do Entity Framework Core !

Ele exige que seus tipos de entidade tenham um construtor sem parâmetros. Isso ocorre porque o EF Core usa reflexão para criar instâncias de suas entidades ao consultar no banco de dados.

Por enquanto….

Parâmetros Opcionais em expressões Lambda


Func<int, int, int> add = (x, y) => x + y; // omitindo os tipos x e y
Func<int, int> square = x => x * x; // omitindo o tipo de dado
Func<int, int> increment = _ => _ + 1; // omitindo até o nome do parâmetro

Outros exemplos

using System.Runtime.InteropServices;

Console.WriteLine("***** Testes com C# 12 | Valores default em Lambda Expressions *****");
Console.WriteLine($"Versao do .NET em uso: {RuntimeInformation
.FrameworkDescription} - Ambiente: {Environment.MachineName}- Kernel: {Environment
.OSVersion.VersionString}");

var incrementar = (int valor, int incremento = 1) => valor + incremento;

Console.WriteLine();
Console.WriteLine(
$"Incremento default = {incrementar.Method.GetParameters()[1].DefaultValue}");

Console.WriteLine();
int teste01 = 1;
Console.WriteLine($"{nameof(teste01)} = {teste01} | Valor inicial");
teste01 = incrementar(teste01);
Console.WriteLine($"{nameof(teste01)} = {teste01} | Depois de incrementar");
teste01 = incrementar(teste01);
Console.WriteLine($"{nameof(teste01)} = {teste01} | Segundo incremento");

Console.WriteLine();
int teste02 = 1000;
Console.WriteLine($"{nameof(teste02)} = {teste02} | Valor inicial");
teste02 = incrementar(teste02, 2);
Console.WriteLine($"{nameof(teste02)} = {teste02} | Depois de incrementar com 2");
teste02 = incrementar(teste02, 3);
Console.WriteLine($"{nameof(teste02)} = {teste02} | Depois de incrementar com 3");

Gostou do artigo? clique no ícone👏e me siga para ver as próximas publicações !! Quer ver mais conteúdos, acesse minhas redes através do Linktree: https://linktree.com/nizzola

Referência:

--

--

Marcio Nizzola

Microsoft MVP | Software Architect na CI&T | Prof. da Etec Itu | Membro Fundador da Comunidade Itu Developers.