No ASP NET não é mais necessário injetar interface ILogger para se obter uma instância de Logger, agora é possível utilizar Attribute.
Exemplo:
public static partial class Log
{
[LoggerMessage(EventId = 0, Level = LogLevel.Error, Message = "An error occurred")]
public static partial Error(this ILogger, string YourMessage);
}Agora é possível fazer condições utilizando um nível mais elevado de sintaxe.
if (score is >= 60 and <= 100)
{
Console.WriteLine("Make Something");
}Essa funcionalidade permite utilizar uma classe de forma semelhante a um record.
Obs: Como é um construtor primário é permitido utilizar ele pra injetar dependências.
public class PrimaryConstructor(string arg1, string arg2)
{
public string ArgUpper => arg1.ToUpper();
public string ArgLower => arg2.ToLower();
}Assim como no JavaScript, agora no C# é possível utilizar o operador spread que é denotado com ... Além disso, uma nova forma de se declarar Arrays e Lists surgiu que usando o [].
List<string> names = ["Gabriel", "Lívia", "Children"];
List<string> expandFamily = [..names, "Claudio", "José", "Wilson", "Chimbinha"];Dentro da classe Random tem a classe Shared que contém métodos generics úteis para randomificação distribuída.
Shuffle - Permite embaralhar um Array (Apenas Array)
string[] names = ["Gabriel", "Lívia", "Children"];
Random.Shared.Shuffle(names);
Array.ForEach(names, Console.WriteLine);GetItems - Permite obter elementos de um Enumerable de forma aleatória.
string[] names = ["Gabriel", "Lívia", "Children"];
Array.ForEach(Random.Shared.GetItems(names, 2), Console.WriteLine);<<<<<<< HEAD:RADME.md
public bool TheNamesIsSimilar(string first, string second)
{
return string.Equals(first, second, StringComparsion.OrdinalIgnoreCase);
}Permite navegar sobre propriedades de um objeto que pode ser nulo, mas sem gerar Exception. Isso evita a utilização de If desnecessários.
customer?.Orders?.Ship();ArgumentNullException é uma classe que contém metódos pra validar objetos nulos.
public void MapTo <T> (T source) where T: class
{
ArgumentNullException.ThrowIfNull(source);
}Permite executar um loop ForEach de forma assincrona, dividindo em threads, muito útil para operações custosas.
List<string> paths = GetFilePathList();
Parallel.ForEach(paths, CompressFile);No Javascript tem o AbortController no C# tem o CancellationTokenSource pra cancelar operações assincronas por meio de Task. Lembrando que isso não funciona com TaskValue, inclusive, isso é uma das diferenças entre utilizar Task e TaskValue.
CancellationTokenSource tokenSource = new()/
CancellationToken token = tokenSource.Token;
Task task = Task.Run(async () =>
{
await using var reader = new("./file.txt");
while (reader.ReadLine() is {} line && !token.IsCancellationRequested)
{
Console.WriteLine(line);
}
}, token);Alguns atributos de validação de model, muito bom como alternativa do RegexExpression.
public readonly record struct Product (
[Base64String]
string Name;
[DaniedValues("Eletronic", "Clean")]
string Category;
[AllowedValues("Brazil", "Castelo")]
string Location;
);Permite definir um alias para um tipo, namespace, etc, por exemplo, no C existe o typedef que permite dar um nome diferente para o tipo da struct. No C# é semelhante com o using.
Exemplo:
using Point3D = string; // Dando um alias para string
Point3D point = "Hello world";É uma forma mais simples de se inicializar coleções do tipo, arrays, spans, ReadonlySpan e lists
int[] numeros = [1, 2, 3, 4, 5];
Span<string> regiaoSul = ["pr", "sc"];
ReadOnlySpan<string> regiaoSuldeste = ["es", "mg", "rj", "sp"];
List<string> frutas = ["Maçã", "Pera"];Podemos definir agora valores padrões pra funções anônimas
var increment = (int origem, int quantificador = 10) => origem * quantificador;Isso já existia em versões antigas
public class Fish (string type)
{
public string Type { get; private set; } = type;
public static explicit operator int (Fish instance) => instance.GetHashCode();
}
var fish = new Fish("Morcego");
var castToInt = (int) fish;Permite fazer validações utilizando o padrão de property, as condições de cada propriedade representa uma operação &&
if (product is { Category: "books", Price: > 100 })
{
Console.WriteLine("This is truth");
}Agora com o in é possível tornar um tipo como sendo imutável em questão de referência, ou seja, eu não consigo reatribuir o parâmetro prod para uma outra instância.
void Fnc(in Product prod)
{
prod.Name = "Smartphone";
}Esse operador permite atribuir valor a uma variável nula caso ela esteja com valor nulo, caso contrário, não será atribuído nada.
string? name = null;
string initialName = "Gabriel Cardoso"
name ??= initialName;
Console.Writeline(name); // Output: Gabriel Cardoso