Olá, neste artigo eu vou escrever um resumo das novidades que eu acho mais relevantes que vieram no C# na versão 8 .
Index: Deconstruct ↑ Antes.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 public sealed class LoggingConfiguration { public bool Enabled { get ; set ; } public string ? Path { get ; set ; } } public static class Logger { public static void LogInfo (in LoggingConfiguration config, in string message ) { var configuration = config ?? new LoggingConfiguration(); if (!configuration.Enabled) { return ; } Console.WriteLine($"{configuration.Path ?? "logs/.log" } => {message} " ); } }
Depois.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 public sealed class LoggingConfiguration { public bool Enabled { get ; set ; } public string ? Path { get ; set ; } public void Deconstruct (out bool enabled, out string path ) => (enabled, path) = ( this .Enabled, this .Path ?? "logs/.log" ); } public static class Logger { public static void LogInfo (in LoggingConfiguration config, in string message ) { var (enabled, path) = config ?? new LoggingConfiguration(); if (!enabled) { return ; } Console.WriteLine($"{path} => {message} " ); } }
using
Declarations ↑ Antes.
1 2 3 4 5 6 7 8 9 10 11 12 13 public static class Reader { public static Task<string > Read (in string path ) { using (var stream = File.OpenRead(path)) { using (var reader = new StreamReader(stream)) { return reader.ReadToEndAsync(); } } } }
Depois.
1 2 3 4 5 6 7 8 9 10 public static class Reader { public static Task<string > Read (in string path ) { using var stream = File.OpenRead(path); using var reader = new StreamReader(stream); return reader.ReadToEndAsync(); } }
static
Local functions ↑ Antes.
1 2 3 4 5 6 7 8 9 public void LogInfo (string message ){ Log("Info" ); void Log (in string level ) { Console.WriteLine($"{level} -> {message} " ); } }
Depois.
1 2 3 4 5 6 7 8 9 public void LogInfo (in string message ){ Log("Info" , message); static void Log (in string level, in string message ) { Console.WriteLine($"{level} -> {message} " ); } }
Nullable reference types ↑ Para habilitar a verificar de null
reference types, adicione no seu csproj
o código abaixo:
1 2 3 4 <PropertyGroup > <LangVersion > 8.0</LangVersion > <Nullable > enable</Nullable > </PropertyGroup >
Com este configuração o compilador vai começar a lançar warning em praticamente todo o trecho de código que pode conter null
.
!
Operator (que perdoa nulo) ↑ 1 2 3 4 5 6 7 8 9 10 11 public class User { private User (in string name ) { this .Name = name ?? throw new ArgumentNullException(nameof (name), "Name cannot be null" ); } public string Name { get ; } public static User NewUser (string ? name ) => new User(name!); }
Sem este operador o compilador iria mostrar o warning abaixo:
'name' may be null here. Possible null reference argument for parameter 'name' in 'User.User(in string name)'.
Neste caso ele não precisaria mostrar este warning já que no construtor da classe User
tem uma validação se o name
é nulo, por isso neste caso podemos usar o operador !
.
Asynchronous streams ↑ Antes.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 public static class UserImporter { public static async Task<IEnumerable<User>> Import(string path) { await using var stream = File.OpenRead(path); using var reader = new StreamReader(stream); string ? id; var users = new List<User>(); while ((id = await reader.ReadLineAsync()) != null ) { users.Add(await GetUserByIdQuery.GetResult(id)); } return users; } } public static class UserService { public static async Task Import (string path ) { foreach (var user in await UserImporter.Import(path)) { await InsertUserCommand.Execute(user); } } }
Depois.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 public static class UserImporter { public static async IAsyncEnumerable<User> Import (string path ) { await using var stream = File.OpenRead(path); using var reader = new StreamReader(stream); string ? id; while ((id = await reader.ReadLineAsync()) != null ) { yield return await GetUserByIdQuery.GetResult(id); } } } public static class UserService { public static async Task Import (string path ) { await foreach (var user in UserImporter.Import(path)) { await InsertUserCommand.Execute(user); } } }
Null-coalescing assignment ↑ Antes.
1 2 3 4 5 6 7 8 9 public static class Logger { public static void LogInfo (string ? path, in string message ) { path = path ?? "logs/.log" ; Console.WriteLine($"{path} => {message} " ); } }
Depois.
1 2 3 4 5 6 7 8 9 public static class Logger { public static void LogInfo (string ? path, in string message ) { path ??= "logs/.log" ; Console.WriteLine($"{path} => {message} " ); } }
Mais exemplos ↑ Abaixo uma lista de projetos que você pode ver as novidades do C# em exemplos reais.
♟ Chess é uma console app feita com ASCII art. 🐷 Hawk (api) é sistema de finança pessoal.Http.Query.Filter é uma lib para fazer filtros baseado no StrongLoop da IBM.
Obrigado pela visita 🙂!