O que há de novo no C# 11
Os seguintes recursos foram adicionados ao C# 11:
- Literais de cadeia de caracteres brutos
- Suporte matemático genérico
- Atributos genéricos
- Literais de cadeia UTF-8
- Novas linhas em expressões de interpolação de cadeia de caracteres
- Padrões de lista
- Tipos de arquivo local
- Membros obrigatórios
- Estruturas padrão automática
- Correspondência
Span<char>
de padrão em uma constantestring
- Âmbito alargado
nameof
- IntPtr numérico
ref
campos escoped ref
- Conversão de grupo de método melhorada para delegado
- Onda de alerta 7
C# 11 é suportado no .NET 7. Para obter mais informações, consulte Versionamento de linguagem C#.
Você pode baixar o SDK mais recente do .NET 7 na página de downloads do .NET. Você também pode baixar o Visual Studio 2022, que inclui o SDK do .NET 7.
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 .
Atributos genéricos
Você pode declarar uma classe genérica cuja classe base é System.Attribute. Esse recurso fornece uma sintaxe mais conveniente para atributos que exigem um System.Type parâmetro. Anteriormente, você precisaria criar um atributo que tomasse um Type
como parâmetro de construtor:
// Before C# 11:
public class TypeAttribute : Attribute
{
public TypeAttribute(Type t) => ParamType = t;
public Type ParamType { get; }
}
E para aplicar o atributo, use o typeof
operador:
[TypeAttribute(typeof(string))]
public string Method() => default;
Usando esse novo recurso, você pode criar um atributo genérico:
// C# 11 feature:
public class GenericAttribute<T> : Attribute { }
Em seguida, especifique o parâmetro type para usar o atributo:
[GenericAttribute<string>()]
public string Method() => default;
Você deve fornecer todos os parâmetros de tipo ao aplicar o atributo. Em outras palavras, o tipo genérico deve ser totalmente construído.
No exemplo acima, os parênteses vazios ((
e )
) podem ser omitidos, pois o atributo não tem argumentos.
public class GenericType<T>
{
[GenericAttribute<T>()] // Not allowed! generic attributes must be fully constructed types.
public string Method() => default;
}
Os argumentos de tipo devem satisfazer as mesmas restrições que o typeof
operador. Tipos que exigem anotações de metadados não são permitidos. Por exemplo, os seguintes tipos não são permitidos como o parâmetro type:
dynamic
string?
(ou qualquer tipo de referência anulável)(int X, int Y)
(ou qualquer outro tipo de tupla usando sintaxe de tupla C#).
Esses tipos não são representados diretamente nos metadados. Eles incluem anotações que descrevem o tipo. Em todos os casos, você pode usar o tipo subjacente:
object
paradynamic
.string
em vez destring?
.ValueTuple<int, int>
em vez de(int X, int Y)
.
Suporte matemático genérico
Existem vários recursos de linguagem que permitem o suporte matemático genérico:
static virtual
Membros em interfaces- operadores definidos pelo usuário verificados
- Operadores de turno relaxados
- operador de turno à direita não assinado
Você pode adicionar static abstract
ou static virtual
membros em interfaces para definir interfaces que incluem operadores sobrecarregados, outros membros estáticos e propriedades estáticas. O cenário principal para esse recurso é usar operadores matemáticos em tipos genéricos. Por exemplo, você pode implementar a System.IAdditionOperators<TSelf, TOther, TResult>
interface em um tipo que implementa operator +
o . Outras interfaces definem outras operações matemáticas ou valores bem definidos. Você pode aprender sobre a nova sintaxe no artigo sobre interfaces. As interfaces que incluem static virtual
métodos são normalmente interfaces genéricas. Além disso, a maioria declarará uma restrição de que o parâmetro type implementa a interface declarada.
Você pode aprender mais e experimentar o recurso no tutorial Explore static abstract interface members, ou no Preview features in .NET 6 – generic math blog post.
A matemática genérica criou outros requisitos sobre a linguagem.
- operador de deslocamento à direita não assinado: Antes do C# 11, para forçar um deslocamento para a direita não assinado, você precisaria converter qualquer tipo de inteiro assinado para um tipo não assinado, executar o turno e, em seguida, converter o resultado de volta para um tipo assinado. A partir do C# 11, você pode usar o , o operador de turno
>>>
não assinado. - Requisitos do operador de turno relaxado: o C# 11 remove o requisito de que o segundo operando deve ser um
int
ou implicitamente conversível emint
. Essa alteração permite que tipos que implementam interfaces matemáticas genéricas sejam usados nesses locais. - operadores definidos pelo usuário verificados e não verificados: os desenvolvedores agora podem definir
checked
operadoresunchecked
aritméticos. O compilador gera chamadas para a variante correta com base no contexto atual. Você pode ler mais sobrechecked
operadores no artigo sobre operadores aritméticos.
Numérico IntPtr
e UIntPtr
Os nint
e nuint
tipos agora alias System.IntPtr e System.UIntPtr, respectivamente.
Novas linhas em interpolações de cadeia
O texto dentro dos {
e }
caracteres para uma interpolação de cadeia de caracteres agora pode abranger várias linhas. O texto entre os marcadores e }
é analisado {
como C#. Qualquer C# legal, incluindo novas linhas, é permitido. Esse recurso facilita a leitura de interpolações de cadeia de caracteres que usam expressões C# mais longas, como expressões de correspondência switch
de padrões ou consultas LINQ.
Você pode saber mais sobre o recurso de novas linhas no artigo interpolações de cadeia de caracteres na referência de idioma.
Padrões de lista
Os padrões de lista estendem a correspondência de padrões para corresponder a sequências de elementos em uma lista ou matriz. Por exemplo, sequence is [1, 2, 3]
é true
quando o sequence
é uma matriz ou uma lista de três inteiros (1, 2 e 3). Você pode combinar elementos usando qualquer padrão, incluindo constante, tipo, propriedade e padrões relacionais. O padrão de descarte (_
) corresponde a qualquer elemento único, e o novo padrão de intervalo (..
) corresponde a qualquer sequência de zero ou mais elementos.
Você pode saber mais detalhes sobre padrões de lista no artigo de correspondência de padrões na referência de idioma.
Conversão de grupo de método melhorada para delegado
O padrão C# em conversões de grupo de método agora inclui o seguinte item:
- A conversão é permitida (mas não necessária) para usar uma instância delegada existente que já contenha essas referências.
As versões anteriores do padrão proibiam o compilador de reutilizar o objeto delegado criado para uma conversão de grupo de métodos. O compilador C# 11 armazena em cache o objeto delegado criado a partir de uma conversão de grupo de métodos e reutiliza esse único objeto delegado. Esse recurso foi disponibilizado pela primeira vez no Visual Studio 2022 versão 17.2 como um recurso de visualização e no .NET 7 Preview 2.
Literais de cadeia de caracteres brutos
Literais de cadeia de caracteres brutos são um novo formato para literais de cadeia de caracteres. Os literais de cadeia de caracteres brutos podem conter texto arbitrário, incluindo espaço em branco, novas linhas, aspas incorporadas e outros caracteres especiais sem exigir sequências de escape. Um literal de cadeia de caracteres bruto começa com pelo menos três caracteres de aspas duplas ("""). Termina com o mesmo número de caracteres de aspas duplas. Normalmente, um literal de cadeia de caracteres bruto usa três aspas duplas em uma única linha para iniciar a cadeia de caracteres e três aspas duplas em uma linha separada para finalizar a cadeia de caracteres. As novas linhas que seguem a cotação de abertura e precedem a cotação de encerramento não estão incluídas no conteúdo final:
string longMessage = """
This is a long message.
It has several lines.
Some are indented
more than others.
Some should start at the first column.
Some have "quoted text" in them.
""";
Qualquer espaço em branco à esquerda das aspas duplas de fechamento será removido do literal da cadeia de caracteres. Literais de cadeia de caracteres brutos podem ser combinados com interpolação de cadeia de caracteres para incluir chaves no texto de saída. Vários $
caracteres indicam quantas chaves consecutivas iniciam e terminam a interpolação:
var location = $$"""
You are at {{{Longitude}}, {{Latitude}}}
""";
O exemplo anterior especifica que duas chaves iniciam e terminam uma interpolação. A terceira chave de abertura e fechamento repetida é incluída na cadeia de caracteres de saída.
Você pode aprender mais sobre literais de cadeia de caracteres brutos no artigo sobre cadeias de caracteres no guia de programação e os artigos de referência de linguagem sobre literais de cadeia de caracteres e cadeias de caracteres interpoladas.
Estrutura padrão automática
O compilador C# 11 garante que todos os campos de um struct
tipo sejam inicializados com seu valor padrão como parte da execução de um construtor. Essa alteração significa que qualquer campo ou propriedade automática não inicializada por um construtor é automaticamente inicializada pelo compilador. Structs onde o construtor não atribui definitivamente todos os campos agora compilados, e todos os campos não explicitamente inicializados são definidos como seu valor padrão. Você pode ler mais sobre como essa alteração afeta a inicialização de struct no artigo sobre structs.
Correspondência Span<char>
de padrão ou ReadOnlySpan<char>
em uma constante string
Você pôde testar se um string
tinha um valor constante específico usando a correspondência de padrões para várias versões. Agora, você pode usar a mesma lógica de correspondência de padrões com variáveis que são Span<char>
ou ReadOnlySpan<char>
.
Nome alargado do âmbito de aplicação
Nomes de parâmetros de tipo e nomes de parâmetros agora estão no escopo quando usados em uma nameof
expressão em uma declaração de atributo nesse método. Esse recurso significa que você pode usar o nameof
operador para especificar o nome de um parâmetro de método em um atributo na declaração de método ou parâmetro. Esse recurso geralmente é útil para adicionar atributos para análise anulável.
Literais de cadeia UTF-8
Você pode especificar o sufixo u8
em um literal de cadeia de caracteres para especificar a codificação de caracteres UTF-8. Se seu aplicativo precisa de cadeias de caracteres UTF-8, para constantes de cadeia HTTP ou protocolos de texto semelhantes, você pode usar esse recurso para simplificar a criação de cadeias de caracteres UTF-8.
Você pode saber mais sobre literais de cadeia UTF-8 na seção literal de cadeia de caracteres do artigo sobre tipos de referência internos.
Membros obrigatórios
Você pode adicionar o required
modificador a propriedades e campos para impor construtores e chamadores para inicializar esses valores. O System.Diagnostics.CodeAnalysis.SetsRequiredMembersAttribute pode ser adicionado aos construtores para informar o compilador que um construtor inicializa todos os membros necessários.
Para obter mais informações sobre os membros necessários, consulte a seção somente inicialização do artigo de propriedades.
ref
Campos e ref scoped
variáveis
Você pode declarar ref
campos dentro de um ref struct
arquivo . Isso suporta tipos como System.Span<T> sem atributos especiais ou tipos internos ocultos.
Você pode adicionar o scoped
modificador a qualquer ref
declaração. Isso limita o escopo para onde a referência pode escapar.
Tipos locais de arquivo
A partir do C# 11, você pode usar o modificador de file
acesso para criar um tipo cuja visibilidade tem como escopo o arquivo de origem no qual ele é declarado. Esse recurso ajuda os autores do gerador de código-fonte a evitar colisões de nomes. Você pode saber mais sobre esse recurso no artigo sobre tipos de escopo de arquivo na referência de idioma.