Nota
O acesso a esta página requer autorização. Pode tentar iniciar sessão ou alterar os diretórios.
O acesso a esta página requer autorização. Pode tentar alterar os diretórios.
O C# 14 inclui os seguintes novos recursos. Você pode experimentar esses recursos usando a versão mais recente do Visual Studio 2022 ou o SDK do .NET 10:
- Membros extensionistas
- Atribuição condicional nula
-
nameof
suporta tipos genéricos não acoplados -
Conversões mais implícitas para
Span<T>
eReadOnlySpan<T>
- Modificadores em parâmetros lambda simples
-
field
Propriedades garantidas -
partial
eventos e construtores - operadores de atribuição compostos definidos pelo usuário
O C# 14 é suportado no .NET 10. Para obter mais informações, consulte versão de linguagem C#.
Você pode baixar o SDK mais recente do .NET 10 na página de downloads do .NET. Você também pode baixar o Visual Studio 2022, que inclui o SDK do .NET 10.
Novos recursos são adicionados à página "Novidades em C#" quando estão disponíveis em versões de visualização pública. A seção do conjunto de trabalho da página de status das funcionalidades do Roslyn rastreia quando as próximas funcionalidades são mescladas na branch principal. Este artigo foi atualizado pela última vez para o .NET 10 Preview 1.
Você pode encontrar quaisquer alterações significativas introduzidas no C# 14 em nosso artigo sobre alterações significativas.
Observação
Estamos interessados nos seus comentários sobre estas funcionalidades. Se você encontrar problemas com qualquer um desses novos recursos, crie um novo problema no repositório dotnet/roslyn.
Membros da Extensão
O C# 14 adiciona uma nova sintaxe para definir membros de extensão. A nova sintaxe permite que você declare propriedades de extensão , além de métodos de extensão. Você também pode declarar membros de extensão que estendem o tipo, em vez de uma instância do tipo. Em outras palavras, esses novos membros da extensão podem aparecer como membros estáticos do tipo que você estende. Essas extensões podem incluir operadores definidos pelo usuário implementados como métodos de extensão estática. O exemplo de código a seguir mostra um exemplo dos diferentes tipos de membros de extensão que você pode declarar:
public static class Enumerable
{
// Extension block
extension<TSource>(IEnumerable<TSource> source) // extension members for IEnumerable<TSource>
{
// Extension property:
public bool IsEmpty => !source.Any();
// Extension method:
public IEnumerable<TSource> Where(Func<TSource, bool> predicate) { ... }
}
// extension block, with a receiver type only
extension<TSource>(IEnumerable<TSource>) // static extension members for IEnumerable<Source>
{
// static extension method:
public static IEnumerable<TSource> Combine(IEnumerable<TSource> first, IEnumerable<TSource> second) { ... }
// static extension property:
public static IEnumerable<TSource> Identity => Enumerable.Empty<TSource>();
// static user defined operator:
public static IEnumerable<TSource> operator + (IEnumerable<TSource> left, IEnumerable<TSource> right) => left.Concat(right);
}
}
Os membros no primeiro bloco de extensão são chamados como se fossem membros da instância de IEnumerable<TSource>
, por exemplo sequence.IsEmpty
. Os membros no segundo bloco de extensão são chamados como se fossem membros estáticos do IEnumerable<TSource>
, por exemplo IEnumerable<int>.Identity
.
Você pode saber mais detalhes lendo o artigo sobre membros de extensão no guia de programação, o artigo de referência de linguagem na palavra-chaveextension
e a especificação de recurso para o novo recurso de membros de extensão.
A palavra-chave field
O token field
permite-lhe escrever um bloco de código para o acessador de uma propriedade sem precisar de declarar um campo de apoio explícito. O token field
é substituído por um campo de suporte sintetizado pelo compilador.
Por exemplo, anteriormente, se você quisesse garantir que uma string
propriedade não pudesse ser definida como null
, era necessário declarar um campo de suporte e implementar ambos os acessadores:
private string _msg;
public string Message
{
get => _msg;
set => _msg = value ?? throw new ArgumentNullException(nameof(value));
}
Agora você pode simplificar seu código para:
public string Message
{
get;
set => field = value ?? throw new ArgumentNullException(nameof(value));
}
Você pode declarar um corpo para um ou ambos os acessores de uma propriedade baseada em campo.
Há uma potencial alteração que quebra compatibilidade ou causa confusão ao ler o código em tipos que também incluem um símbolo chamado field
. Você pode usar @field
ou this.field
para desambiguar entre a palavra-chave field
e o identificador, ou pode renomear o símbolo atual field
para dar uma melhor distinção.
Se você tentar esse recurso e tiver comentários, comente sobre o problema do recurso no csharplang
repositório.
A palavra-chave contextual field
está em C# 13 como um recurso de visualização.
Conversões implícitas de intervalos
O C# 14 introduz suporte de primeira classe para System.Span<T> e System.ReadOnlySpan<T> na linguagem. Este suporte envolve novas conversões implícitas permitindo uma programação mais natural com estes tipos.
Span<T>
e ReadOnlySpan<T>
são usados de muitas maneiras importantes em C# e no tempo de execução. A sua introdução melhora o desempenho sem pôr em risco a segurança. O C# 14 reconhece o relacionamento e suporta algumas conversões entre ReadOnlySpan<T>
, Span<T>
e T[]
. Os tipos de span podem ser recetores de método de extensão, compor com outras conversões e ajudar com cenários genéricos de inferência de tipo.
Você pode encontrar a lista de conversões de intervalo implícitas no artigo sobre tipos internos na seção de referência de idioma. Pode obter mais detalhes lendo a especificação da funcionalidade para tipos de extensão de primeira categoria.
Tipos genéricos não acoplados e nameof
A partir do C# 14, o argumento para nameof
pode ser um tipo genérico não vinculado. Por exemplo, nameof(List<>)
é avaliado como List
. Em versões anteriores do C#, apenas tipos genéricos fechados, como List<int>
, podiam ser usados para retornar o List
nome.
Parâmetros lambda simples com modificadores
Você pode adicionar modificadores de parâmetro, como scoped
, ref
, in
, out
, ou ref readonly
a parâmetros de expressão lambda sem especificar o tipo de parâmetro:
delegate bool TryParse<T>(string text, out T result);
// ...
TryParse<int> parse1 = (text, out result) => Int32.TryParse(text, out result);
Anteriormente, a adição de modificadores era permitida apenas quando as declarações de parâmetros incluíam os tipos para os parâmetros. A declaração anterior exigiria tipos em todos os parâmetros:
TryParse<int> parse2 = (string text, out int result) => Int32.TryParse(text, out result);
O params
modificador ainda requer uma lista de parâmetros explicitamente tipada.
Você pode ler mais sobre essas alterações no artigo sobre expressões lambda na referência da linguagem C#.
Mais membros parciais
Agora você pode declarar construtores de instância e eventos como membros parciais.
Construtores parciais e eventos parciais devem incluir exatamente uma declaração definidora e uma declaração de implementação.
Somente a declaração de implementação de um construtor parcial pode incluir um inicializador de construtor: this()
ou base()
. Apenas uma declaração de tipo parcial pode incluir a sintaxe do construtor primário.
A declaração de execução de um evento parcial deve incluir add
e remove
acessores. A declaração definidora declara um evento semelhante a um campo.
Atribuição composta definida pelo usuário
Você pode saber mais na especificação de recurso para atribuição composta definida pelo usuário.
Atribuição condicional nula
Os operadores de acesso de membro nulo-condicional, ?.
e ?[]
, agora podem ser usados no lado esquerdo de uma atribuição ou atribuição composta.
Antes do C# 14, você precisava verificar nulo uma variável antes de atribuir a uma propriedade:
if (customer is not null)
{
customer.Order = GetCurrentOrder();
}
Você pode simplificar o código anterior usando o ?.
operador:
customer?.Order = GetCurrentOrder();
O lado direito do =
operador é avaliado apenas quando o lado esquerdo não é nulo. Caso customer
seja nulo, o código não irá chamar GetCurrentOrder
.
Além da atribuição, você pode usar operadores de acesso de membro condicional nulo com operadores de atribuição compostos (+=
, -=
, e outros). No entanto, incremento e decréscimo, ++
e --
, não são permitidos.
Você pode saber mais no artigo de referência de idioma sobre o acesso de membro condicional e a especificação de recurso para atribuição condicional nula.