ref
structuurtypen (C#-verwijzing)
U kunt de ref
wijzigingsfunctie gebruiken in de declaratie van een structuurtype. Exemplaren van een ref struct
type worden toegewezen aan de stack en kunnen niet ontsnappen aan de beheerde heap. Om ervoor te zorgen dat de compiler het gebruik van ref struct
typen als volgt beperkt:
- Een
ref struct
kan niet het elementtype van een matrix zijn. - Een
ref struct
kan geen gedeclareerd type van een veld van een klasse of een niet-ref struct
. - Een
ref struct
kan niet worden geboksd aan System.ValueType of System.Object. - Een
ref struct
variabele kan niet worden vastgelegd in een lambda-expressie of een lokale functie. - Voor C# 13
ref struct
kunnen variabelen niet worden gebruikt in eenasync
methode. Vanaf C# 13 kan eenref struct
variabele niet worden gebruikt in hetzelfde blok als deawait
expressie in eenasync
methode. U kunt echter variabelen gebruikenref struct
in synchrone methoden, bijvoorbeeld in methoden die retourneren Task of Task<TResult>. - Voor C# 13 kan een
ref struct
variabele niet worden gebruikt in iterators. Vanaf C# 13ref struct
kunnen typen enref
lokale bevolking worden gebruikt in iterators, mits ze zich niet in codesegmenten met deyield return
instructie bevindt. - Voor C# 13
ref struct
kunnen interfaces niet worden geïmplementeerd. Vanaf C# 13 kan eenref
struct interfaces implementeren, maar moet voldoen aan de veiligheidsregels van ref. Een type kan bijvoorbeeldref struct
niet worden geconverteerd naar het interfacetype omdat hiervoor een boksconversie is vereist. - Voor C# 13 kan een
ref struct
typeargument niet zijn. Vanaf C# 13 kan eenref struct
typeargument zijn wanneer de typeparameter de component in deallows ref struct
componentwhere
opgeeft.
Normaal gesproken definieert u een ref struct
type wanneer u een type nodig hebt dat ook gegevensleden van ref struct
typen bevat:
public ref struct CustomRef
{
public bool IsValid;
public Span<int> Inputs;
public Span<int> Outputs;
}
Als u een als readonly
wilt ref struct
declareren, combineert u de readonly
en ref
modifiers in de typedeclaratie (de readonly
modifier moet vóór de ref
wijzigingsfunctie komen):
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; }
}
In .NET zijn System.Span<T> System.ReadOnlySpan<T>en ref struct
.
ref
Velden
Vanaf C# 11 kunt u een ref
veld in een ref struct
declareren, zoals in het volgende voorbeeld wordt weergegeven:
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;
}
}
Een ref
veld kan de null
waarde hebben. Gebruik de Unsafe.IsNullRef<T>(T) methode om te bepalen of een ref
veld is null
.
U kunt de readonly
wijzigingsfunctie op een ref
veld op de volgende manieren toepassen:
readonly ref
: U kunt een dergelijk veld opnieuw toewijzen aan de= ref
operator alleen binnen een constructor of eeninit
accessor. U kunt een waarde toewijzen aan de=
operator op elk gewenst moment dat is toegestaan door de wijzigingsfunctie voor veldtoegang.ref readonly
: U kunt op enig moment geen waarde met de=
operator toewijzen aan een dergelijk veld. U kunt echter een veld opnieuw toewijzen met de= ref
operator.readonly ref readonly
: U kunt een dergelijk veld alleen opnieuw toewijzen in een constructor of eeninit
accessor. U kunt op elk moment geen waarde aan het veld toewijzen.
De compiler zorgt ervoor dat een verwijzing die is opgeslagen in een ref
veld, de referent niet overleeft.
De ref
functie velden maakt een veilige implementatie van typen mogelijk, zoals System.Span<T>:
public readonly ref struct Span<T>
{
internal readonly ref T _reference;
private readonly int _length;
// Omitted for brevity...
}
Het Span<T>
type slaat een verwijzing op waarmee deze toegang heeft tot de aaneengesloten elementen in het geheugen. Met het gebruik van een verwijzing kan een Span<T>
exemplaar voorkomen dat de opslag waarnaar wordt verwezen, wordt gekopieerd.
Het wegwerppatroon
U kunt een wegwerp ref struct
definiëren. Om dat te doen, moet u ervoor zorgen dat een ref struct
past bij het wegwerppatroon. Dat wil gezegd, het heeft een exemplaarmethode Dispose
, die toegankelijk, parameterloos is en een void
retourtype heeft. U kunt de using-instructie of declaratie gebruiken met een exemplaar van een wegwerp.ref struct
Vanaf C# 13 kunt u ook de IDisposable typen ref struct
implementeren. Overbelastingsresolutie geeft echter de voorkeur aan het wegwerppatroon aan de interfacemethode. De compiler wordt alleen omgezet in een IDisposable.Dispose
methode wanneer er geen geschikte Dispose
methode wordt gevonden.
Beperkingen voor ref struct
typen die een interface implementeren
Deze beperkingen zorgen ervoor dat een ref struct
type dat een interface implementeert, voldoet aan de noodzakelijke ref-veiligheidsregels .
- Een
ref struct
kan niet worden geconverteerd naar een instantie van een interface die wordt geïmplementeerd. Deze beperking omvat de impliciete conversie wanneer u eenref struct
type als argument gebruikt wanneer de parameter een interfacetype is. De conversie resulteert in een boksconversie, die de veiligheid van ref schendt. - Een
ref struct
die een interface implementeert, moet alle interfaceleden implementeren. Deref struct
implementatie moet leden implementeren waarbij de interface een standaard implementatie bevat.
De compiler dwingt deze beperkingen af. Als u typen schrijft ref struct
die interfaces implementeren, kan elke nieuwe update nieuwe standaardinterfaceleden bevatten. Totdat u een implementatie voor deze nieuwe methoden opgeeft, wordt uw toepassing niet gecompileerd.
Belangrijk
Een ref struct
die een interface implementeert, omvat het potentieel voor latere wijzigingen die fouten veroorzaken door bronnen en binaire fouten. De onderbreking treedt op als een ref struct
interface wordt geïmplementeerd die is gedefinieerd in een andere assembly en die assembly een update biedt waarmee standaardleden aan die interface worden toegevoegd.
Het brononderbreking vindt plaats wanneer u het ref struct
nieuwe lid opnieuw compileert, ook al is er een standaard implementatie.
Het binaire einde vindt plaats als u de externe assembly bijwerkt zonder het ref struct
type opnieuw te compileren en de bijgewerkte code de standaard implementatie van de nieuwe methode aanroept. De runtime genereert een uitzondering wanneer het standaardlid wordt geopend.
C#-taalspecificatie
Zie de volgende secties van de C#-taalspecificatie voor meer informatie:
Zie de offertenota voor structverbeteringen op laag niveau voor meer informatie over ref
velden.