Share via


Nieuw in C# 14

C# 14 bevat de volgende nieuwe functies. U kunt deze functies proberen met behulp van de nieuwste Versie van Visual Studio 2022 of de .NET 10 SDK:

C# 14 wordt ondersteund op .NET 10. Zie C#-taalversiebeheer voor meer informatie.

U kunt de nieuwste .NET 10 SDK downloaden via de .NET-downloadpagina. U kunt ook Visual Studio 2022 downloaden, waaronder de .NET 10 SDK.

Nieuwe functies worden toegevoegd aan de pagina 'Wat is er nieuw in C#' wanneer deze beschikbaar zijn in openbare preview-versies. In de werksetsectie van de Roslyn-functiestatuspagina wordt bijgehouden wanneer toekomstige functies worden samengevoegd in de hoofdbranch. Dit artikel is voor het laatst bijgewerkt voor .NET 10 Preview 1.

U vindt alle belangrijke wijzigingen die zijn geïntroduceerd in C# 14 in ons artikel over belangrijke wijzigingen.

Notitie

We zijn geïnteresseerd in uw feedback over deze functies. Als u problemen ondervindt met een van deze nieuwe functies, maakt u een nieuw probleem in de dotnet-/roslyn-opslagplaats .

Uitbreidingsleden

C# 14 voegt nieuwe syntaxis toe om extensieleden te definiëren. Met de nieuwe syntaxis kunt u uitbreidingseigenschappen naast extensiemethoden declareren. U kunt ook extensieleden declareren die het type uitbreiden in plaats van een exemplaar van het type. Met andere woorden, deze nieuwe extensieleden kunnen worden weergegeven als statische leden van het type dat u uitbreidt. In het volgende codevoorbeeld ziet u een voorbeeld van de verschillende soorten extensieleden die u kunt declareren:

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

De leden in het eerste extensieblok worden aangeroepen alsof ze instantieleden van IEnumerable<TSource> zijn, zoals bij sequence.IsEmpty. De leden in het tweede extensieblok worden aangeroepen alsof ze statische leden zijn van IEnumerable<TSource>, bijvoorbeeld IEnumerable<int>.Identity.

Meer informatie vindt u in het artikel over extensieleden in de programmeerhandleiding, het taalverwijzingsartikel over het en de extension voor de nieuwe functie voor extensieleden.

Het trefwoord field

Met het token field kunt u een accessorfunctie voor een eigenschap schrijven zonder een expliciet ondersteunend veld te declareren. Het token field wordt vervangen door een gesynthetiseerd backingveld van de compiler.

Voorheen moest u bijvoorbeeld, als u wilde zorgen dat een string-eigenschap niet op nullkon worden ingesteld, een backingveld declareren en beide toegangsmethoden implementeren.

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

U kunt uw code nu vereenvoudigen naar:

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

U kunt een body of implementatie opgeven voor een of beide accessors van een eigenschap met veldondersteuning.

Er is een potentiële wijziging die fouten of verwarring kan veroorzaken bij het lezen van code in typen die ook een symbool met de naam field bevatten. U kunt @field of this.field gebruiken om onderscheid te maken tussen het field trefwoord en de id, of u kunt de naam van het huidige field symbool wijzigen om beter onderscheid te maken.

Als u deze functie probeert en feedback hebt, kunt u reageren op het functieprobleem in de csharplang opslagplaats.

Het field contextuele trefwoord bevindt zich in C# 13 als preview-functie.

Impliciete spanconversies

C# 14 introduceert eersteklas ondersteuning voor System.Span<T> en System.ReadOnlySpan<T> in de taal. Deze ondersteuning omvat nieuwe impliciete conversies die meer natuurlijke programmering met deze typen mogelijk maken.

Span<T> en ReadOnlySpan<T> worden op veel belangrijke manieren gebruikt in C# en de runtime. Hun introductie verbetert de prestaties zonder risicovolle veiligheid. C# 14 herkent de relatie en ondersteunt enkele conversies tussen ReadOnlySpan<T>, Span<T>en T[]. De spantypen kunnen ontvangers van extensiemethoden zijn, combineren met andere conversies en bijstaan in scenario's voor algemene typedeductie.

U vindt de lijst met impliciete spanconversies in het artikel over ingebouwde typen in de sectie taalverwijzing. Meer informatie vindt u door de functiespecificatie voor spantypen van de eerste klasse te lezen.

Niet-afhankelijke algemene typen en nameof

Vanaf C# 14 kan het argument voor nameof een niet-afhankelijk algemeen type zijn. Bijvoorbeeld, nameof(List<>) evalueert tot List. In eerdere versies van C# kunnen alleen gesloten algemene typen, zoals List<int>, worden gebruikt om de List naam te retourneren.

Eenvoudige lambdaparameters met modifiers

U kunt parameteraanpassingen toevoegen, zoals scoped, ref, in, outof ref readonly aan lambda-expressieparameters zonder het parametertype op te geven:

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

Voorheen werd het toevoegen van modifiers alleen toegestaan toen de parameterdeclaraties de typen voor de parameters bevatten. Voor de voorgaande declaratie zijn typen vereist voor alle parameters:

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

De params wijzigingsfunctie vereist nog steeds een expliciet getypte parameterlijst.

Meer informatie over deze wijzigingen vindt u in het artikel over lambda-expressies in de C#-taalreferentie.

Meer gedeeltelijke leden

U kunt nu instantieconstructors en gebeurtenissen declareren als gedeeltelijke leden .

Gedeeltelijke constructors en gedeeltelijke gebeurtenissen moeten exact één definiërende declaratie en één implementerende declaratie bevatten.

Alleen de implementatiedeclaratie van een gedeeltelijke constructor kan een initialisatiefunctie voor de constructor bevatten: this() of base(). Slechts één gedeeltelijke typedeclaratie kan de syntaxis van de primaire constructor bevatten.

De uitvoeringsdeclaratie van een gedeeltelijke gebeurtenis moet add en remove accessors bevatten. De definiërende declaratie declareert een veldachtige gebeurtenis.

Gebruikersgedefinieerde samengestelde toewijzing

Meer informatie vindt u in de functiespecificatie voor door de gebruiker gedefinieerde samengestelde toewijzing.

Null-voorwaardelijke toewijzing

De null-voorwaardelijke lidtoegangsoperatoren ?. en ?[] kunnen nu aan de linkerkant van een toewijzing of samengestelde toewijzing worden gebruikt.

Voor C# 14 moest u een variabele null controleren voordat u deze toewijst aan een eigenschap:

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

U kunt de voorgaande code vereenvoudigen met behulp van de ?. operator:

customer?.Order = GetCurrentOrder();

De rechterkant van de = operator wordt alleen geëvalueerd wanneer de linkerkant niet null is. Als customer null is, wordt GetCurrentOrder niet aangeroepen.

Naast de toewijzing kunt u ook null-voorwaardelijke lidtoegangsoperatoren gebruiken in combinatie met samengestelde toewijzingsoperatoren (+=, -= en andere). Echter, verhogen en verlagen, ++ en --, zijn niet toegestaan.

U kunt meer leren in het naslagartikel over de voorwaardelijke ledenbenadering en de kenmerkenspecificatie voor de null-voorwaardelijke toewijzing.

Zie ook