Dela via


Nyheter i C# 11

Följande funktioner har lagts till i C# 11:

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

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

Kommentar

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 .

Allmänna attribut

Du kan deklarera en allmän klass vars basklass är System.Attribute. Den här funktionen ger en mer praktisk syntax för attribut som kräver en System.Type parameter. Tidigare skulle du behöva skapa ett attribut som tar ett Type som konstruktorparameter:

// Before C# 11:
public class TypeAttribute : Attribute
{
   public TypeAttribute(Type t) => ParamType = t;

   public Type ParamType { get; }
}

Och för att tillämpa attributet använder du operatorn typeof :

[TypeAttribute(typeof(string))]
public string Method() => default;

Med den här nya funktionen kan du skapa ett allmänt attribut i stället:

// C# 11 feature:
public class GenericAttribute<T> : Attribute { }

Ange sedan typparametern för att använda attributet:

[GenericAttribute<string>()]
public string Method() => default;

Du måste ange alla typparametrar när du tillämpar attributet. Med andra ord måste den generiska typen vara helt konstruerad. I exemplet ovan kan tomma parenteser (( och )) utelämnas eftersom attributet inte har några argument.

public class GenericType<T>
{
   [GenericAttribute<T>()] // Not allowed! generic attributes must be fully constructed types.
   public string Method() => default;
}

Typargumenten måste uppfylla samma begränsningar som operatorn typeof . Typer som kräver metadataanteckningar tillåts inte. Följande typer tillåts till exempel inte som typparameter:

  • dynamic
  • string? (eller någon nullbar referenstyp)
  • (int X, int Y) (eller andra tuppeln typer med C# tuppeln syntax).

Dessa typer representeras inte direkt i metadata. De innehåller anteckningar som beskriver typen. I alla fall kan du använda den underliggande typen i stället:

  • object för dynamic.
  • stringstring?i stället för .
  • ValueTuple<int, int>(int X, int Y)i stället för .

Allmänt matematiskt stöd

Det finns flera språkfunktioner som möjliggör allmänt matematiskt stöd:

  • static virtual medlemmar i gränssnitt
  • kontrollerade användardefinierade operatorer
  • avslappnade skiftoperatorer
  • osignerad högerskiftsoperator

Du kan lägga till static abstract eller static virtual medlemmar i gränssnitt för att definiera gränssnitt som innehåller överbelastningsbara operatorer, andra statiska medlemmar och statiska egenskaper. Det primära scenariot för den här funktionen är att använda matematiska operatorer i generiska typer. Du kan till exempel implementera System.IAdditionOperators<TSelf, TOther, TResult> gränssnittet i en typ som implementerar operator +. Andra gränssnitt definierar andra matematiska operationer eller väldefinierade värden. Du kan lära dig mer om den nya syntaxen i artikeln om gränssnitt. Gränssnitt som innehåller static virtual metoder är vanligtvis allmänna gränssnitt. Dessutom deklarerar de flesta en begränsning för att typparametern implementerar det deklarerade gränssnittet.

Du kan lära dig mer och prova funktionen själv i självstudien Utforska statiska abstrakta gränssnittsmedlemmar eller förhandsversionsfunktionerna i .NET 6 – allmänt matematiskt blogginlägg.

Allmän matematik skapade andra krav på språket.

  • osignerad höger skiftoperator: Innan C# 11, för att tvinga fram ett osignerat högerskift, skulle du behöva omvandla alla signerade heltalstyper till en osignerad typ, utföra skiftet och sedan omvandla resultatet tillbaka till en signerad typ. Från och med C# 11 kan du använda operatorn >>>, den osignerade skiftoperatorn.
  • Krav för avslappnad skiftoperator: C# 11 tar bort kravet på att den andra operanden måste vara en int eller implicit konvertibel till int. Den här ändringen gör att typer som implementerar allmänna matematiska gränssnitt kan användas på dessa platser.
  • markerade och omarkerade användardefinierade operatorer: Utvecklare kan nu definiera checked och unchecked aritmetiska operatorer. Kompilatorn genererar anrop till rätt variant baserat på den aktuella kontexten. Du kan läsa mer om checked operatorer i artikeln om aritmetiska operatorer.

Numeriska IntPtr och UIntPtr

Och nintnuint skriver nu alias System.IntPtr och System.UIntPtr, respektive.

Nya radlinjer i stränginterpolationer

Texten inuti { tecknen och } för en stränginterpolation kan nu sträcka sig över flera rader. Texten mellan { markörer och } parsas som C#. Alla juridiska C#-filer, inklusive nya linjer, tillåts. Den här funktionen gör det enklare att läsa stränginterpolationer som använder längre C#-uttryck, till exempel mönstermatchningsuttryck switch eller LINQ-frågor.

Du kan läsa mer om funktionen newlines i artikeln om stränginterpolationer i språkreferensen.

Listmönster

Listmönster utökar mönstermatchning för att matcha sekvenser av element i en lista eller en matris. Är till exempel sequence is [1, 2, 3]true när sequence är en matris eller en lista med tre heltal (1, 2 och 3). Du kan matcha element med valfritt mönster, inklusive konstant, typ, egenskap och relationsmönster. Mönstret ignorera (_) matchar ett enskilt element, och det nya intervallmönstret (..) matchar alla sekvenser med noll eller fler element.

Du kan lära dig mer om listmönster i artikeln mönstermatchning i språkreferensen.

Förbättrad metodgruppkonvertering till ombud

C#-standarden för metodgruppkonverteringar innehåller nu följande objekt:

  • Konverteringen tillåts (men krävs inte) för att använda en befintlig ombudsinstans som redan innehåller dessa referenser.

Tidigare versioner av standarden förbjöd kompilatorn att återanvända det ombudsobjekt som skapats för en metodgruppkonvertering. C# 11-kompilatorn cachelagrar det ombudsobjekt som skapats från en metodgruppkonvertering och återanvänder det enskilda ombudsobjektet. Den här funktionen var först tillgänglig i Visual Studio 2022 version 17.2 som en förhandsversionsfunktion och i .NET 7 Preview 2.

Råa strängliteraler

Råsträngliteraler är ett nytt format för strängliteraler. Råsträngliteraler kan innehålla godtycklig text, inklusive blanksteg, nya rader, inbäddade citattecken och andra specialtecken utan att kräva escape-sekvenser. En rå strängliteral börjar med minst tre dubbla citattecken ("""). Det slutar med samma antal dubbla citattecken. Vanligtvis använder en rå strängliteral tre dubbla citattecken på en enda rad för att starta strängen och tre dubbla citattecken på en separat rad för att avsluta strängen. De nya raderna efter öppningscitatet och före slutcitatet ingår inte i det slutliga innehållet:

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.
    """;

Alla blanksteg till vänster om de avslutande dubbla citattecknarna tas bort från strängliteralen. Råsträngliteraler kan kombineras med stränginterpolation för att inkludera klammerparenteser i utdatatexten. Flera $ tecken anger hur många klammerparenteser som startar och avslutar interpolationen:

var location = $$"""
   You are at {{{Longitude}}, {{Latitude}}}
   """;

Föregående exempel anger att två klammerparenteser startar och avslutar en interpolation. Den tredje upprepade inledande och avslutande klammerparentesen ingår i utdatasträngen.

Du kan lära dig mer om råa strängliteraler i artikeln om strängar i programmeringsguiden och språkreferensartiklarna om strängliteraler och interpolerade strängar.

Automatisk standard-struct

C# 11-kompilatorn ser till att alla fält av en struct typ initieras till standardvärdet som en del av körningen av en konstruktor. Den här ändringen innebär att alla fält eller automatiska egenskaper som inte initieras av en konstruktor initieras automatiskt av kompilatorn. Structs där konstruktorn inte definitivt tilldelar alla fält kompileras nu, och alla fält som inte uttryckligen initieras anges till deras standardvärde. Du kan läsa mer om hur den här ändringen påverkar struct-initieringen i artikeln om structs.

Mönstermatchning Span<char> eller ReadOnlySpan<char> på en konstant string

Du har kunnat testa om ett string har ett specifikt konstant värde med mönstermatchning för flera versioner. Nu kan du använda samma mönstermatchningslogik med variabler som är Span<char> eller ReadOnlySpan<char>.

Utökat namn på omfång

Typparameternamn och parameternamn finns nu i omfånget när de används i ett nameof uttryck i en attributdeklaration för den metoden. Den här funktionen innebär att du kan använda operatorn nameof för att ange namnet på en metodparameter i ett attribut i metoden eller parameterdeklarationen. Den här funktionen är oftast användbar för att lägga till attribut för nullbar analys.

UTF-8 strängliteraler

Du kan ange suffixet u8 på en strängliteral för att ange KODning av UTF-8-tecken. Om programmet behöver UTF-8-strängar, för HTTP-strängkonstanter eller liknande textprotokoll, kan du använda den här funktionen för att förenkla skapandet av UTF-8-strängar.

Du kan lära dig mer om UTF-8 strängliteraler i avsnittet strängliteral i artikeln om inbyggda referenstyper.

Obligatoriska medlemmar

Du kan lägga till modifieraren i required egenskaper och fält för att framtvinga konstruktorer och anropare för att initiera dessa värden. System.Diagnostics.CodeAnalysis.SetsRequiredMembersAttribute Kan läggas till i konstruktorer för att informera kompilatorn om att en konstruktor initierar alla nödvändiga medlemmar.

Mer information om nödvändiga medlemmar finns i avsnittet endast init i egenskapsartikeln.

ref fält och ref scoped variabler

Du kan deklarera ref fält i en ref struct. Detta stöder typer som System.Span<T> utan särskilda attribut eller dolda interna typer.

Du kan lägga till modifieraren i scoped valfri ref deklaration. Detta begränsar omfånget där referensen kan komma ifrån.

Fillokala typer

Från och med C# 11 kan du använda file åtkomstmodifieraren för att skapa en typ vars synlighet är begränsad till källfilen där den deklareras. Den här funktionen hjälper källgeneratorförfattare att undvika namngivningskollisioner. Du kan läsa mer om den här funktionen i artikeln om filomfattningstyper i språkreferensen.

Se även