Novidades do C# 8.0

Henrique Dal Bello
Training Center
Published in
5 min readDec 17, 2018

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

--

--

Henrique Dal Bello
Training Center

Knowledge is for sharing. Developing bugs since 2012 💻