Nyheter i C# 13
C# 13 innehåller följande nya funktioner. Du kan prova dessa funktioner med den senaste Visual Studio 2022 version eller .NET 9 SDK:
-
params
samlingar -
Ny
lock
typ och semantik. -
Ny escape-sekvens –
\e
. - Förbättringar av naturlig typ av metodgrupp
- Implicit indexerareåtkomst i objektinitierare
-
Aktivera lokala
ref
ochunsafe
kontexter i iteratorer och asynkrona metoder -
Aktivera
ref struct
typer för att implementera gränssnitt. - Tillåt referensstruktureringstyper som argument för typparametrar i generiska objekt.
-
Partiella egenskaper och indexerare tillåts nu i
partial
typer. - Prioritet för överlagringslösning gör det möjligt för biblioteksförfattare att utse en överlagringslösning som att vara bättre än andra.
Från och med Visual Studio 17.12 innehåller C# 13 field
sammanhangsberoende nyckelord som en förhandsgranskningsfunktion.
C# 13 stöds på .NET 9. Mer information finns i C#-språkversioner.
Du kan ladda ned den senaste .NET 9 SDK från sidan .NET-nedladdningar. Du kan också ladda ned Visual Studio 2022, som innehåller .NET 9 SDK.
Nya funktioner läggs till på sidan "Nyheter i C#" när de är tillgängliga i offentliga förhandsversioner. Den arbetsuppsättningen delen av roslyn-funktionsstatussidan spårar när kommande funktioner slås samman till huvudgrenen.
Du hittar eventuella icke-bakåtkompatibla ändringar som introduceras i C# 13 i vår artikel om icke-bakåtkompatibla ändringar.
Not
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 problem i dotnet/roslyn lagringsplats.
params
samlingar
Den params
modifieraren är inte begränsad till matristyper. Nu kan du använda params
med valfri identifierad samlingstyp, inklusive System.Span<T>, System.ReadOnlySpan<T>och typer som implementerar System.Collections.Generic.IEnumerable<T> och har en Add
-metod. Förutom betongtyper kan gränssnitten System.Collections.Generic.IEnumerable<T>, System.Collections.Generic.IReadOnlyCollection<T>, System.Collections.Generic.IReadOnlyList<T>, System.Collections.Generic.ICollection<T>och System.Collections.Generic.IList<T> också användas.
När en gränssnittstyp används syntetiserar kompilatorn lagringen för de angivna argumenten. Du kan läsa mer i funktionsspecifikationen för samlingar params
.
Metoddeklarationer kan till exempel deklarera intervall som params
parametrar:
public void Concat<T>(params ReadOnlySpan<T> items)
{
for (int i = 0; i < items.Length; i++)
{
Console.Write(items[i]);
Console.Write(" ");
}
Console.WriteLine();
}
Nytt låsobjekt
.NET 9-körningen innehåller en ny typ för trådsynkronisering, System.Threading.Lock typ. Den här typen ger bättre trådsynkronisering via dess API. Metoden Lock.EnterScope() anger ett exklusivt omfång. Den ref struct
som returneras från det som stöder Dispose()
-mönstret för att lämna det exklusiva omfånget.
C#-lock
-instruktionen identifierar om låsets mål är ett Lock
objekt. I så fall använder den det uppdaterade API:et i stället för det traditionella API:et med hjälp av System.Threading.Monitor. Kompilatorn identifierar också om du konverterar ett Lock
objekt till en annan typ och den Monitor
baserade koden genereras. Du kan läsa mer i funktionsspecifikationen för nya låsobjektet.
Med den här funktionen kan du få fördelarna med den nya bibliotekstypen genom att ändra vilken typ av objekt du lock
. Ingen annan kod behöver ändras.
Ny escape-sekvens
Du kan använda \e
som en teckenliteral escape-sekvens för ESCAPE
-tecknet Unicode U+001B
. Tidigare använde du \u001b
eller \x1b
. Att använda \x1b
rekommenderades inte eftersom om nästa tecken efter 1b
var giltiga hexadecimala siffror blev dessa tecken en del av escape-sekvensen.
Naturlig typ av metodgrupp
Den här funktionen gör små optimeringar för upplösning av överbelastning som involverar metodgrupper. En metodgrupp är en metod och alla dess överlagringar med samma namn. Det tidigare beteendet var att kompilatorn skulle konstruera hela uppsättningen kandidatmetoder för en metodgrupp. Om en naturlig typ behövdes fastställdes den naturliga typen från den fullständiga uppsättningen kandidatmetoder.
Det nya beteendet är att beskära uppsättningen kandidatmetoder inom varje område och ta bort de kandidatmetoder som inte är tillämpliga. De borttagna metoderna är vanligtvis generiska metoder med fel aritet eller begränsningar som inte är uppfyllda. Processen fortsätter endast till nästa yttre nivå om inga kandidatmetoder hittas. Den här processen följer närmare den allmänna algoritmen för överbelastningsmatchning. Om alla kandidatmetoder som hittas i ett visst omfång inte matchar har metodgruppen ingen naturlig typ.
Du kan läsa information om ändringarna i förslagsspecifikationen.
Implicit indexåtkomst
Den implicita indexoperatorn "från slutet", ^
, tillåts nu i ett objektinitieringsuttryck. Du kan till exempel nu initiera en matris i en objektinitierare enligt följande kod:
public class TimerRemaining
{
public int[] buffer { get; set; } = new int[10];
}
var countdown = new TimerRemaining()
{
buffer =
{
[^1] = 0,
[^2] = 1,
[^3] = 2,
[^4] = 3,
[^5] = 4,
[^6] = 5,
[^7] = 6,
[^8] = 7,
[^9] = 8,
[^10] = 9
}
};
Klassen TimerRemaining
innehåller en buffer
matris som initierats till en längd av 10. I föregående exempel tilldelas värden till den här matrisen med indexoperatorn "från slutet" (^
), vilket effektivt skapar en matris som räknas ned från 9 till 0.
I versioner före C# 13 kan ^
-operatorn inte användas i en objektinitierare. Du måste indexera elementen från början.
ref
och unsafe
i iteratorer och metoderna async
Med den här funktionen och följande två funktioner kan ref struct
typer använda nya konstruktioner. Du kommer inte att använda dessa om du inte skriver egna ref struct
typer. Det är mer sannolikt att du kommer att se en indirekt fördel när System.Span<T> och System.ReadOnlySpan<T> får fler funktioner.
Före C# 13 kunde iteratormetoder (metoder som använder yield return
) och async
metoder inte deklarera lokala ref
variabler, och de kunde inte heller ha en unsafe
kontext.
I C# 13 kan async
metoder deklarera ref
lokala variabler eller lokala variabler av ref struct
typ. Dessa variabler kan dock inte nås över en await
gräns. De kan inte heller nås över en yield return
gräns.
Med den här avslappnade begränsningen kan kompilatorn på ett verifierbart säkert sätt använda ref
lokala variabler och ref struct
typer på fler platser. Du kan på ett säkert sätt använda typer som System.ReadOnlySpan<T> i dessa metoder. Kompilatorn meddelar dig om du bryter mot säkerhetsreglerna.
På samma sätt tillåter C# 13 unsafe
kontexter i iteratormetoder. Alla yield return
- och yield break
-uttalanden måste dock vara i säkra kontexter.
allows ref struct
Innan C# 13 kunde ref struct
typer inte deklareras som typargument för en allmän typ eller metod. Nu kan allmänna typdeklarationer lägga till en anti-begränsning, allows ref struct
. Det här antivillkoret deklarerar att typargumentet som anges för den typparametern kan vara en ref struct
typ. Kompilatorn tillämpar referenssäkerhetsregler på alla instanser av den typen parameter.
Du kan till exempel deklarera en allmän typ som följande kod:
public class C<T> where T : allows ref struct
{
// Use T as a ref struct:
public void M(scoped T p)
{
// The parameter p must follow ref safety rules
}
}
På så sätt kan typer som System.Span<T> och System.ReadOnlySpan<T> användas med generiska algoritmer, i förekommande fall. Du kan läsa mer i uppdateringarna för where
och i artikeln i programmeringsguiden om generiska begränsningar.
ref struct
gränssnitt
Innan C# 13 tilläts inte ref struct
typer att implementera gränssnitt. Från och med C# 13 kan de det. Du kan deklarera att en ref struct
typ implementerar ett gränssnitt. Men för att säkerställa referenssäkerhetsregler kan en ref struct
typ inte konverteras till en gränssnittstyp. Den konverteringen är en boxningskonvertering och kan bryta mot referenssäkerheten. Explicita gränssnittsmetoddeklarationer i en ref struct
kan endast nås via en typparameter där den typparametern allows ref struct
. Dessutom måste ref struct
typer implementera alla metoder som deklarerats i ett gränssnitt, inklusive de metoder som har en standardimplementering.
Lär dig mer i uppdateringarna om ref struct
typer och tillägget av den generiska begränsningen allows ref struct
.
Fler delvisa medlemmar
Du kan deklarera partial
egenskaper och partial
indexerare i C# 13. Partiella egenskaper och indexerare följer vanligtvis samma regler som partial
metoder: du skapar en som deklarerar deklarationen och en implementera deklarationen. Signaturerna för de två deklarationerna måste matcha. En begränsning är att du inte kan använda en automatisk egenskapsdeklaration för att implementera en partiell egenskap i för. Egenskaper som inte deklarerar ett innehåll anses vara deklarerande deklaration.
public partial class C
{
// Declaring declaration
public partial string Name { get; set; }
}
public partial class C
{
// implementation declaration:
private string _name;
public partial string Name
{
get => _name;
set => _name = value;
}
}
Du kan läsa mer i artikeln om delmedlemmar.
Prioritet för överbelastningsupplösning
I C# 13 känner kompilatorn igen OverloadResolutionPriorityAttribute för att föredra en överbelastning framför en annan. Biblioteksförfattare kan använda det här attributet för att säkerställa att en ny, bättre överlagring föredras framför en befintlig överlagring. Du kan till exempel lägga till en ny överbelastning med bättre prestanda. Du vill inte bryta befintlig kod som använder biblioteket, men du vill att användarna ska uppdatera till den nya versionen när de kompileras om. Du kan använda Överbelastningsupplösningsprioritet för att informera kompilatorn om vilken överbelastning som ska föredras. Överbelastningar med högsta prioritet prioriteras.
Den här funktionen är avsedd för biblioteksförfattare för att undvika tvetydigheter när nya överlagringar läggs till. Biblioteksförfattare bör vara försiktiga med det här attributet för att undvika förvirring.
Nyckelordet field
Det field
kontextuella nyckelordet finns i C# 13 som en förhandsgranskningsfunktion. Token field
kommer åt kompilatorns syntetiserade bakgrundsfält i en egenskapsåtkomst. Det gör att du kan skriva en accessor utan att deklarera ett explicit stödjande fält i din typdeklaration. Du kan deklarera en kropp för en eller båda accessorerna för en fältbaserad egenskap.
Funktionen field
släpps som en förhandsversionsfunktion. Vi vill lära oss av dina erfarenheter med hjälp av det. Det finns en möjlig störande ändring eller oklarhet vid kodläsning i typer som även innehåller ett fält med namnet field
. Du kan använda @field
eller this.field
för att skilja mellan nyckelordet field
och identifieraren.
Viktig
Nyckelordet field
är en förhandsversionsfunktion i C# 13. Du måste använda .NET 9 och ange elementet <LangVersion>
till preview
i projektfilen för att kunna använda det field
kontextuella nyckelordet.
Du bör vara försiktig med att använda field
nyckelordsfunktionen i en klass som har ett fält med namnet field
. Det nya nyckelordet field
skuggar ett fält med namnet field
i omfånget för en egenskapsaccessor. Du kan antingen ändra namnet på variabeln field
eller använda @
-token för att referera till field
-identifieraren som @field
. Du kan läsa mer genom att läsa funktionsspecifikationen för nyckelordet field
.
Om du provar den här funktionen och har feedback lägger du till den i funktionsproblemet på csharplang
-lagringsplatsen.