Dela via


Nyheter i C# 14

C# 14 innehåller följande nya funktioner. Du kan prova de här funktionerna med den senaste Visual Studio 2022-versionen eller .NET 10 SDK:

C# 14 stöds på .NET 10. Mer information finns i C#-språkversioner.

Du kan ladda ned den senaste .NET 10 SDK från nedladdningssidan för .NET. Du kan också ladda ned Visual Studio 2022, som innehåller .NET 10 SDK.

Nya funktioner läggs till på sidan "Nyheter i C#" när de är tillgängliga i offentliga förhandsversioner. Arbetsuppsättningsavsnittet på roslyn-funktionsstatussidan spårar när kommande funktioner slås samman till huvudgrenen. Den här artikeln uppdaterades senast för .NET 10 Preview 1.

Du hittar alla brytande ändringar som introduceras i C# 14 i vår artikel om brytande ändringar.

Anmärkning

Vi är intresserade av din feedback om dessa funktioner. Om du får problem med någon av dessa nya funktioner skapar du ett nytt problemdotnet/roslyn-lagringsplatsen .

Utvidgningsmedlemmar

C# 14 lägger till ny syntax för att definiera tilläggsmedlemmar. Med den nya syntaxen kan du deklarera tilläggsegenskaper utöver tilläggsmetoder. Du kan också deklarera tilläggsmedlemmar som utökar typen i stället för en instans av typen. Med andra ord kan dessa nya tilläggsmedlemmar visas som statiska medlemmar av den typ som du utökar. I följande kodexempel visas ett exempel på de olika typer av tilläggsmedlemmar som du kan deklarera:

public static class Enumerable
{
    // Extension block
    extension<TSource>(IEnumerable<TSource> source) // extension members for IEnumerable<TSource>
    {
        // Extension property:
        public bool IsEmpty => !source.Any();
        // Extension indexer:
        public TSource this[int index] => source.Skip(index).First();

        // 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>();
    }
}

Medlemmarna i det första tilläggsblocket anropas som om de är instansmedlemmar IEnumerable<TSource>i , till exempel sequence.IsEmpty. Medlemmarna i det andra tilläggsblocket anropas som om de är statiska medlemmar IEnumerable<TSource>i , till exempel IEnumerable<int>.Identity.

Du kan läsa mer information genom att läsa artikeln om tilläggsmedlemmar i programmeringsguiden, språkreferensartikeln om nyckelordetextension och funktionsspecifikationen för den nya tilläggsfunktionen medlemmar.

Nyckelordet field

Med token field kan du skriva en egenskapsåtkomsttext utan att deklarera ett explicit bakgrundsfält. Token field ersätts med ett kompilatorsyntetiserat bakgrundsfält.

Om du till exempel tidigare ville se till att en string egenskap inte kunde anges till nullmåste du deklarera ett bakgrundsfält och implementera båda åtkomsterna:

private string _msg;
public string Message
{
    get => _msg;
    set => _msg = value ?? throw new ArgumentNullException(nameof(value));
}

Nu kan du förenkla koden för att:

public string Message
{
    get;
    set => field = value ?? throw new ArgumentNullException(nameof(value));
}

Du kan deklarera en kropp för en eller båda accessorerna för en fältbaserad egenskap.

Det finns en potentiell förändring som bryter kompatibilitet eller förvirring vid kodläsning i typer som innehåller en symbol med namnet field. Du kan använda @field eller this.field för att skilja mellan nyckelordet field och identifieraren, eller så kan du byta namn på den aktuella field symbolen för att ge bättre skillnad.

Om du provar den här funktionen och har feedback kommenterar du funktionsproblemet på lagringsplatsen csharplang .

Det field kontextuella nyckelordet finns i C# 13 som en förhandsgranskningsfunktion.

Implicita intervallkonverteringar

C# 14 introducerar förstklassigt stöd för System.Span<T> och System.ReadOnlySpan<T> på språket. Det här stödet omfattar nya implicita konverteringar som möjliggör mer naturlig programmering med dessa typer.

Span<T> och ReadOnlySpan<T> används på många viktiga sätt i C# och körtiden. Introduktionen förbättrar prestandan utan att riskera säkerheten. C# 14 identifierar relationen och stöder vissa konverteringar mellan ReadOnlySpan<T>, Span<T>och T[]. Span-typerna kan vara tilläggsmetodmottagare, kombinera med andra konverteringar och hjälpa till med generiska typinferensscenarier.

Du hittar listan över implicita span-konverteringar i artikeln om inbyggda typer i språkreferensavsnittet. Du kan läsa mer information genom att läsa funktionsspecifikationen för first class span-typer.

Obundna generiska typer och nameof

Från och med C# 14 kan argumentet till nameof vara en obunden generisk typ. Till exempel utvärderas nameof(List<>) till List. I tidigare versioner av C#kunde endast stängda generiska typer, till exempel List<int>, användas för att returnera List namnet.

Enkla lambda-parametrar med modifierare

Du kan lägga till parametermodifierare, till exempel scoped, ref, in, outeller ref readonly till lambda-uttrycksparametrar utan att ange parametertypen:

delegate bool TryParse<T>(string text, out T result);
// ...
TryParse<int> parse1 = (text, out result) => Int32.TryParse(text, out result);

Tidigare tilläts endast tillägg av modifierare när parameterdeklarationerna inkluderade parametrarnas typer. Föregående deklaration skulle kräva typer på alla parametrar:

TryParse<int> parse2 = (string text, out int result) => Int32.TryParse(text, out result);

Modifieraren params kräver fortfarande en uttryckligen angiven parameterlista.

Du kan läsa mer om dessa ändringar i artikeln om lambda-uttryck i C#-språkreferensen.

Fler delvisa medlemmar

Nu kan du deklarera instanskonstruktorer och händelser som partiella medlemmar.

Partiella konstruktorer och partiella händelser måste innehålla exakt en definierande deklaration och en implementeringsdeklaration.

Endast implementeringsdeklarationen för en partiell konstruktor kan innehålla en konstruktorinitierare: this() eller base(). Endast en partiell typdeklaration kan innehålla den primära konstruktorsyntaxen.

Implementeringsdeklarationen för en partiell händelse måste innehålla add och remove accessorer. Den definierande deklarationen deklarerar en fältliknande händelse.

Användardefinierad sammansatt tilldelning

Du kan läsa mer i funktionsspecifikationen för användardefinierad sammansatt tilldelning.

Nullvillkorsstyrd tilldelning

Operatorerna för null-conditional medlemsåtkomst, ?. och ?[], kan nu användas på vänstra sidan av en tilldelning eller sammansatt tilldelning.

Innan C# 14 måste du null-kontrollera en variabel innan du tilldelar till en egenskap:

if (customer is not null)
{
    customer.Order = GetCurrentOrder();
}

Du kan förenkla föregående kod med hjälp av operatorn ?. :

customer?.Order = GetCurrentOrder();

Operatorns = högra sida utvärderas endast när den vänstra sidan inte är null. Om customer är null anropar GetCurrentOrderkoden inte .

Förutom tilldelning kan du använda nullbetingade medlemsåtkomstoperatorer med sammansatta tilldelningsoperatorer (+=, -= och andra). Men inkrement och dekrement, ++ och --, är inte tillåtna.

Du kan läsa mer i språkreferensartikeln om villkorlig medlemsåtkomst och funktionsspecifikationen för null-villkorsstyrd tilldelning.

Se även