Partilhar via


O que há de novo no C# 12

O C# 12 inclui os seguintes novos recursos. Você pode experimentar esses recursos usando a versão mais recente do Visual Studio 2022 ou o .NET 8 SDK.

O C# 12 é suportado no .NET 8. Para obter mais informações, consulte versão de linguagem C#.

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

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.

Construtores primários

Agora você pode criar construtores primários em qualquer class e struct. Os construtores primários não estão mais restritos a tipos record. Os parâmetros do construtor primário estão no escopo de todo o corpo da classe. Para garantir que todos os parâmetros do construtor primário sejam definitivamente atribuídos, todos os construtores explicitamente declarados devem chamar o construtor primário usando this() sintaxe. Adicionar um construtor primário a um class impede que o compilador declare um construtor implícito sem parâmetros. Em um struct, o construtor implícito sem parâmetros inicializa todos os campos, incluindo os parâmetros primários do construtor, para o padrão de bits zero.

O compilador gera propriedades públicas para parâmetros primários do construtor somente em tipos record, record class ou record struct. Classes e estruturas que não são de registro nem sempre desejam esse comportamento para parâmetros primários do construtor.

Você pode aprender mais sobre construtores primários no tutorial para explorando construtores primários e no artigo sobre construtores de instância.

Expressões de coleção

As expressões de coleção introduzem uma nova sintaxe para criar valores de coleção comuns. É possível inserir outras coleções nesses valores usando um elemento spread ..e.

Vários tipos semelhantes a coleções podem ser criados sem a necessidade de suporte BCL externo. Estes tipos são:

Os exemplos a seguir mostram usos de expressões de coleção:

// Create an array:
int[] a = [1, 2, 3, 4, 5, 6, 7, 8];

// Create a list:
List<string> b = ["one", "two", "three"];

// Create a span
Span<char> c  = ['a', 'b', 'c', 'd', 'e', 'f', 'h', 'i'];

// Create a jagged 2D array:
int[][] twoD = [[1, 2, 3], [4, 5, 6], [7, 8, 9]];

// Create a jagged 2D array from variables:
int[] row0 = [1, 2, 3];
int[] row1 = [4, 5, 6];
int[] row2 = [7, 8, 9];
int[][] twoDFromVariables = [row0, row1, row2];

O elemento spread , ..e em uma expressão de coleção adiciona todos os elementos nessa expressão. O argumento deve ser um tipo de coleção. Os exemplos a seguir mostram como o elemento spread funciona:

int[] row0 = [1, 2, 3];
int[] row1 = [4, 5, 6];
int[] row2 = [7, 8, 9];
int[] single = [.. row0, .. row1, .. row2];
foreach (var element in single)
{
    Console.Write($"{element}, ");
}
// output:
// 1, 2, 3, 4, 5, 6, 7, 8, 9,

O elemento spread avalia cada elemento da expressão de enumerações. Cada elemento é incluído na coleção de saída.

Você pode usar expressões de coleção em qualquer lugar que precise de uma coleção de elementos. Eles podem especificar o valor inicial de uma coleção ou ser passados como argumentos para métodos que usam tipos de coleção. Você pode saber mais sobre expressões de coleção no artigo de referência de linguagem sobre expressões de coleção ou na especificação de recurso .

ref readonly parâmetros

O C# adicionou parâmetros in para permitir a passagem de referências de somente leitura. in parâmetros permitem variáveis e valores, e podem ser usados sem qualquer anotação em argumentos.

A adição de parâmetros ref readonly permite mais clareza para APIs que podem estar usando parâmetros ref ou parâmetros in:

Para saber mais sobre os parâmetros ref readonly, consulte o artigo sobre modificadores de parâmetro na referência de idioma ou a especificação de recursos de parâmetros readonly ref .

Parâmetros lambda padrão

Agora você pode definir valores padrão para parâmetros em expressões lambda. A sintaxe e as regras são as mesmas que adicionar valores padrão para argumentos a qualquer método ou função local.

Você pode saber mais sobre parâmetros padrão em expressões lambda no artigo sobre expressões lambda.

Alias qualquer tipo

Pode usar a diretiva de alias using para criar um alias para qualquer tipo, não apenas para tipos nomeados. Isso significa que você pode criar aliases semânticos para tipos de tupla, tipos de matriz, tipos de ponteiro ou outros tipos inseguros. Para obter mais informações, consulte a especificação do recurso . Para obter um exemplo de passo a passo de refatoração, consulte refatore o código usando um alias de qualquer tipo no blog .NET.

Matrizes em linha

As matrizes embutidas são usadas pela equipe de tempo de execução e outros autores de bibliotecas para melhorar o desempenho em seus aplicativos. As matrizes inline permitem que os desenvolvedores criem uma matriz de tamanho fixo em um tipo de struct. Uma struct com um buffer embutido deve fornecer características de desempenho semelhantes a um buffer de tamanho fixo inseguro. Você provavelmente não declarará suas próprias matrizes embutidas, mas as usará de forma transparente quando forem expostas como objetos System.Span<T> ou System.ReadOnlySpan<T> de APIs de tempo de execução.

Um de matriz embutida é declarado semelhante ao seguinte struct:

[System.Runtime.CompilerServices.InlineArray(10)]
public struct Buffer
{
    private int _element0;
}

Você os usa como qualquer outra matriz:

var buffer = new Buffer();
for (int i = 0; i < 10; i++)
{
    buffer[i] = i;
}

foreach (var i in buffer)
{
    Console.WriteLine(i);
}

A diferença é que o compilador pode tirar proveito de informações conhecidas sobre uma matriz embutida. Você provavelmente consumiria matrizes embutidas como faria com qualquer outra matriz. Para obter mais informações sobre como declarar matrizes embutidas, consulte a referência de idioma em struct tipos.

Atributo experimental

Tipos, métodos ou montagens podem ser marcados com a System.Diagnostics.CodeAnalysis.ExperimentalAttribute para indicar um recurso experimental. O compilador emite um aviso se você acessar um método ou tipo anotado com o ExperimentalAttribute. Todos os tipos incluídos em um assembly marcado com o atributo Experimental são experimentais. Você pode ler mais no artigo sobre atributos gerais lidos pelo compilador, ou na especificação da funcionalidade .

Intercetores

Advertência

Os intercetores são um recurso experimental, disponível no modo de visualização com C# 12. O recurso pode estar sujeito a alterações ou remoção em uma versão futura. Portanto, não é recomendado para aplicações de produção ou já lançadas.

Para usar intercetores, o projeto de usuário deve especificar a propriedade <InterceptorsPreviewNamespaces>. Esta é uma lista de namespaces que podem conter intercetadores.

Por exemplo: <InterceptorsPreviewNamespaces>$(InterceptorsPreviewNamespaces);Microsoft.AspNetCore.Http.Generated;MyLibrary.Generated</InterceptorsPreviewNamespaces>

Um interceptor é um método que pode substituir declarativamente uma chamada para um método interceptável por uma chamada para o próprio método no momento da compilação. Essa substituição ocorre fazendo com que o intercetor declare os locais de origem das chamadas que interceta. Os intercetores fornecem uma facilidade limitada para alterar a semântica do código existente, adicionando novo código a uma compilação, por exemplo, em um gerador de código-fonte.

Você usa um intercetador como parte de um gerador de código-fonte para modificar um código já existente, em vez de adicionar código novo a uma compilação existente. O gerador de código-fonte substitui chamadas para um método interceptável por uma chamada para o método intercetor do .

Se estiver interessado em experimentar intercetores, pode aprender mais lendo a especificação da funcionalidade . Se você usar o recurso, certifique-se de manter-se atualizado com quaisquer alterações na especificação do recurso para esse recurso experimental. Se o recurso for finalizado, adicionaremos mais orientações neste site.

Ver também