O que há de novo no C# 10

O C# 10 adiciona os seguintes recursos e aprimoramentos à linguagem C#:

O C# 10 é suportado no .NET 6. Para obter mais informações, consulte Versionamento de linguagem C#.

Você pode baixar o SDK mais recente do .NET 6 na página de downloads do .NET. Você também pode baixar o Visual Studio 2022, que inclui o SDK do .NET 6.

Nota

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 .

Estruturas de gravação

Você pode declarar registros de tipo de valor usando as record struct declarações ou readonly record struct . Agora você pode esclarecer que a record é um tipo de referência com a record class declaração.

Melhorias nos tipos de estrutura

O C# 10 introduz as seguintes melhorias relacionadas aos tipos de estrutura:

  • Você pode declarar um construtor sem parâmetros de instância em um tipo de estrutura e inicializar um campo de instância ou propriedade em sua declaração. Para obter mais informações, consulte a seção Inicialização de struct e valores padrão do artigo Tipos de estrutura.
  • Um operando esquerdo da with expressão pode ser de qualquer tipo de estrutura ou um tipo anônimo (referência).

Manipulador de cadeia de caracteres interpolado

Você pode criar um tipo que cria a cadeia de caracteres resultante de uma expressão de cadeia de caracteres interpolada. As bibliotecas .NET usam esse recurso em muitas APIs. Você pode criar um seguindo este tutorial.

Diretivas de utilização global

Você pode adicionar o global modificador a qualquer diretiva using para instruir o compilador de que a diretiva se aplica a todos os arquivos de origem na compilação. Normalmente, trata-se de todos os arquivos de origem em um projeto.

Declaração de namespace com escopo de arquivo

Você pode usar um novo formulário da namespace declaração para declarar que todas as declarações a seguir são membros do namespace declarado:

namespace MyNamespace;

Essa nova sintaxe economiza espaço horizontal e vertical para namespace declarações.

Padrões de propriedade estendidos

A partir do C# 10, você pode fazer referência a propriedades aninhadas ou campos dentro de um padrão de propriedade. Por exemplo, um padrão do formulário

{ Prop1.Prop2: pattern }

é válido em C# 10 e posteriores e equivalente a

{ Prop1: { Prop2: pattern } }

válido em C# 8.0 e posterior.

Para obter mais informações, consulte a nota de proposta de recurso Padrões de propriedade estendidos. Para obter mais informações sobre um padrão de propriedade, consulte a seção Padrão de propriedade do artigo Padrões .

Melhorias na expressão do Lambda

O C# 10 inclui muitas melhorias na forma como as expressões lambda são tratadas:

  • As expressões lambda podem ter um tipo natural, onde o compilador pode inferir um tipo delegado a partir da expressão lambda ou grupo de métodos.
  • As expressões do Lambda podem declarar um tipo de retorno quando o compilador não pode inferi-lo.
  • Os atributos podem ser aplicados a expressões lambda.

Esses recursos tornam as expressões lambda mais semelhantes a métodos e funções locais. Eles facilitam o uso de expressões lambda sem declarar uma variável de um tipo delegado, e funcionam de forma mais integrada com as novas APIs ASP.NET Core Minimal APIs.

Cordas interpoladas constantes

Em C# 10, const as cadeias de caracteres podem ser inicializadas usando interpolação de cadeia de caracteres se todos os espaços reservados forem eles próprios cadeias constantes. A interpolação de cadeias de caracteres pode criar cadeias de caracteres constantes mais legíveis à medida que você cria cadeias de caracteres constantes usadas em seu aplicativo. As expressões de espaço reservado não podem ser constantes numéricas porque essas constantes são convertidas em cadeias de caracteres em tempo de execução. A cultura atual pode afetar sua representação de cadeia de caracteres. Saiba mais na referência de idioma sobre const expressões.

Os tipos de registro podem selar ToString

Em C# 10, você pode adicionar o sealed modificador quando substituir ToString em um tipo de registro. A selagem do ToString método impede que o compilador sintetize um ToString método para quaisquer tipos de registro derivados. A sealedToString garante que todos os tipos de registo derivados utilizam o ToString método definido num tipo de registo de base comum. Você pode saber mais sobre esse recurso no artigo sobre registros.

Cessão e declaração na mesma desconstrução

Essa alteração remove uma restrição de versões anteriores do C#. Anteriormente, uma desconstrução podia atribuir todos os valores a variáveis existentes ou inicializar variáveis recém-declaradas:

// Initialization:
(int x, int y) = point;

// assignment:
int x1 = 0;
int y1 = 0;
(x1, y1) = point;

O C# 10 remove essa restrição:

int x = 0;
(x, int y) = point;

Atribuição definitiva melhorada

Antes do C# 10, havia muitos cenários em que a atribuição definitiva e a análise de estado nulo produziam avisos que eram falsos positivos. Estes geralmente envolviam comparações com constantes booleanas, acessando uma variável apenas nas true instruções ou false em uma if instrução, e expressões coalescentes nulas. Estes exemplos geraram avisos em versões anteriores do C#, mas não no C# 10:

string representation = "N/A";
if ((c != null && c.GetDependentValue(out object obj)) == true)
{
   representation = obj.ToString(); // undesired error
}

// Or, using ?.
if (c?.GetDependentValue(out object obj) == true)
{
   representation = obj.ToString(); // undesired error
}

// Or, using ??
if (c?.GetDependentValue(out object obj) ?? false)
{
   representation = obj.ToString(); // undesired error
}

O principal impacto dessa melhoria é que os avisos para atribuição definitiva e análise de estado nulo são mais precisos.

Permitir atributo AsyncMethodBuilder em métodos

Em C# 10 e posterior, você pode especificar um construtor de métodos assíncrono diferente para um único método, além de especificar o tipo de construtor de métodos para todos os métodos que retornam um determinado tipo de tarefa. Um construtor de métodos assíncronos personalizados permite cenários avançados de ajuste de desempenho em que um determinado método pode se beneficiar de um construtor personalizado.

Para saber mais, consulte a seção no AsyncMethodBuilder artigo sobre atributos lidos pelo compilador.

Diagnóstico do atributo CallerArgumentExpression

Você pode usar o System.Runtime.CompilerServices.CallerArgumentExpressionAttribute para especificar um parâmetro que o compilador substitui pela representação de texto de outro argumento. Esse recurso permite que as bibliotecas criem diagnósticos mais específicos. O código a seguir testa uma condição. Se a condição for false, a mensagem de exceção conterá a representação em texto do argumento passado para condition:

public static void Validate(bool condition, [CallerArgumentExpression("condition")] string? message=null)
{
    if (!condition)
    {
        throw new InvalidOperationException($"Argument failed validation: <{message}>");
    }
}

Você pode saber mais sobre esse recurso no artigo sobre atributos de informações do chamador na seção de referência de idioma.

Pragma #line melhorado

O C# 10 suporta um novo formato para o #line pragma. Você provavelmente não usará o novo formato, mas verá seus efeitos. Os aprimoramentos permitem uma saída mais refinada em linguagens específicas de domínio (DSLs), como o Razor. O mecanismo Razor usa esses aprimoramentos para melhorar a experiência de depuração. Você descobrirá que os depuradores podem destacar sua fonte do Razor com mais precisão. Para saber mais sobre a nova sintaxe, consulte o artigo sobre diretivas de pré-processador na referência de idioma. Você também pode ler a especificação de recurso para exemplos baseados no Razor.