Megosztás a következőn keresztül:


Numerikus intPtr

Jegyzet

Ez a cikk egy funkcióspecifikáció. A specifikáció a funkció tervezési dokumentumaként szolgál. Tartalmazza a specifikáció javasolt módosításait, valamint a funkció tervezése és fejlesztése során szükséges információkat. Ezeket a cikkeket mindaddig közzéteszik, amíg a javasolt specifikációmódosításokat nem véglegesítik, és be nem építik a jelenlegi ECMA-specifikációba.

A szolgáltatás specifikációja és a befejezett implementáció között eltérések lehetnek. Ezeket a különbségeket a vonatkozó nyelvi tervezési értekezlet (LDM) megjegyzései rögzítik.

A funkcióspektusok C# nyelvi szabványba való bevezetésének folyamatáról a specifikációkcímű cikkben olvashat bővebben.

Bajnoki probléma: https://github.com/dotnet/csharplang/issues/6065

Összefoglalás

Ez a natív egész számok kezdeti funkciójának (spec) egy változata, ahol a nint/nuint típusok eltérnek az alapul szolgáló System.IntPtr/System.UIntPtrtípusoktól. Röviden: a(z) nint/nuint egyszerű típusok aliasaként kezeljük a(z) System.IntPtr/System.UIntPtr, ahogyan a int kapcsolatában System.Int32. A System.Runtime.CompilerServices.RuntimeFeature.NumericIntPtr futtatókörnyezet funkciójelzője aktiválja ezt az új viselkedést.

Tervezés

8.3.5 Egyszerű típusok

A C# előre definiált struct típusok, úgynevezett egyszerű típusok készletét biztosítja. Az egyszerű típusokat kulcsszavak azonosítják, de ezek a kulcsszavak egyszerűen aliasok az struct névtér előre definiált System típusaihoz, az alábbi táblázatban leírtak szerint.

kulcsszó alias típus
sbyte System.SByte
byte System.Byte
short System.Int16
ushort System.UInt16
int System.Int32
uint System.UInt32
nint System.IntPtr
nuint System.UIntPtr
long System.Int64
ulong System.UInt64
char System.Char
float System.Single
double System.Double
bool System.Boolean
decimal System.Decimal

[...]

8.3.6 Integráltípusok

A C# tizenegy integrált típust támogat: sbyte, byte, short, ushort, int, uint, nint, nuint, long, ulongés char. [...]

8.8 Nem felügyelt típusok

Más szóval egy unmanaged_type az alábbiak egyike:

  • sbyte, byte, short, ushort, int, uint, nint, nuint, long, ulong, char, float, double, decimalvagy bool.
  • Bármelyik enum_type.
  • Minden felhasználó által definiált struct_type, amely nem konstruktált típus, és csak unmanaged_typemezőket tartalmaz.
  • Nem biztonságos kódban bármelyik mutató_típus.

10.2.3 Implicit numerikus konverziók

Az implicit numerikus konverziók a következők:

  • A sbyte a short, int, nint, long, float, doublevagy decimal.
  • A byte a short, ushort, int, uint, nint, nuint, long, ulong, float, doublevagy decimal.
  • A short a int, nint, long, float, doublevagy decimal.
  • ushort- int, uint, nint, nuint, long, ulong, float, doublevagy decimal.
  • A int-ról nint-re, long-re, float-re, double-re vagy decimal-re.
  • A uint a nuint, long, ulong, float, doublevagy decimal.
  • A nintlong, float, doublevagy decimal.
  • A nuintulong, float, doublevagy decimal.
  • A long a float, doublevagy decimal.
  • A ulong a float, doublevagy decimal.
  • A char a ushort, int, uint, nint, nuint, long, ulong, float, doublevagy decimal.
  • float-tól double-ig.

[...]

10.2.11 Implicit állandó kifejezés-konverziók

Az implicit konstanskifejezés-átalakítás a következő konverziókat teszi lehetővé:

  • A típusú intsbyte, byte, short, ushort, uint, nint, nuintvagy ulongtípussá alakíthatók, feltéve, hogy a constant_expression értéke a céltípus tartományán belül van. [...]

10.3.2 Kifejezett numerikus konverziók

Az explicit numerikus konverziók egy numeric_type egy másik numeric_type való konvertálásai, amelyeknél még nem létezik implicit numerikus átalakítás:

  • A sbyte a byte, ushort, uint, nuint, ulongvagy char.
  • byte-tól sbyte-ig vagy char-ig.
  • A short a sbyte, byte, ushort, uint, nuint, ulongvagy char.
  • A ushort a sbyte, byte, shortvagy char.
  • int a sbyte, byte, short, ushort, uint, nuint, ulongvagy char.
  • A uint a sbyte, byte, short, ushort, int, nintvagy char.
  • A long- sbyte, byte, short, ushort, int, uint, nint, nuint, ulongvagy char.
  • nint-től sbyte, byte, short, ushort, int, uint, nuint, ulongvagy char.
  • nuint-től sbyte, byte, short, ushort, int, uint, nint, longvagy char.
  • A ulong- sbyte, byte, short, ushort, int, uint, nint, nuint, longvagy char.
  • A char a sbyte, bytevagy short.
  • float-sbyte, byte, short, ushort, int, uint, ,nint, nuint,, long, ulong, charvagy decimal.
  • A double- sbyte, byte, short, ushort, int, uint, nint, nuint, long, ulong, char, floatvagy decimal.
  • A decimal- sbyte, byte, short, ushort, int, uint, nint, nuint, long, ulong, char, floatvagy double.

[...]

10.3.3 Explicit enumerálási konverziók

A explicit enumerálási konverziók a következők:

  • sbyte, byte, short, ushort, int, uint, nint, nuint, long, ulong, char, float, doublevagy decimal egészen a enum_typetípusig.
  • Bármely enum_type, sbyte, byte, short, ushort, int, uint, nint, nuint, long, ulong, char, float, doublevagy decimal.
  • Bármely enum_type bármely más enum_typeesetében.

12.6.4.7 Jobb konverziós cél

Adott két típus, T₁ és T₂, ahol T₁ egy jobb konverziós cél, mint T₂, ha az alábbi feltételek valamelyike fennáll:

  • Az T₁-ről T₂-ra történő implicit átalakítás létezik, és nem létezik implicit átalakítás T₂-ról T₁-ra
  • T₁ Task<S₁>, T₂Task<S₂>, és S₁ jobb konverziós cél, mint S₂
  • T₁ S₁ vagy S₁?, ahol a S₁ aláírt integráltípus, T₂ pedig S₂ vagy S₂?, ahol a S₂ aláírás nélküli integráltípus. Konkrétan: [...]

12.8.12 Elem hozzáférés

[...] A argument_list kifejezéseinek száma megegyezik a array_typerangértékével, és minden kifejezésnek int, uint, nint, nuint, longvagy ulong, kell lennie, vagy implicit módon átalakíthatónak kell lennie egy vagy több ilyen típusra.

11.8.12.2 Tömb hozzáférés

[...] A argument_list kifejezéseinek száma megegyezik a array_typerangértékével, és minden kifejezésnek int, uint, nint, nuint, longvagy ulong, kell lennie, vagy implicit módon átalakíthatónak kell lennie egy vagy több ilyen típusra.

[...] Az űrlap P[A]tömbhozzáférésének futásidejű feldolgozása, ahol a P egy array_typeprimary_no_array_creation_expression és A egy argument_list, a következő lépésekből áll: [...]

  • A argument_list indexkifejezéseinek kiértékelése sorrendben történik, balról jobbra. Az indexkifejezések kiértékelése után implicit átalakítást hajtunk végre az alábbi típusok egyikére: int, uint, nint, nuint, long, ulong. A lista első olyan típusát választja ki, amelyhez implicit konverzió tartozik. [...]

12.8.16 Postfix inkrementáló és csökkentő operátorok

Az unáris operátor túlterhelésének feloldását alkalmazzák egy adott operátor-implementáció kiválasztásához. Az előre definiált ++ és -- operátorok a következő típusokhoz léteznek: sbyte, byte, short, ushort, int, uint, nint, nuint,long, ulong, char, float, double, decimalés bármely számtípus.

12.9.2 Unary plus operátor

Az előre definiált plusz operátorok a következők:

...
nint operator +(nint x);
nuint operator +(nuint x);

12.9.3 Unary mínusz operátor

Az előre definiált egyváltozós mínusz operátorok a következők:

  • Egész szám tagadása:

    ...
    nint operator –(nint x);
    

12.8.16 Postfix inkrementáló és csökkentő operátorok

Az előre definiált ++ és -- operátorok a következő típusokhoz léteznek: sbyte, byte, short, ushort, int, uint, nint, nuint, long, ulong, char, float, double, decimalés bármely számtípus.

11.7.19 Alapértelmezett értékkifejezések

Ezenkívül a default_value_expression állandó kifejezés, ha a típus a következő értéktípusok egyike: sbyte, byte, short, ushort, int, uint, nint, nuint, long, ulong, char, float, double, decimal, bool, vagy bármilyen számbavételi típus.

12.9.5 Bitenkénti komplementer operátor

Az előre definiált bitenkénti komplementer operátorok a következők:

...
nint operator ~(nint x);
nuint operator ~(nuint x);

12.9.6 Előtag-növekmény- és csökkentés operátorok

Az előre definiált ++ és -- operátorok a következő típusokhoz léteznek: sbyte, byte, short, ushort, int, uint, nint, nuint, long, ulong, char, float, double, decimalés bármely számtípus.

12.10 Aritmetikai operátorok

12.10.2 Szorzási operátor

Az előre definiált szorzási operátorok az alábbiakban láthatók. Az operátorok az x és a yszorzatát számítják ki.

  • Egész szám szorzása:

    ...
    nint operator *(nint x, nint y);
    nuint operator *(nuint x, nuint y);
    

12.10.3 Osztás operátora

Az előre definiált osztási operátorokat az alábbiakban találja. Az operátorok mindegyike kiszámítja a x és yhányadosát.

  • Egész szám osztás:

    ...
    nint operator /(nint x, nint y);
    nuint operator /(nuint x, nuint y);
    

12.10.4 Fennmaradó operátor

Az előre definiált fennmaradó operátorokat az alábbiakban találja. Az operátorok mind kiszámítják a x és yközötti osztás fennmaradó részét.

  • Az egész szám maradéka:

    ...
    nint operator %(nint x, nint y);
    nuint operator %(nuint x, nuint y);
    

12.10.5 Összeadás operátor

  • Egész szám hozzáadása:

    ...
    nint operator +(nint x, nint y);
    nuint operator +(nuint x, nuint y);
    

12.10.6 Kivonási operátor

  • Egész szám kivonása:

    ...
    nint operator –(nint x, nint y);
    nuint operator –(nuint x, nuint y);
    

12.11 Műszak operátorok

Az előre definiált műszak operátorai az alábbiakban láthatók.

  • Balra váltás:

    ...
    nint operator <<(nint x, int count);
    nuint operator <<(nuint x, int count);
    
  • Jobbra váltás:

    ...
    nint operator >>(nint x, int count);
    nuint operator >>(nuint x, int count);
    

    A >> operátor jobbra eltolja x-t az alább leírt módon kiszámított bitek számával.

    Ha xint, nint vagy longtípusú, akkor a x alacsonyrendű bitjei el lesznek vetve, a fennmaradó bitek jobbra vannak tolva, a magas sorrendű üres bitpozíciók pedig nullára vannak állítva, ha x nem negatív, és egyre van állítva, ha x negatív.

    Ha a xuint, nuint vagy ulongtípusú, a x alacsonyrendű bitjeit elvetik, a fennmaradó biteket jobbra tolják, és a magasrendű üres bitháttereket nullára állítják.

  • Aláíratlan eltolás jobbra:

    ...
    nint operator >>>(nint x, int count);
    nuint operator >>>(nuint x, int count);
    

Az előre definiált operátorok esetében az eltolandó bitek számát a következőképpen számítjuk ki: [...]

  • Ha a x típusa nint vagy nuint, a műszakok számát egy 32 bites platformon az alacsony sorrendű öt bites count, vagy egy 64 bites platformon az alsórendű hat bites count adja meg.

12.12 Relációs és típustesztelő operátorok

12.12.2 Egész szám összehasonlító operátorai

Az előre definiált egész számok összehasonlító operátorai a következők:

...
bool operator ==(nint x, nint y);
bool operator ==(nuint x, nuint y);

bool operator !=(nint x, nint y);
bool operator !=(nuint x, nuint y);

bool operator <(nint x, nint y);
bool operator <(nuint x, nuint y);

bool operator >(nint x, nint y);
bool operator >(nuint x, nuint y);

bool operator <=(nint x, nint y);
bool operator <=(nuint x, nuint y);

bool operator >=(nint x, nint y);
bool operator >=(nuint x, nuint y);

12.12 Logikai operátorok

12.12.2 Egész szám logikai operátorok

Az előre definiált egész szám logikai operátorai a következők:

...
nint operator &(nint x, nint y);
nuint operator &(nuint x, nuint y);

nint operator |(nint x, nint y);
nuint operator |(nuint x, nuint y);

nint operator ^(nint x, nint y);
nuint operator ^(nuint x, nuint y);

12.22 Állandó kifejezések

Az állandó kifejezés lehet értéktípus vagy referenciatípus. Ha egy állandó kifejezés értéktípus, akkor a következő típusok egyikének kell lennie: sbyte, byte, short, ushort, int, uint, nint, nuint, long, ulong, char, float, double, decimal, bool, vagy bármilyen számbavételi típus.

[...]

Az implicit konstanskifejezés-átalakítás lehetővé teszi, hogy a int típusú állandó kifejezés sbyte, byte, short, ushort, uint, nint, nuint, vagy ulonglegyen, feltéve, hogy az állandó kifejezés értéke a céltípus tartományán belül van.

17.4 Tömbelem-hozzáférés

A tömbelemek az űrlap A[I₁, I₂, ..., Iₓ] kifejezésével érhetők el, ahol a A tömbtípusú kifejezés, és minden Iₑ egy int, uint, nint, nuint,long, ulongtípusú kifejezés, vagy implicit módon konvertálható egy vagy több ilyen típusra. A tömbelem-hozzáférés eredménye egy változó, nevezetesen az indexek által kiválasztott tömbelem.

23.5 Mutatókonvertálások

23.5.1 Általános

[...]

Emellett egy nem biztonságos környezetben az elérhető explicit konverziók halmaza kiterjeszthető a következő explicit mutatókonverziókra is:

  • Bármelyik pointer_type-től bármely másik pointer_typeirányába.
  • sbyte, byte, short, ushort, int, uint, nint, nuint,long, vagy ulong bármelyik pointer_type.
  • Bármely pointer_type, sbyte, byte, short, ushort, int, uint, nint, nuint,long, vagy ulong.

23.6.4 Mutatóelem-hozzáférés

[...] A P[E]mutatóelem-hozzáférésében a P kifejezésnek olyan mutató típusúnak kell lennie, amely nem void*, E pedig olyan kifejezésnek, amely implicit módon átalakítható int, uint, nint, nuint,longvagy ulong.

23.6.7 Mutató aritmetikai

Nem biztonságos környezetben a + operátor és operátor az void*kivételével minden mutatótípus értékeire alkalmazható. Így minden mutatótípushoz T*a következő operátorok implicit módon vannak definiálva:

[...]
T* operator +(T* x, nint y);
T* operator +(T* x, nuint y);
T* operator +(nint x, T* y);
T* operator +(nuint x, T* y);
T* operator -(T* x, nint y);
T* operator -(T* x, nuint y);

Adott egy P kifejezés T* mutató típusban és egy N kifejezés a int, uint, nint, nuint,longvagy ulongtípuban, a P + N és N + P kifejezések kiszámítják a T* mutatóértéket, amely az N * sizeof(T)által megadott címhez hozzáadott P eredménye. Hasonlóképpen a P – N kifejezés kiszámítja a T*által megadott címből N * sizeof(T) kivonásából származó P típusú mutató értékét.

Különböző szempontok

Kompatibilitástörő változások

Ennek a kialakításnak az egyik fő hatása, hogy System.IntPtr és System.UIntPtr nyernek néhány beépített operátort (átalakítások, unary és bináris).
Ezek közé tartoznak checked operátorok, ami azt jelenti, hogy az alábbi operátorok ezeken a típusokon most túlcsorduláskor jelennek meg:

  • IntPtr + int
  • IntPtr - int
  • IntPtr -> int
  • long -> IntPtr
  • void* -> IntPtr

Metaadatok kódolása

Ez a kialakítás azt jelenti, hogy nint és nuint egyszerűen kibocsáthatóak System.IntPtr-ként és System.UIntPtr-ként, System.Runtime.CompilerServices.NativeIntegerAttributehasználata nélkül.
Hasonlóképpen, a metaadatok betöltésekor NativeIntegerAttribute figyelmen kívül hagyható.