IntPtr numérique
Remarque
Cet article est une spécification de fonctionnalité. La spécification sert de document de conception pour la fonctionnalité. Il inclut les modifications de spécification proposées, ainsi que les informations nécessaires pendant la conception et le développement de la fonctionnalité. Ces articles sont publiés jusqu’à ce que les modifications de spécification proposées soient finalisées et incorporées dans la spécification ECMA actuelle.
Il peut y avoir des différences entre la spécification de la fonctionnalité et l’implémentation terminée. Ces différences sont consignées dans les notes pertinentes de la réunion de conception linguistique (LDM).
Vous pouvez en savoir plus sur le processus d’adoption des speclets de fonctionnalités dans la norme de langage C# dans l’article sur les spécifications .
Résumé
Il s’agit d’une révision sur la fonctionnalité initiale d’entiers natifs (spécification), où les types nint
/nuint
étaient distincts des types sous-jacents System.IntPtr
/System.UIntPtr
.
En bref, nous traitons maintenant nint
/nuint
en tant qu’alias de types simples System.IntPtr
/System.UIntPtr
, comme nous le faisons pour int
par rapport à System.Int32
. L’indicateur de fonctionnalité System.Runtime.CompilerServices.RuntimeFeature.NumericIntPtr
runtime déclenche ce nouveau comportement.
Création
8.3.5 Types simples
C# fournit un ensemble de types struct
prédéfinis appelés types simples. Les types simples sont identifiés par le biais de mots clés, mais ces mots clés sont simplement des alias pour les types de struct
prédéfinis dans l’espace de noms System
, comme décrit dans le tableau ci-dessous.
Mot-clé | Type aliasé |
---|---|
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 Types intégraux
C# prend en charge onze types entiers : sbyte
, byte
, short
, ushort
, int
, uint
, nint
, nuint
, long
, ulong
, et char
. [...]
8.8 Types non managés
En d’autres termes, une unmanaged_type est l’une des suivantes :
sbyte
,byte
,short
,ushort
,int
,uint
,nint
,nuint
,long
,ulong
,char
,float
,double
,decimal
oubool
.- Tout enum_type.
- Tout struct_type défini par l’utilisateur qui n’est pas un type construit et ne contient que des champs de unmanaged_type.
- Dans un code non sécurisé, tout pointer_type.
10.2.3 Conversions numériques implicites
Les conversions numériques implicites sont les suivantes :
- De
sbyte
àshort
,int
,nint
,long
,float
,double
oudecimal
. - De
byte
àshort
,ushort
,int
,uint
,nint
,nuint
,long
,ulong
,float
,double
oudecimal
. - De
short
àint
,nint
,long
,float
,double
oudecimal
. - De
ushort
àint
,uint
,nint
,nuint
,long
,ulong
,float
,double
oudecimal
. - De
int
ànint
,long
,float
,double
oudecimal
. - De
uint
ànuint
,long
,ulong
,float
,double
oudecimal
. - De
nint
àlong
,float
,double
oudecimal
. - De
nuint
àulong
,float
,double
oudecimal
. - De
long
àfloat
,double
oudecimal
. - De
ulong
àfloat
,double
oudecimal
. - De
char
àushort
,int
,uint
,nint
,nuint
,long
,ulong
,float
,double
oudecimal
. - De
float
àdouble
.
[...]
10.2.11 Conversions d’expressions constantes implicites
Une conversion d’expression constante implicite permet les conversions suivantes :
- Une constant_expression de type
int
peut être convertie en typesbyte
,byte
,short
,ushort
,uint
,nint
,nuint
ouulong
, à condition que la valeur du constant_expression se trouve dans la plage du type de destination. [...]
10.3.2 Conversions numériques explicites
Les conversions numériques explicites sont les conversions d’un numeric_type vers une autre numeric_type pour laquelle une conversion numérique implicite n’existe pas déjà :
- De
sbyte
àbyte
,ushort
,uint
,nuint
,ulong
ouchar
. - De
byte
àsbyte
ouchar
. - De
short
àsbyte
,byte
,ushort
,uint
,nuint
,ulong
ouchar
. - De
ushort
àsbyte
,byte
,short
ouchar
. - De
int
àsbyte
,byte
,short
,ushort
,uint
,nuint
,ulong
ouchar
. - De
uint
àsbyte
,byte
,short
,ushort
,int
,nint
ouchar
. - De
long
àsbyte
,byte
,short
,ushort
,int
,uint
,nint
,nuint
,ulong
ouchar
. - De
nint
àsbyte
,byte
,short
,ushort
,int
,uint
,nuint
,ulong
ouchar
. - De
nuint
àsbyte
,byte
,short
,ushort
,int
,uint
,nint
,long
ouchar
. - De
ulong
àsbyte
,byte
,short
,ushort
,int
,uint
,nint
,nuint
,long
ouchar
. - De
char
àsbyte
,byte
oushort
. - De
float
àsbyte
,byte
,short
,ushort
,int
,uint
,nint
,nuint
,long
,ulong
,char
oudecimal
. - De
double
àsbyte
,byte
,short
,ushort
,int
,uint
,nint
,nuint
,long
,ulong
,char
,float
oudecimal
. - De
decimal
àsbyte
,byte
,short
,ushort
,int
,uint
,nint
,nuint
,long
,ulong
,char
,float
oudouble
.
[...]
10.3.3 Conversions d’énumération explicites
Les conversions d’énumération explicites sont les suivantes :
- À partir de
sbyte
,byte
,short
,ushort
,int
,uint
,nint
,nuint
,long
,ulong
,char
,float
,double
oudecimal
à n’importe quel enum_type. - De n’importe quel enum_type à
sbyte
,byte
,short
,ushort
,int
,uint
,nint
,nuint
,long
,ulong
,char
,float
,double
oudecimal
. - De tout enum_type à tout autre enum_type.
12.6.4.7 Meilleure cible de conversion
Étant donné deux types T₁
et T₂
, T₁
est une meilleure cible de conversion que T₂
si l'un des critères suivants est rempli :
- Une conversion implicite de
T₁
enT₂
existe et aucune conversion implicite deT₂
enT₁
existe T₁
estTask<S₁>
,T₂
estTask<S₂>
etS₁
est une meilleure cible de conversion queS₂
T₁
estS₁
ouS₁?
oùS₁
est un type intégral signé etT₂
estS₂
ouS₂?
oùS₂
est un type intégral non signé. Plus précisément : [...]
Accès aux éléments 12.8.12
[...] Le nombre d’expressions dans la argument_list doit être identique au rang du array_type, et chaque expression doit être de type int
, uint
, nint
, nuint
, long
, ou ulong,
ou doit être implicitement convertible en un ou plusieurs de ces types.
11.8.12.2 Accès au tableau
[...] Le nombre d’expressions dans la argument_list doit être identique au rang du array_type, et chaque expression doit être de type int
, uint
, nint
, nuint
, long
, ou ulong,
ou doit être implicitement convertible en un ou plusieurs de ces types.
[...] Le traitement à l’exécution d’un accès à un tableau de la forme P[A]
, où P
est une primary_no_array_creation_expression d’un array_type et A
est une argument_list, consiste en les étapes suivantes : [...]
- Les expressions d’index de la argument_list sont évaluées dans l’ordre, de gauche à droite. Après l'évaluation de chaque expression d'index, une conversion implicite vers l'un des types suivants est effectuée :
int
,uint
,nint
,nuint
,long
,ulong
. Le premier type de cette liste pour lequel une conversion implicite existe est choisi. [...]
12.8.16 Opérateurs suffixés d’incrémentation et de décrémentation
La résolution de surcharge d’opérateur unaire est appliquée pour sélectionner une implémentation d’opérateur spécifique. Les opérateurs ++
et --
prédéfinis existent pour les types suivants : sbyte
, byte
, short
, ushort
, int
, uint
, nint
, nuint
,long
, ulong
, char
, float
, double
, decimal
et tout type d’énumération.
12.9.2 Opérateur unaire plus
Les opérateurs plus unaires prédéfinis sont les suivants :
...
nint operator +(nint x);
nuint operator +(nuint x);
12.9.3 Opérateur unaire moins
Les opérateurs moins unaires prédéfinis sont les suivants :
Négation entière :
... nint operator –(nint x);
12.8.16 Opérateurs suffixés d’incrémentation et de décrémentation
Les opérateurs ++
et --
prédéfinis existent pour les types suivants : sbyte
, byte
, short
, ushort
, int
, uint
, nint
, nuint
, long
, ulong
, char
, float
, double
, decimal
et tout type d’énumération.
11.7.19 Expressions de valeur par défaut
En outre, un default_value_expression est une expression constante si le type est l’un des types valeur suivants : sbyte
, byte
, short
, ushort
, int
, uint
, nint
, nuint
, long
, ulong
, char
, float
, double
, decimal
, bool,
ou tout type d’énumération.
12.9.5 Opérateur complément binaire
Les opérateurs de complément au niveau du bit prédéfinis sont les suivants :
...
nint operator ~(nint x);
nuint operator ~(nuint x);
12.9.6 Opérateurs d’incrémentation et de décrémentation de préfixe
Les opérateurs ++
et --
prédéfinis existent pour les types suivants : sbyte
, byte
, short
, ushort
, int
, uint
, nint
, nuint
, long
, ulong
, char
, float
, double
, decimal
et tout type d’énumération.
12.10 Opérateurs arithmétiques
12.10.2 Opérateur de multiplication
Les opérateurs de multiplication prédéfinis sont répertoriés ci-dessous. Les opérateurs calculent tous le produit de x
et de y
.
Multiplication des entiers :
... nint operator *(nint x, nint y); nuint operator *(nuint x, nuint y);
12.10.3 Opérateur de division
Les opérateurs de division prédéfinis sont répertoriés ci-dessous. Les opérateurs calculent tous le quotient de x
et de y
.
Division entière :
... nint operator /(nint x, nint y); nuint operator /(nuint x, nuint y);
12.10.4 Opérateur de reste
Les opérateurs de reste prédéfinis sont listés ci-dessous. Les opérateurs calculent tous le reste de la division entre x
et y
.
Reste entier :
... nint operator %(nint x, nint y); nuint operator %(nuint x, nuint y);
12.10.5 Opérateur d’addition
Ajout entier :
... nint operator +(nint x, nint y); nuint operator +(nuint x, nuint y);
12.10.6 Opérateur de soustraction
Soustraction entière :
... nint operator –(nint x, nint y); nuint operator –(nuint x, nuint y);
12.11 Opérateurs de décalage
Les opérateurs de décalage prédéfinis sont listés ci-dessous.
Décalage vers la gauche :
... nint operator <<(nint x, int count); nuint operator <<(nuint x, int count);
Décalage vers la droite :
... nint operator >>(nint x, int count); nuint operator >>(nuint x, int count);
L’opérateur
>>
déplacex
vers la droite d'un nombre de bits calculé comme décrit ci-dessous.Lorsque
x
est de typeint
,nint
oulong
, les bits de bas ordre dex
sont ignorés, les bits restants sont décalés vers la droite et les positions de bits vides de l’ordre élevé sont définies sur zéro six
est non négatif et défini sur un six
est négatif.Lorsque
x
est de typeuint
,nuint
ouulong
, les bits de bas ordre dex
sont ignorés, les bits restants sont décalés vers la droite et les positions de bits vides de l’ordre élevé sont définies sur zéro.Décalage logique à droite :
... nint operator >>>(nint x, int count); nuint operator >>>(nuint x, int count);
Pour les opérateurs prédéfinis, le nombre de bits à déplacer est calculé comme suit : [...]
- Lorsque le type de
x
estnint
ounuint
, le nombre de décalages est donné par les cinq bits decount
de faible ordre sur une plateforme 32 bits, ou les six bits decount
de l’ordre inférieur sur une plateforme 64 bits.
12.12 Opérateurs relationnels et de test de type
12.12.2 Opérateurs de comparaison d’entiers
Les opérateurs de comparaison d’entiers prédéfinis sont les suivants :
...
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 Opérateurs logiques
12.12.2 Opérateurs logiques entiers
Les opérateurs logiques entiers prédéfinis sont les suivants :
...
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);
Expressions constantes 12.22
Une expression constante peut être un type valeur ou un type référence. Si une expression constante est un type valeur, il doit s’agir de l’un des types suivants : sbyte
, byte
, short
, ushort
, int
, uint
, nint
, nuint
, long
, ulong
, char
, float
, double
, decimal
, bool,
ou tout type d’énumération.
[...]
Une conversion d’expression constante implicite permet à une expression constante de type int
d’être convertie en sbyte
, byte
, short
, ushort
, uint
, nint
, nuint
, ou ulong
, à condition que la valeur de l’expression constante se trouve dans la plage du type de destination.
Accès aux éléments de tableau 17.4
Les éléments de tableau sont accessibles à l’aide d’expressions element_access du formulaire A[I₁, I₂, ..., Iₓ]
, où A
est une expression d’un type de tableau et chaque Iₑ
est une expression de type int
, uint
, nint
, nuint
,long
, ulong
, ou peut être convertie implicitement en un ou plusieurs de ces types. Le résultat d’un accès à un élément de tableau est une variable, à savoir l’élément de tableau sélectionné par les index.
23.5 Conversions de pointeur
23.5.1 Général
[...]
En outre, dans un contexte non sécurisé, l’ensemble de conversions explicites disponibles est étendu pour inclure les conversions de pointeur explicite suivantes :
- De tout pointer_type à tout autre pointer_type.
- De
sbyte
,byte
,short
,ushort
,int
,uint
,nint
,nuint
,long
ouulong
à n’importe quel pointer_type. - De n’importe quel pointer_type à
sbyte
,byte
,short
,ushort
,int
,uint
,nint
,nuint
,long
ouulong
.
23.6.4 Accès à l’élément pointeur
[...] Dans un accès d’élément de pointeur du formulaire P[E]
, P
doit être une expression d’un type de pointeur autre que void*
, et E
doit être une expression qui peut être implicitement convertie en int
, uint
, nint
, nuint
,long
ou ulong
.
23.6.7 Arithmétique des pointeurs
Dans un contexte non sécurisé, l’opérateur +
et l’opérateur –
peuvent être appliqués aux valeurs de tous les types de pointeurs, sauf void*
. Ainsi, pour chaque type de pointeur T*
, les opérateurs suivants sont implicitement définis :
[...]
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);
Étant donné une expression P
d’un type pointeur T*
et une expression N
de type int
, uint
, nint
, nuint
,long
ou ulong
, les expressions P + N
et N + P
calculent la valeur de pointeur de type T*
qui résulte de l’ajout de N * sizeof(T)
à l’adresse donnée par P
. De même, l’expression P – N
calcule la valeur du pointeur de type T*
qui résulte de la soustraction des N * sizeof(T)
de l’adresse donnée par P
.
Différentes considérations
Changements cassants
L'un des principaux impacts de cette conception est que System.IntPtr
et System.UIntPtr
gagnent des opérateurs intégrés (conversions, unaires et binaires).
Ceux-ci incluent les opérateurs checked
, ce qui signifie que les opérateurs suivants sur ces types lanceront désormais une exception en cas de dépassement :
IntPtr + int
IntPtr - int
IntPtr -> int
long -> IntPtr
void* -> IntPtr
Encodage des métadonnées
Cette conception signifie que nint
et nuint
peuvent simplement être émis en tant que System.IntPtr
et System.UIntPtr
, sans utiliser System.Runtime.CompilerServices.NativeIntegerAttribute
.
De même, lors du chargement des métadonnées, NativeIntegerAttribute
peut être ignoré.
C# feature specifications