Henrique Dal Bello
Dec 17, 2018 · 5 min read

Ta saindo versão nova do forno! 💻

C# 8.0 e .Net Core 3.0 já estão disponíveis!
Hoje quero mostrar um pouco das features novas que foram e/ou ainda vão ser adicionadas na versão 8.0.

Para quem quiser testar, está disponível no Visual Studio 2019 Preview, basta instalar e fazer o teste. No fim do artigo tem algumas instruções e links.

Obs.: Os tópicos marcados com um * não estão disponíveis ainda na versão preview


Nullable reference types

O intuito dela é produzir warnings ao identificar um objeto possivelmente nulo no seu código, que possa resultar em um NullReferenceException.

Juntamente com isso, é possível agora tornar uma string em um “nullable type”. Aqueles que já conhecem sabem que diferente de um int, que para ser nullable é necessário estar como int?ou Nullable<int>, strings já são nullables em sua raiz (por serem variáveis de referência e não de valor).

Então para quê vou tornar meu string em um nullable type?
Bom… É mais para ter um maior cuidado com nossa famosa exceçãoNullReferenceException, assim podemos diminuir as incidências delas por conta de esquecer de checar se o objeto está nulo ou não.

Colocar nullable ou não, não vai barrar você de atribuir null em sua string, mas com certeza o intellisense vai pintar de amarelo e criar warnings no seu código quando detectar um perigo! Veja as diferenças:

Outra coisa legal, pelo menos nesta versão preview, é que não é “obrigatório” o uso dessa feature, ela somente é habilitada caso você coloque a tag #nullable enable no topo da sua classe.
Ou se quiser habilitar para o projeto todo, basta colocar no seu .csproj a tag:

<NullableReferenceTypes>true</NullableReferenceTypes>

O que foi bem sensato por parte da Microsoft, eu por exemplo, ficaria bem irritado ao abrir meu projeto e ver centenas de warnings para todos os lados.

IAsyncEnumerable<T>

Conhecemos a interface IEnumerable<T>e agora foi introduzido o IAsyncEnumerable<T>que torna a nossa coleção em uma coleção assíncrona!
Agora não é mais necessário gerar um Task<IEnumerable<T>>, o que tornava um pouco chato tanto a implementação quanto a própria sintaxe.

Array Slicing

Chega de usar o nosso grande System.Linqpara fazer slicing de array!
Antes usávamos muito os métodos Take()eSkip()para conseguir selecionar uma porção específica de um array ou mais especificamente de um IEnumerable<T>. A partir do C# 8.0 isso talvez não seja mais necessário!!

E é bem fácil de escrever e compreender, temos duas sintaxes para isso:

Recursive Patterns*

Com essa nova feature podemos melhorar o nosso switch case, passando várias referências/valores dentro do switch.
Em poucas palavras (ou códigos) hoje usamos switch(variavel), agora podemos usar switch(variavel1, variavel2, variavel3) e ter cases para cada variação dentre essas variáveis:

switch(p.Nome, p.Sobrenome)
{
case (string n, string s):
return $"{n} {s}";
case (string n, null):
return n;
case (null, string s):
return $"Sr. {s}";
case (null, null):
return "Desconhecido";
}

Switch expressions*

Ainda falando de switch, por conta do novo recursive pattern é possivel que os cases ficam bem maiores que o esperado, portanto foram adicionados a possibilidade do uso de expressões para os cases.
Assim como utilizamos em métodos (feature do C# 7.0), podemos aplicar o mesmo agora dentro de cada condição do nosso switch.

Basta usar os tokens => que fica bem melhor pra dar nosso famoso return:

return (p.Nome, p.Sobrenome) switch
{
(string n, string s) => $"{n} {s}",
(string n, null) => n,
(null, string s) => $"Sr. {s}",
(null, null) => "Desconhecido"
}

Implicity typed new-expressions*

Hoje quando definimos um array de um determinado objeto, é necessário escrever por exemplo new Pessoa("nome", "sobrenome")para todos os itens criados dentro do array.

O que essa feature faz é basicamente excluir a necessidade de escrever isso, já que está “tipado”, o compilador já vai entender que se trata daquele objeto, portanto inibindo a escrita de “Pessoa” para: new ("nome", "sobrenome")

Pessoa[] pessoas = new 
{
new ("Henrique", "Dal Bello"),
new ("Bill", "Gates"),
new ("Mark", "Zuckerberg")
};

Default interface members

Os contratos de interface exigem que cada classe que o implementa contenha os métodos definidos nela, portanto, toda vez que adicionarmos um novo método nela, automaticamente haverá erros subindo por conta de classes que ainda não implementam.

No C# 8.0, podemos definir um método default, sim, um método único que caso a classe não tenha o seu próprio implementado (quase como um override), ele vai utilizar o que foi definido na interface.

public interface ILogger
{
void Log(string mensagem);
void Log(Exception ex) => Log(ex.Message); //Default
}

Testando o preview do C# 8.0

Pra quem quiser testar, basta baixar o Visual Studio 2019 Preview, o SDK do .net core 3.0 e ser feliz!

Na hora que criar o projeto de teste, não esqueça de mudar o framework para o .Net Core 3.0 lá em properties do projeto e também habilitar o C# 8.0 na aba lateralBuild > Advanced mudando para C# 8.0 (beta).

Visual Studio 2019 Preview:

SDK:

Fontes:

https://blogs.msdn.microsoft.com/dotnet/2018/12/05/take-c-8-0-for-a-spin/

https://www.youtube.com/watch?v=VdC0aoa7ung

Training Center

Conectamos pessoas que querem aprender algo relacionado a desenvolvimento de software com gente que pode guiá-las.

Henrique Dal Bello

Written by

Knowledge is for sharing. Developing bugs since 2012 💻

Training Center

Conectamos pessoas que querem aprender algo relacionado a desenvolvimento de software com gente que pode guiá-las.

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade