Megosztás:


ref struktúratípusok (C#-referencia)

Struktúratípus deklarálásakor használja a ref módosítót. A veremen lefoglalhat egy típuspéldányt ref struct , és nem tudnak menekülni a felügyelt halomhoz. A tulajdonság biztosítása érdekében a fordító az alábbiak szerint korlátozza a típusok használatát ref struct :

  • Tömb elemtípusaként nem használható ref struct .
  • Osztályban vagy nem osztályban nem deklarálhat ref struct mezőtípustref struct.
  • Nem lehet beszűkíteni a ref struct kívánt vagy System.ValueTypeSystem.Object.
  • Lambda-kifejezésben vagy helyi függvényben nem rögzíthet ref struct változót.
  • A C# 13 előtt nem használhat ref struct változókat egy async metódusban. A C# 13-tól kezdődően egy ref struct változó nem használható ugyanabban a blokkban, mint egy await metódus kifejezése async . A változókat azonban szinkron metódusokban is használhatja ref struct , például olyan metódusokban, amelyek visszaadják Task vagy Task<TResult>.
  • A C# 13 előtt nem használhat változót ref structaz iterátorokban. A C# 13-tól ref struct kezdődően a típusok és ref a helyiek használhatók az iterátorokban, feltéve, hogy nincsenek kódszegmensekben az yield return utasítással.
  • A C# 13 ref struct előtt nem lehet interfészeket implementálni. A C# 13-tól kezdődően a ref szerkezetek interfészeket implementálhatnak, de be kell tartaniuk a ref biztonsági szabályokat. Egy típus például ref struct nem konvertálható illesztőtípussá, mert ehhez boxing átalakításra van szükség.
  • A C# 13 ref struct előtt nem lehet típusargumentum. A C# 13-tól kezdődően a ref struct típusargumentum lehet, ha a típusparaméter a záradékában adja meg a allows ref struct paramétert where .

A C# nyelv referenciadokumentuma a C# nyelv legújabb kiadású verzióját ismerteti. Emellett a közelgő nyelvi kiadás nyilvános előzetes verziójú funkcióinak kezdeti dokumentációját is tartalmazza.

A dokumentáció azonosítja azokat a funkciókat, amelyeket először a nyelv utolsó három verziójában vagy az aktuális nyilvános előzetes verziókban vezetnek be.

Jótanács

Ha meg szeretné tudni, hogy mikor jelent meg először egy funkció a C#-ban, tekintse meg a C# nyelvi verzióelőzményeiről szóló cikket.

Általában akkor határoz meg típust ref struct , ha olyan típusra van szüksége, amely az adattípusokat ref struct is tartalmazza:

public ref struct CustomRef
{
    public bool IsValid;
    public Span<int> Inputs;
    public Span<int> Outputs;
}

As ref structdeklarálásához readonly egyesítse a readonly típusdeklarációban a módosítókat és ref a módosítókat (a readonly módosítónak a ref módosító előtt kell lennie):

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; }
}

A .NET-ben példákat ref struct láthat a következőkre System.Span<T> : és System.ReadOnlySpan<T>.

ref Mezők

Egy mező deklarálható ref a ref structkövetkező példában látható módon:

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;
    }
}

Egy ref mezőnek lehet null értéke. Unsafe.IsNullRef<T>(T) A metódus használatával állapítsa meg, hogy egy ref mező .null

A módosító a readonly következő módokon alkalmazható egy ref mezőre:

  • readonly ref: Ezt a mezőt újra hozzárendelheti úgy, hogy csak konstruktoron vagy tartozékon belül használja az = ref operátortinit. A mezőhozzáférési módosító által engedélyezett bármely ponton hozzárendelhet értéket = az operátorhoz.
  • ref readonly: A mezőhöz nem rendelhet értéket az = operátorral. Az operátor használatával azonban újból hozzárendelheti a = ref mezőt.
  • readonly ref readonly: Ezt a mezőt csak konstruktorban vagy tartozékban lehet újból hozzárendelni init . Bármikor nem rendelhet értéket a mezőhöz.

A fordító biztosítja, hogy egy mezőben tárolt ref hivatkozás ne lépje túl a hivatkozási értékét.

A ref mezők funkció lehetővé teszi a következő típusok System.Span<T>biztonságos implementálását:

public readonly ref struct Span<T>
{
    internal readonly ref T _reference;
    private readonly int _length;

    // Omitted for brevity...
}

A Span<T> típus egy hivatkozást tárol, amelyen keresztül hozzáfér a memória összefüggő elemeihez. Hivatkozás használatával a Span<T> példányok elkerülik a hivatkozott tárterület másolását.

Az eldobható minta

Definiálhat egy eldobható ref struct. Ehhez győződjön meg arról, hogy az ref struct eldobható mintához illeszkedik. Ez azt jelent, hogy egy elérhető, paraméter nélküli és visszatérési típusú példánymetódussal Dispose rendelkezik void . A használati utasítást vagy deklarációt használhatja egy eldobható ref structpéldánysal.

A C# 13-tól kezdve a IDisposable típusokat ref struct is implementálhatja. A túlterhelés feloldása azonban inkább az egyszer használatos mintát részesíti előnyben az interfészmetódushoz. A fordító csak akkor oldja fel a IDisposable.Dispose metódust, ha nem található megfelelő Dispose metódus.

Az interfészt ref struct megvalósító típusok korlátozásai

Ezek a korlátozások biztosítják, hogy az ref struct interfészt megvalósító típus kövesse a szükséges ref biztonsági szabályokat.

  • Nem konvertálhat egy ref struct példányt az általa implementálandó felületre. Ez a korlátozás magában foglalja az implicit konverziót, amikor egy típust ref struct használ argumentumként, és a paraméter egy felülettípus. Az átalakítás egy boxing konverziót eredményez, amely sérti a ref biztonságát. A ref struct explicit felületi deklarációkként deklarálhatnak metódusokat. Ezeket a metódusokat azonban csak olyan általános metódusokból érheti el, amelyekben a típusparaméterek allows ref struct típusai vannak.
  • A felületi megvalósító ref struct kell implementálnia az összes példányillesztő-tagot. A ref struct akkor is implementálnia kell a példánytagokat, ha az interfész alapértelmezett implementációt tartalmaz.

A fordító kikényszeríti ezeket a korlátozásokat. Ha felületeket implementáló típusokat ír ref struct , minden új frissítés tartalmazhat új alapértelmezett illesztőtagokat. Amíg nem ad implementációt az új példány metódusaihoz, az alkalmazás nem fordítja le. Az alapértelmezett implementációval rendelkező static interfészmetódushoz nem adhat meg konkrét implementációt.

Fontos

Egy felület típussal való ref struct implementálása lehetőséget ad a későbbi forrástörési és bináris kompatibilitástörő változásokra. A törés akkor fordul elő, ha egy ref struct másik szerelvényben definiált felületet implementál, és a szerelvény egy olyan frissítést biztosít, amely alapértelmezett tagokat ad hozzá az adott felülethez.

A forrástörés akkor fordul elő, ha újrafordítsa a ref structkövetkezőt: Az új tagot kell implementálnia, annak ellenére, hogy van egy alapértelmezett implementáció.

A bináris törés akkor fordul elő, ha a külső szerelvényt a típus újrafordítása ref struct nélkül frissíti, és a frissített kód meghívja az új metódus alapértelmezett implementációját. A futtatókörnyezet kivételt jelez az alapértelmezett tag elérésekor.

C# nyelvspecifikáció

További információt a C# nyelvspecifikációjának alábbi szakaszaiban talál:

A mezőkkel kapcsolatos ref további információkért tekintse meg az Alacsony szintű szerkezetfejlesztések javaslati megjegyzését.

Lásd még