Numeric IntPtr
Notitie
Dit artikel is een functiespecificatie. De specificatie fungeert als het ontwerpdocument voor de functie. Het bevat voorgestelde specificatiewijzigingen, samen met informatie die nodig is tijdens het ontwerp en de ontwikkeling van de functie. Deze artikelen worden gepubliceerd totdat de voorgestelde specificaties zijn voltooid en opgenomen in de huidige ECMA-specificatie.
Er kunnen enkele verschillen zijn tussen de functiespecificatie en de voltooide implementatie. Deze verschillen worden vastgelegd in de relevante LDM-notities (Language Design Meeting).
Meer informatie over het proces voor het aannemen van functiespeclets in de C#-taalstandaard vindt u in het artikel over de specificaties.
Samenvatting
Dit is een revisie van de oorspronkelijke native integers feature (specificatie), waarbij de nint
/nuint
typen verschilden van de onderliggende typen System.IntPtr
/System.UIntPtr
.
Kortom, we behandelen nu nint
/nuint
als eenvoudige typen aliasing System.IntPtr
/System.UIntPtr
, zoals we doen voor int
in relatie tot System.Int32
. Met de System.Runtime.CompilerServices.RuntimeFeature.NumericIntPtr
runtime-functievlag wordt dit nieuwe gedrag geactiveerd.
Ontwerpen
8.3.5 Eenvoudige typen
C# biedt een set vooraf gedefinieerde struct
typen die de eenvoudige typen worden genoemd. De eenvoudige typen worden geïdentificeerd via trefwoorden, maar deze trefwoorden zijn gewoon aliassen voor vooraf gedefinieerde struct
typen in de System
naamruimte, zoals beschreven in de onderstaande tabel.
trefwoord | gedefinieerd type |
---|---|
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 Integrale typen
C# ondersteunt elf integrale typen: sbyte
, byte
, short
, ushort
, int
, uint
, nint
, nuint
, long
, ulong
en char
. [...]
8.8 Niet-beheerde typen
Met andere woorden, een unmanaged_type is een van de volgende:
-
sbyte
,byte
,short
,ushort
,int
,uint
,nint
,nuint
,long
,ulong
,char
,float
,double
,decimal
ofbool
. - Elke enum_type.
- Door de gebruiker gedefinieerde struct_type die geen samengesteld type is en uitsluitend velden van unmanaged_typebevat.
- In onveilige code, elke pointertype.
10.2.3 Impliciete numerieke conversies
De impliciete numerieke conversies zijn:
- Van
sbyte
totshort
,int
,nint
,long
,float
,double
ofdecimal
. - Van
byte
totshort
,ushort
,int
,uint
,nint
,nuint
,long
,ulong
,float
,double
ofdecimal
. - Van
short
totint
,nint
,long
,float
,double
, ofdecimal
. - Van
ushort
totint
,uint
,nint
,nuint
,long
,ulong
,float
,double
ofdecimal
. - Van
int
totnint
,long
,float
,double
ofdecimal
. - Van
uint
totnuint
,long
,ulong
,float
,double
ofdecimal
. -
van
nint
totlong
,float
,double
ofdecimal
. -
van
nuint
totulong
,float
,double
ofdecimal
. - Van
long
totfloat
,double
, ofdecimal
. - Van
ulong
totfloat
,double
ofdecimal
. - Van
char
totushort
,int
,uint
,nint
,nuint
,long
,ulong
,float
,double
ofdecimal
. - Van
float
totdouble
.
[...]
10.2.11 Impliciete constante expressieconversies
Een impliciete conversie van constante expressies maakt de volgende conversies mogelijk:
- Een constant_expression van het type
int
kan worden geconverteerd naar het typesbyte
,byte
,short
,ushort
,uint
,nint
,nuint
ofulong
, mits de waarde van de constant_expression binnen het bereik van het doeltype valt. [...]
10.3.2 Expliciete numerieke conversies
De expliciete numerieke conversies zijn de conversies van een numeric_type naar een andere numeric_type waarvoor nog geen impliciete numerieke conversie bestaat:
- Van
sbyte
totbyte
,ushort
,uint
,nuint
,ulong
ofchar
. - Van
byte
totsbyte
ofchar
. - Van
short
totsbyte
,byte
,ushort
,uint
,nuint
,ulong
ofchar
. - Van
ushort
totsbyte
,byte
,short
ofchar
. - Van
int
naarsbyte
,byte
,short
,ushort
,uint
,nuint
,ulong
ofchar
. - Van
uint
totsbyte
,byte
,short
,ushort
,int
,nint
ofchar
. - Van
long
totsbyte
,byte
,short
,ushort
,int
,uint
, ,nint
,nuint
,,ulong
ofchar
. -
van
nint
totsbyte
,byte
,short
,ushort
,int
,uint
,nuint
,ulong
ofchar
. -
van
nuint
totsbyte
,byte
,short
,ushort
,int
,uint
,nint
,long
ofchar
. - Van
ulong
totsbyte
,byte
,short
,ushort
,int
,uint
, ,nint
,nuint
,,long
ofchar
. - Van
char
totsbyte
,byte
ofshort
. - Van
float
totsbyte
,byte
,short
,ushort
,int
,uint
,nint
,nuint
,long
,ulong
,char
ofdecimal
. - Van
double
totsbyte
,byte
,short
,ushort
,int
,uint
, ,nint
,nuint
,,long
,ulong
,char
,float
ofdecimal
. - Van
decimal
totsbyte
,byte
,short
,ushort
,int
,uint
, ,nint
,nuint
,long
,ulong
,char
,float
ofdouble
.
[...]
10.3.3 Expliciete opsommingsomzettingen
De expliciete opsommingsconversies zijn:
- Van
sbyte
,byte
,short
,ushort
,int
,uint
,nint
,nuint
,long
,ulong
,char
,float
,double
, ofdecimal
op een enum_type. - Van enum_type tot
sbyte
,byte
,short
,ushort
,int
,uint
,nint
,nuint
,long
,ulong
,char
,float
,double
ofdecimal
. - Van elke enum_type naar elke andere enum_type.
12.6.4.7 Beter conversiedoel
Als we de twee typen T₁
en T₂
beschouwen, is T₁
een betere conversiedoel dan T₂
als een van de volgende voorwaarden geldt:
- Er bestaat een impliciete conversie van
T₁
naarT₂
en er bestaat geen impliciete conversie vanT₂
naarT₁
-
T₁
isTask<S₁>
,T₂
isTask<S₂>
enS₁
is een beter conversiedoel danS₂
-
T₁
isS₁
ofS₁?
waarbijS₁
een ondertekend integraal type is enT₂
isS₂
ofS₂?
waarbijS₂
een niet-ondertekend integraaltype is. Specifiek: [...]
12.8.12 Elementtoegang
[...] Het aantal expressies in de argument_list moet gelijk zijn aan de rang van de array_typeen elke expressie moet van het type int
, uint
, nint
, nuint
, long
of ulong,
zijn of impliciet kunnen worden omgezet in een of meer van deze typen.
11.8.12.2 Matrixtoegang
[...] Het aantal expressies in de argument_list moet gelijk zijn aan de rang van de array_typeen elke expressie moet van het type int
, uint
, nint
, nuint
, long
of ulong,
zijn of impliciet kunnen worden omgezet in een of meer van deze typen.
[...] De tijdsverwerking van een arraytoegang van het formulier P[A]
, waarbij P
een primary_no_array_creation_expression is van een arraytype en A
een argument_listis, bestaat uit de volgende stappen: [...]
- De indexexpressies van de argument_list worden op volgorde geëvalueerd, van links naar rechts. Na de evaluatie van elke indexexpressie wordt een impliciete conversie naar een van de volgende typen uitgevoerd:
int
,uint
,nint
,nuint
,long
,ulong
. Het eerste type in deze lijst waarvoor een impliciete conversie bestaat, wordt gekozen. [...]
12.8.16 Postfix incrementeer- en decrementeeroperatoren
De overbelastingsresolutie van unaire operatoren wordt gebruikt om een specifieke operatorimplementatie te selecteren. Vooraf gedefinieerde operatoren voor ++
en --
bestaan voor de volgende typen: sbyte
, byte
, short
, ushort
, int
, uint
, nint
, nuint
,long
, ulong
, char
, float
, double
, decimal
en elk enumtype.
12.9.2 Unary plus operator
De vooraf gedefinieerde unaire plusoperators zijn:
...
nint operator +(nint x);
nuint operator +(nuint x);
12.9.3 Unaire mintekenoperator
De vooraf gedefinieerd unaire minus-operatoren zijn:
Negatie van gehele getallen:
... nint operator –(nint x);
12.8.16 Postfix-increment- en decrementoperatoren
Vooraf gedefinieerde ++
- en --
operators bestaan voor de volgende typen: sbyte
, byte
, short
, ushort
, int
, uint
, nint
, nuint
, long
, ulong
, char
, float
, double
, decimal
en een opsommingstype.
11.7.19 Standaardwaardeexpressies
Bovendien is een default_value_expression een constante expressie als het type een van de volgende waardetypen is: sbyte
, byte
, short
, ushort
, int
, uint
, nint
, nuint
, long
, ulong
, char
, float
, double
, decimal
, bool,
of een opsommingstype.
12.9.5 Bitsgewijze complementoperator
De vooraf gedefinieerde bitsgewijze complementoperators zijn:
...
nint operator ~(nint x);
nuint operator ~(nuint x);
12.9.6 Prefix-verhogings- en verlagingsoperatoren
Vooraf gedefinieerde ++
- en --
operators bestaan voor de volgende typen: sbyte
, byte
, short
, ushort
, int
, uint
, nint
, nuint
, long
, ulong
, char
, float
, double
, decimal
en een opsommingstype.
12.10 Rekenkundige operatoren
12.10.2 Vermenigvuldigingsoperator
De vooraf gedefinieerde vermenigvuldigingsoperatoren worden hieronder vermeld. De operators berekenen allemaal het product van x
en y
.
Vermenigvuldiging van gehele getallen:
... nint operator *(nint x, nint y); nuint operator *(nuint x, nuint y);
12.10.3 Divisieoperator
Hieronder vindt u de vooraf gedefinieerde divisieoperators. De operators berekenen allemaal het quotiënt van x
en y
.
Deling van gehele getallen:
... nint operator /(nint x, nint y); nuint operator /(nuint x, nuint y);
Operator 12.10.4 Rest
De vooraf gedefinieerde restoperators worden hieronder weergegeven. De operators berekenen allemaal de rest van de deling tussen x
en y
.
Restgetal geheel getal:
... nint operator %(nint x, nint y); nuint operator %(nuint x, nuint y);
12.10.5 Optellen operator
Optellen van gehele getallen:
... nint operator +(nint x, nint y); nuint operator +(nuint x, nuint y);
12.10.6 Aftrekkingsoperator
Geheel getal aftrekken:
... nint operator –(nint x, nint y); nuint operator –(nuint x, nuint y);
12.11 Shift-operatoren
De vooraf gedefinieerde shiftoperators worden hieronder weergegeven.
Naar links verschuiven:
... nint operator <<(nint x, int count); nuint operator <<(nuint x, int count);
Naar rechts gaan:
... nint operator >>(nint x, int count); nuint operator >>(nuint x, int count);
De operator
>>
verschuiftx
naar rechts door een aantal bits dat is berekend, zoals hieronder wordt beschreven.Wanneer
x
van het typeint
,nint
oflong
is, worden de laagwaardige bits vanx
verwijderd, worden de resterende bits naar rechts verschoven, en worden de hoogwaardige lege bitposities ingesteld op nul alsx
niet-negatief is en op één alsx
negatief is.Wanneer
x
van het typeuint
,nuint
ofulong
is, worden de lage volgorde vanx
verwijderd, worden de resterende bits naar rechts verplaatst en worden de lege bitposities in hoge volgorde ingesteld op nul.Niet-ondertekende dienst rechts:
... nint operator >>>(nint x, int count); nuint operator >>>(nuint x, int count);
Voor de vooraf gedefinieerde operators wordt het aantal bits dat moet worden verplaatst als volgt berekend: [...]
- Wanneer het type
x
nint
ofnuint
is, wordt het aantal verschuivingen gegeven door de laagste vijf bits vancount
op een 32-bits platform of de zes laagste bits vancount
op een 64-bits platform.
12.12 Relationele en typetestoperators
12.12.2 Vergelijkingsoperatoren voor gehele getallen
De vooraf gedefinieerde vergelijkingsoperatoren voor gehele getallen zijn:
...
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 Logische operators
12.12.2 Logische operatoren voor gehele getallen
De vooraf gedefinieerde logische operatoren voor gehele getallen zijn:
...
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 Constante uitdrukkingen
Een constante expressie kan een waardetype of een verwijzingstype zijn. Als een constante expressie een waardetype is, moet dit een van de volgende typen zijn: sbyte
, byte
, short
, ushort
, int
, uint
, nint
, nuint
, long
, ulong
, char
, float
, double
, decimal
, bool,
of een opsommingstype.
[...]
Bij een impliciete expressieconversie kan een constante expressie van het type int
worden geconverteerd naar sbyte
, byte
, short
, ushort
, uint
, nint
, nuint
, of ulong
, mits de waarde van de constante expressie binnen het bereik van het doeltype valt.
17.4 Toegang tot matrixelementen
Matrixelementen worden geopend met behulp van element_access expressies van het formulier A[I₁, I₂, ..., Iₓ]
, waarbij A
een expressie van een matrixtype is en elke Iₑ
een expressie is van het type int
, uint
, nint
, nuint
,long
, ulong
of impliciet kan worden geconverteerd naar een of meer van deze typen. Het resultaat van toegang tot een matrixelement is een variabele, namelijk het matrixelement dat door de indexen is geselecteerd.
23.5 Aanwijzerconversies
23.5.1 Algemeen
[...]
Bovendien wordt in een onveilige context de set beschikbare expliciete conversies uitgebreid met de volgende expliciete aanwijzerconversies:
- Van elke pointer_type naar elke andere pointer_type.
- Van
sbyte
,byte
,short
,ushort
,int
,uint
,nint
,nuint
,long
ofulong
op een pointer_type. - Van pointer_type tot
sbyte
,byte
,short
,ushort
,int
,uint
,nint
,nuint
,long
, totulong
.
23.6.4 Toegang tot aanwijzerelementen
[...] In een verwijzingselementtoegang van het formulier P[E]
moet P
een expressie zijn van een ander type aanwijzer dan void*
en moet E
een expressie zijn die impliciet kan worden geconverteerd naar int
, uint
, nint
, nuint
,long
of ulong
.
23.6.7 Pointer-aritmetica
In een onveilige context kunnen de operator +
en –
worden toegepast op waarden van alle typen aanwijzers, met uitzondering van void*
. Voor elk type aanwijzer T*
worden de volgende operators dus impliciet gedefinieerd:
[...]
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);
Gezien een expressie P
van een aanwijzertype T*
en een expressie N
van het type int
, uint
, nint
, nuint
,long
of ulong
, berekenen de expressies P + N
en N + P
de aanwijzerwaarde van het type T*
die voortkomt uit het optellen van N * sizeof(T)
bij het adres opgegeven door P
. Op dezelfde manier berekent de expressie P – N
de aanwijzerwaarde van het type T*
die het gevolg is van het aftrekken van N * sizeof(T)
van het adres dat is opgegeven door P
.
Verschillende overwegingen
Belangrijke wijzigingen
Een van de belangrijkste gevolgen van dit ontwerp is dat System.IntPtr
en System.UIntPtr
enkele ingebouwde operators (conversies, unaire en binaire) krijgen.
Deze omvatten checked
operators, wat betekent dat de volgende operators op deze typen nu worden gegenereerd wanneer deze overlopen:
IntPtr + int
IntPtr - int
IntPtr -> int
long -> IntPtr
void* -> IntPtr
Metagegevenscodering
Dit ontwerp betekent dat nint
en nuint
eenvoudig kunnen worden verzonden als System.IntPtr
en System.UIntPtr
, zonder gebruik te maken van System.Runtime.CompilerServices.NativeIntegerAttribute
.
Op dezelfde manier kan NativeIntegerAttribute
worden genegeerd bij het laden van metagegevens.
C# feature specifications