Novidades em C# 15

C# 15 inclui as seguintes novas funcionalidades. Experimente estas funcionalidades usando a versão mais recente do Visual Studio 2026 insiders ou o SDK de pré-visualização do .NET 11:

C# 15 é a mais recente versão de pré-visualização de C#. As versões de pré-visualização do .NET 11 suportam C# 15. Para obter mais informações, consulte versão de linguagem C#.

Pode descarregar o mais recente SDK de pré-visualização do .NET 11 na página de downloads do .NET. Pode descarregar o Visual Studio 2026 Insiders, que inclui a SDK de prévia do .NET 11.

A página "Novidades em C#" adiciona novas funcionalidades quando estão disponíveis em versões públicas de pré-visualização. 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.

Pode encontrar quaisquer alterações significativas introduzidas em C# 15 no nosso artigo sobre alterações disruptivas.

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.

Argumentos de expressão de coleções

Pode passar argumentos ao construtor ou método de fábrica da coleção subjacente usando um with(...) elemento como primeiro elemento numa expressão de coleção. Esta funcionalidade permite-lhe especificar capacidade, comparadores ou outros parâmetros do construtor diretamente dentro da sintaxe da expressão da coleção.

O exemplo seguinte mostra como passar um argumento de capacidade a um List<T> construtor e um comparador a um HashSet<T>:

string[] values = ["one", "two", "three"];

// Pass capacity argument to List<T> constructor
List<string> names = [with(capacity: values.Length * 2), .. values];

// Pass comparer argument to HashSet<T> constructor
HashSet<string> set = [with(StringComparer.OrdinalIgnoreCase), "Hello", "HELLO", "hello"];
// set contains only one element because all strings are equal with OrdinalIgnoreCase

Para saber mais sobre argumentos de expressão de coleções, consulte o artigo de referência de linguagem sobre expressões de coleções ou a especificação de características. Para informações sobre o uso de argumentos de expressões de coleção em inicializadores de coleções, veja Inicializadores de Objetos e Coleções.

Tipos de União

C# 15 introduz tipos de união, que representam um valor que pode ser um de vários tipos de casos. Declare uma união com a union palavra-chave:

public record class Cat(string Name);
public record class Dog(string Name);
public record class Bird(string Name);

public union Pet(Cat, Dog, Bird);

As uniões fornecem conversões implícitas de cada tipo de caso, e o compilador garante que as expressões switch são exaustivas em todos os tipos de casos:

Pet pet = new Dog("Rex");

string name = pet switch
{
    Dog d => d.Name,
    Cat c => c.Name,
    Bird b => b.Name,
};

O runtime inclui os tipos UnionAttribute e IUnion começando com .NET 11 Preview 5. Algumas funcionalidades da especificação da proposta ainda não estão implementadas. Essas funcionalidades vão surgir em pré-visualizações futuras.

Para mais informações, veja Tipos de União na referência da linguagem ou na especificação de características.

Hierarquias fechadas

A partir de C# 15, podes aplicar o closed modificador a uma classe para declarar uma hierarquia fechada. Uma classe fechada só pode ter derivação no assembly onde é declarada, o que determina, em tempo de compilação, o conjunto das classes derivadas diretas:

public closed record class GateState;
public record class Closed : GateState;
public record class Open(float Percent) : GateState;

Como o compilador conhece todos os descendentes diretos, uma switch expressão que gere cada um é exaustiva e não necessita de um arm padrão:

string Describe(GateState state) => state switch
{
    Closed => "closed",
    Open(var percent) => $"{percent}% open",
    // No warning: every direct descendant of 'GateState' is handled.
};

O closed modificador é uma palavra-chave contextual. Uma closed classe é implícita abstract e não pode ser combinada com sealed, static, ou um modificador explícito abstract . A derivação não é transitiva: um descendente não fechado de uma classe fechada ainda pode ser derivado de noutros assemblies. Para alargar a verificação de exaustividade ao longo da hierarquia, marque também os descendentes intermediários closed.

Observação

Em C# 15 preview 5, o runtime ainda não é distribuído System.Runtime.CompilerServices.ClosedAttribute. Até que isso aconteça, todos os projetos que utilizam o closed modificador devem declarar o atributo em si:

namespace System.Runtime.CompilerServices;

[AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = false)]
public sealed class ClosedAttribute : Attribute { }

Para mais informações, consulte os padrões de modificador fechado e Hierarquia fechada na referência da linguagem, ou a especificação de funcionalidades. Pode copiar os exemplos desta secção, incluindo a alternativa ClosedAttribute, do projeto de fragmentos de código palavras-chave no repositório dotnet/docs do GitHub.