Delen via


ref structuurtypen (C#-verwijzing)

Gebruik de wijzigingsfunctie bij het ref declareren van een structuurtype. U wijst exemplaren van een ref struct type toe aan de stack en ze kunnen niet ontsnappen aan de beheerde heap. Om deze eigenschap te garanderen, beperkt de compiler het gebruik van ref struct typen als volgt:

  • U kunt een ref struct elementtype van een matrix niet gebruiken.
  • U kunt een ref struct veld niet declareren als het type veld in een klasse of een niet-veldref struct.
  • U kunt geen vakken ref struct aan System.ValueType of System.Object.
  • U kunt geen ref struct variabele vastleggen in een lambda-expressie of een lokale functie.
  • Voor C# 13 kunt u geen variabelen in een async methode gebruikenref struct. Vanaf C# 13 kan een ref struct variabele niet worden gebruikt in hetzelfde blok als de await expressie in een async methode. U kunt echter variabelen gebruiken ref struct in synchrone methoden, bijvoorbeeld in methoden die retourneren Task of Task<TResult>.
  • Voor C# 13 kunt u geen ref struct variabele in iterators gebruiken. Vanaf C# 13 ref struct kunnen typen en ref lokale bevolking worden gebruikt in iterators, mits ze zich niet in codesegmenten met de yield return instructie bevindt.
  • Voor C# 13 ref struct kunnen interfaces niet worden geïmplementeerd. Vanaf C# 13 kan een ref struct interfaces implementeren, maar moet voldoen aan de veiligheidsregels van ref. Een type kan bijvoorbeeld ref 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 een ref struct typeargument zijn wanneer de typeparameter de component in de allows ref struct component where opgeeft.

De C#-taalreferentiedocumenten de laatst uitgebrachte versie van de C#-taal. Het bevat ook de eerste documentatie voor functies in openbare previews voor de aanstaande taalrelease.

De documentatie identificeert alle functies die voor het eerst zijn geïntroduceerd in de laatste drie versies van de taal of in de huidige openbare previews.

Aanbeveling

Raadpleeg het artikel over de versiegeschiedenis van de C#-taal om te achterhalen wanneer een functie voor het eerst is geïntroduceerd in C#.

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 ref structwilt readonly 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 ref structSystem.Span<T>en System.ReadOnlySpan<T> .

ref Velden

U kunt een ref veld in een ref structdeclareren, 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 dit veld opnieuw toewijzen met behulp van de = ref operator alleen in 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 elk moment geen waarde met de = operator aan dit veld toewijzen. U kunt het veld echter opnieuw toewijzen met behulp van de = ref operator.
  • readonly ref readonly: U kunt dit veld alleen opnieuw toewijzen in een constructor of een init 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. Door een verwijzing te gebruiken, voorkomt een Span<T> exemplaar dat de opslag waarnaar wordt verwezen, wordt gekopieerd.

Het wegwerppatroon

U kunt een wegwerp ref structdefiniëren. Om dat te doen, moet u ervoor zorgen dat een ref struct past bij het wegwerppatroon. Dat wil gezegd, het heeft een instantiemethode 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, de noodzakelijke ref-veiligheidsregels volgt.

  • U kunt een ref struct exemplaar van een interface die wordt geïmplementeerd, niet converteren naar een exemplaar. Deze beperking omvat de impliciete conversie wanneer u een ref struct type als argument gebruikt en de parameter een interfacetype is. De conversie resulteert in een boksconversie, die de veiligheid van ref schendt. Een ref struct kan methoden declareren als expliciete interfacedeclaraties. U kunt deze methoden echter alleen openen vanuit algemene methoden waarbij het typeparametertypen allows ref struct zijn.
  • Een ref struct die een interface implementeert moet alle exemplaarinterfaceleden implementeren. De ref struct moet instantieleden implementeren, zelfs wanneer 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 opgeeft voor nieuwe exemplaarmethoden, wordt uw toepassing niet gecompileerd. U kunt geen specifieke implementatie opgeven voor een static interfacemethode met een standaard implementatie.

Belangrijk

Het implementeren van een interface met een ref struct type introduceert 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 broneinde treedt op wanneer u het ref structnieuwe lid opnieuw compileert, ook al is er een standaard implementatie.

Het binaire einde treedt op 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 ref op laag niveau voor meer informatie over velden.

Zie ook