Not
Åtkomst till denna sida kräver auktorisation. Du kan prova att logga in eller byta katalog.
Åtkomst till denna sida kräver auktorisation. Du kan prova att byta katalog.
ref Använd modifieraren när du deklarerar en strukturtyp. Du allokerar instanser av en ref struct typ i stacken och de kan inte fly till den hanterade heapen. För att säkerställa den här egenskapen begränsar kompilatorn användningen av ref struct typer på följande sätt:
- Du kan inte använda en
ref structsom elementtyp för en matris. - Du kan inte deklarera en
ref structsom typ av ett fält i en klass eller en icke-ref struct. - Du kan inte boxa till
ref structSystem.ValueType eller System.Object. - Du kan inte avbilda en
ref structvariabel i ett lambda-uttryck eller en lokal funktion. - Innan C# 13 kan du inte använda
ref structvariabler i enasyncmetod. Från och med C# 13 kan enref structvariabel inte användas i samma block somawaituttrycket i enasyncmetod. Du kan dock användaref structvariabler i synkrona metoder, till exempel i metoder som returnerar Task eller Task<TResult>. - Innan C# 13 kan du inte använda en
ref structvariabel i iteratorer. Från och med C# 13ref structkan typer ochreflokalbefolkningen användas i iteratorer, förutsatt att de inte finns i kodsegment med -instruktionenyield return. - Före C# 13 kan en
ref structinte implementera gränssnitt. Från och med C# 13 kan enrefstruct implementera gränssnitt, men måste följa referenssäkerhetsreglerna . En typ kan till exempelref structinte konverteras till gränssnittstypen eftersom det kräver en boxningskonvertering. - Före C# 13 kan en
ref structinte vara ett typargument. Från och med C# 13 kan ettref structvara typargumentet när typparametern angerallows ref structi -wheresatsen.
C#-språkreferensen dokumenterar den senaste versionen av C#-språket. Den innehåller även inledande dokumentation för funktioner i offentliga förhandsversioner för den kommande språkversionen.
Dokumentationen identifierar alla funktioner som först introducerades i de tre senaste versionerna av språket eller i aktuella offentliga förhandsversioner.
Tips/Råd
Information om när en funktion först introducerades i C# finns i artikeln om språkversionshistoriken för C#.
Vanligtvis definierar du en ref struct typ när du behöver en typ som även innehåller datamedlemmar av ref struct typer:
public ref struct CustomRef
{
public bool IsValid;
public Span<int> Inputs;
public Span<int> Outputs;
}
Om du vill deklarera en ref struct som kombinerar readonly du och readonly modifierarna i typdeklarationen (refmodifieraren måste komma före readonly modifierarenref):
public readonly ref struct ConversionRequest
{
public ConversionRequest(double rate, ReadOnlySpan<double> values)
{
Rate = rate;
Values = values;
}
public double Rate { get; }
public ReadOnlySpan<double> Values { get; }
}
I .NET är ref structSystem.Span<T>och System.ReadOnlySpan<T> .
ref Fält
Du kan deklarera ett ref fält i , ref structsom följande exempel visar:
public ref struct RefFieldExample
{
private ref int number;
public int GetNumber()
{
if (System.Runtime.CompilerServices.Unsafe.IsNullRef(ref number))
{
throw new InvalidOperationException("The number ref field is not initialized.");
}
return number;
}
}
Ett ref fält kan ha värdet null .
Unsafe.IsNullRef<T>(T) Använd metoden för att avgöra om ett ref fält är null.
Du kan tillämpa readonly modifieraren på ett ref fält på följande sätt:
-
readonly ref: Du kan återtilldela det här fältet med hjälp av operatorn= refendast i en konstruktor eller eninitaccessor. Du kan tilldela ett värde med operatorn=när som helst som tillåts av fältåtkomstmodifieraren. -
ref readonly: Du kan när som helst inte tilldela ett värde med operatorn=till det här fältet. Du kan dock återtilldela fältet med hjälp av operatorn= ref. -
readonly ref readonly: Du kan bara återtilldela det här fältet i en konstruktor eller eninitaccessor. När som helst kan du inte tilldela ett värde till fältet.
Kompilatorn ser till att en referens som lagras i ett ref fält inte överlever sina referenser.
Funktionen ref fält möjliggör en säker implementering av typer som System.Span<T>:
public readonly ref struct Span<T>
{
internal readonly ref T _reference;
private readonly int _length;
// Omitted for brevity...
}
Typen Span<T> lagrar en referens genom vilken den kommer åt sammanhängande element i minnet. Med hjälp av en referens undviker en Span<T> instans att kopiera lagringen som den refererar till.
Engångsmönstret
Du kan definiera en disponibel ref struct. För att göra det, se till att ett ref struct passar disponibelt mönster. Den har alltså en instansmetod Dispose som är tillgänglig, parameterlös och har en void returtyp. Du kan använda instruktionen eller deklarationen med en instans av en disponibel ref struct.
Från och med C# 13 kan du även implementera typerna IDisposable på ref struct . Överlagringsupplösning föredrar dock engångsmönstret jämfört med gränssnittsmetoden. Kompilatorn matchar endast en IDisposable.Dispose metod när en lämplig Dispose metod inte hittas.
Begränsningar för ref struct typer som implementerar ett gränssnitt
Dessa begränsningar säkerställer att en ref struct typ som implementerar ett gränssnitt följer de nödvändiga referenssäkerhetsreglerna .
- Du kan inte konvertera en
ref structtill en instans av ett gränssnitt som implementeras. Den här begränsningen inkluderar implicit konvertering när du använder enref structtyp som argument och parametern är en gränssnittstyp. Konverteringen resulterar i en boxningskonvertering, vilket strider mot referenssäkerheten. Enref structkan deklarera metoder som explicita gränssnittsdeklarationer. Du kan dock bara komma åt dessa metoder från generiska metoder där typparametertypernaallows ref struct. - En
ref structsom implementerar ett gränssnitt måste implementera alla instansgränssnittsmedlemmar.ref structmåste implementera instansmedlemmar även när gränssnittet innehåller en standardimplementering.
Kompilatorn tillämpar dessa begränsningar. Om du skriver ref struct typer som implementerar gränssnitt kan varje ny uppdatering innehålla nya standardgränssnittsmedlemmar. Tills du har angett en implementering för nya instansmetoder kompileras inte programmet. Du kan inte ange en specifik implementering för en static gränssnittsmetod med en standardimplementering.
Viktigt!
Genom att implementera ett gränssnitt med en ref struct typ introduceras potentialen för senare källbrytande och binärt icke-bakåtkompatibla ändringar. Pausen inträffar om en ref struct implementerar ett gränssnitt som definierats i en annan sammansättning och den sammansättningen tillhandahåller en uppdatering som lägger till standardmedlemmar i gränssnittet.
Källbrytningen inträffar när du kompilera ref structom : Den måste implementera den nya medlemmen, även om det finns en standardimplementering.
Binärbrytningen inträffar om du uppgraderar den externa sammansättningen utan att kompilera ref struct om typen och den uppdaterade koden anropar standardimplementeringen av den nya metoden. Körningen utlöser ett undantag när standardmedlemmen används.
Språkspecifikation för C#
Mer information finns i följande avsnitt i C#-språkspecifikationen:
Mer information om ref fält finns i förslag på förbättringar på låg nivå .