Poznámka:
Přístup k této stránce vyžaduje autorizaci. Můžete se zkusit přihlásit nebo změnit adresáře.
Přístup k této stránce vyžaduje autorizaci. Můžete zkusit změnit adresáře.
Poznámka
Tento článek je specifikace funkce. Specifikace slouží jako návrhový dokument pro funkci. Zahrnuje navrhované změny specifikace spolu s informacemi potřebnými při návrhu a vývoji funkce. Tyto články se publikují, dokud nebudou navrhované změny specifikace finalizovány a začleněny do aktuální specifikace ECMA.
Mezi specifikací funkce a dokončenou implementací může docházet k nějakým nesrovnalostem. Tyto rozdíly jsou zachyceny v poznámkách příslušné schůzky k návrhu jazyka (LDM) .
Další informace o procesu přijetí specifikací funkcí do jazyka C# najdete v článku o specifikacích .
Problém šampiona: https://github.com/dotnet/csharplang/issues/6065
Shrnutí
Toto je revize původní vlastnosti nativních celých čísel (specifikace), kde nint/nuint typy byly odlišné od základních typů System.IntPtr/System.UIntPtr.
Stručně řečeno, nyní považujeme nint/nuint za jednoduché typy aliasing System.IntPtr/System.UIntPtr, stejně jako int ve vztahu k System.Int32. Příznak funkce modulu runtime System.Runtime.CompilerServices.RuntimeFeature.NumericIntPtr aktivuje toto nové chování.
Návrh
8.3.5 Jednoduché typy
Jazyk C# poskytuje sadu předdefinovaných typů struct označovaných jako jednoduché typy. Jednoduché typy jsou identifikovány prostřednictvím klíčových slov, ale tato klíčová slova jsou jednoduše aliasy pro předdefinované typy struct v oboru názvů System, jak je popsáno v následující tabulce.
| klíčové slovo | typ aliasu |
|---|---|
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ální typy
Jazyk C# podporuje jedenáct integrálních typů: sbyte, byte, short, ushort, int, uint, nint, nuint, long, ulonga char. [...]
8.8 Nespravované typy
Jinými slovy, unmanaged_type je jedna z následujících možností:
-
sbyte,byte,short,ushort,int,uint,nint,nuint,long,ulong,char,float,double,decimalnebobool. - Všechny enum_type.
- Jakýkoli uživatelem definovaný struct_type, který není konstruovaný typ a obsahuje pouze pole unmanaged_types.
- V nebezpečném kódu může být jakýkoli pointer_type.
10.2.3 Implicitní číselné převody
Implicitní číselné převody jsou:
- Od
sbyteposhort,int,nint,long,float,doublenebodecimal. - Od
byteposhort,ushort,int,uint,nint,nuint,long,ulong,float,doublenebodecimal. - Od
shortpoint,nint,long,float,doublenebodecimal. - Od
ushortpoint,uint,nint,nuint,long,ulong,float,doublenebodecimal. - Od
intponint,long,float,doublenebodecimal. - Od
uintponuint,long,ulong,float,doublenebodecimal. -
od
nintdolong,float,doublenebodecimal. -
od
nuintdoulong,float,doublenebodecimal. - Od
longpofloat,doublenebodecimal. - Od
ulongpofloat,doublenebodecimal. - Od
charpoushort,int,uint,nint,nuint,long,ulong,float,doublenebodecimal. - Od
floatdodouble.
[...]
10.2.11 Implicitní převody konstantních výrazů
Převod implicitního konstantního výrazu umožňuje následující převody:
-
constant_expression typu
intlze převést na typsbyte,byte,short,ushort,uint,nint,nuintneboulong, za předpokladu, že hodnota constant_expression je v rozsahu cílového typu. [...]
10.3.2 Explicitní číselné převody
Explicitní číselné převody jsou převody z numeric_type do jiného numeric_type, pro které implicitní číselný převod ještě neexistuje:
- Od
sbytepobyte,ushort,uint,nuint,ulongnebochar. - Od
bytedosbytenebochar. - Od
shortposbyte,byte,ushort,uint,nuint,ulongnebochar. - Od
ushortposbyte,byte,shortnebochar. - Od
intposbyte,byte,short,ushort,uint,nuint,ulongnebochar. - Od
uintposbyte,byte,short,ushort,int,nintnebochar. - Od
longposbyte,byte,short,ushort,int,uint,nint,nuint,ulongnebochar. -
nintsbyte,byte,short,ushort,int,uint,nuint,ulongnebochar. -
nuintsbyte,byte,short,ushort,int,uint,nint,longnebochar. - Od
ulongposbyte,byte,short,ushort,int,uint,nint,nuint,longnebochar. - Od
charposbyte,byteneboshort. - Od
floatposbyte,byte,short,ushort,int,uint,nint,nuint,long,ulong,charnebodecimal. - Od
doubleposbyte,byte,short,ushort,int,uint,nint,nuint,long,ulong,char,floatnebodecimal. - Od
decimalposbyte,byte,short,ushort,int,uint,nint,nuint,long,ulong,char,floatnebodouble.
[...]
10.3.3 Explicitní výčtové převody
Explicitní převody výčtu jsou:
- Z
sbyte,byte,short,ushort,int,uint,nint,nuint,long,ulong,char,float,doublenebodecimalna jakýkoliv enum_type. - Z libovolné enum_type na
sbyte,byte,short,ushort,int,uint,nint,nuint,long,ulong,char,float,doublenebodecimal. - Z jakéhokoliv typu enum_type do jakéhokoliv jiného typu enum_type.
12.6.4.7 Lepší cíl převodu
Vzhledem ke dvěma typům T₁ a T₂je T₁lepším cílem převodu než T₂, pokud platí některá z následujících možností:
- Implicitní převod z
T₁naT₂existuje a neexistuje žádný implicitní převod zT₂naT₁. -
T₁jeTask<S₁>,T₂jeTask<S₂>aS₁je lepším cílem převodu nežS₂ -
T₁jeS₁neboS₁?, kdeS₁je celočíselný typ aT₂jeS₂neboS₂?, kdeS₂je celočíselný typ bez znaménka. Konkrétně: [...]
12.8.12 Přístup k elementům
[...] Počet výrazů v argument_list musí být stejný jako pořadí array_typea každý výraz musí být typu int, uint, nint, nuint, longnebo ulong, nebo implicitně převést na jeden nebo více těchto typů.
11.8.12.2 Přístup k poli
[...] Počet výrazů v argument_list musí být stejný jako pořadí array_typea každý výraz musí být typu int, uint, nint, nuint, longnebo ulong, nebo implicitně převést na jeden nebo více těchto typů.
[...] Zpracování přístupu k poli ve tvaru P[A], kde P je primární výraz pro vytvoření pole určitého typu pole a A je seznam argumentů, se skládá z následujících kroků: [...]
- Výrazy indexu argument_list se vyhodnocují v pořadí zleva doprava. Po vyhodnocení každého výrazu indexu se provádí implicitní převod na jeden z následujících typů:
int,uint,nint,nuint,long,ulong. První typ v tomto seznamu, pro který existuje implicitní převod, je vybrán. [...]
12.8.16 Operátory přírůstku a dekrementace
Rozlišení přetížení unárního operátoru se použije k výběru konkrétní implementace operátoru. Předdefinované operátory ++ a -- existují pro následující typy: sbyte, byte, short, ushort, int, uint, nint, nuint,long, ulong, char, float, double, decimala jakýkoli typ výčtu.
12.9.2 Unární operátor plus
Předdefinované unární operátory plus jsou:
...
nint operator +(nint x);
nuint operator +(nuint x);
12.9.3 Unární operátor minus
Předdefinované operátory unárního minusu jsou:
Celočíselná negace:
... nint operator –(nint x);
12.8.16 Operátory přírůstku a dekrementace
Předdefinované operátory ++ a -- existují pro následující typy: sbyte, byte, short, ushort, int, uint, nint, nuint, long, ulong, char, float, double, decimala libovolný typ výčtu.
11.7.19 Výrazy výchozí hodnoty
Kromě toho je default_value_expression konstantní výraz, pokud je typ jedním z následujících typů hodnot: sbyte, byte, short, ushort, int, uint, nint, nuint, long, ulong, char, float, double, decimal, bool, nebo jakýkoli typ výčtu.
12.9.5 Bitový operátor doplňku
Předdefinované bitové doplňkové operátory jsou:
...
nint operator ~(nint x);
nuint operator ~(nuint x);
12.9.6 Operátory inkrementace a dekrementace předpon
Předdefinované operátory ++ a -- existují pro následující typy: sbyte, byte, short, ushort, int, uint, nint, nuint, long, ulong, char, float, double, decimala libovolný typ výčtu.
12.10 Aritmetické operátory
12.10.2 Operátor násobení
Předdefinované operátory násobení jsou uvedeny níže. Všechny operátory vypočítají součin x a y.
Celočíselné násobení:
... nint operator *(nint x, nint y); nuint operator *(nuint x, nuint y);
12.10.3 Operátor dělení
Níže jsou uvedeny předdefinované operátory dělení. Všechny operátory vypočítají podíl x a y.
Celočíselné dělení:
... nint operator /(nint x, nint y); nuint operator /(nuint x, nuint y);
12.10.4 Operátor zbytku
Níže jsou uvedeny předdefinované operátory zbytku. Operátoři vypočítají zbytek dělení z x na y.
Celý zbytek:
... nint operator %(nint x, nint y); nuint operator %(nuint x, nuint y);
12.10.5 Operátor sčítání
Celočíselné sčítání:
... nint operator +(nint x, nint y); nuint operator +(nuint x, nuint y);
12.10.6 Operátor odčítání
Odčítání celých čísel:
... nint operator –(nint x, nint y); nuint operator –(nuint x, nuint y);
12.11 Posunové operátory
Níže jsou uvedeny předdefinované operátory posunu.
Posun doleva:
... nint operator <<(nint x, int count); nuint operator <<(nuint x, int count);Posunout doprava:
... nint operator >>(nint x, int count); nuint operator >>(nuint x, int count);Operátor
>>posunexdoprava o počet bitů vypočítaný podle níže uvedených instrukcí.Pokud je
xtypuint,nintnebolong, zahodí se bityxs nízkým pořadím, zbývající bity se posunou doprava a pozice prázdných bitů s vysokým pořadím se nastaví na nulu, pokud jexnezáporná a nastaví se na jednu, pokud jexzáporná.Pokud je
xtypuuint,nuintneboulong, bityxs nízkým pořadím se zahodí, zbývající bity se posunou doprava a pozice prázdných bitů s vysokým pořadím se nastaví na nulu.Posun bez znaménka doprava:
... nint operator >>>(nint x, int count); nuint operator >>>(nuint x, int count);
Pro předdefinované operátory se počet bitů pro posun vypočítá takto: [...]
- Pokud je typ
xnintnebonuint, počet posunů je dán nižšími pěti bitycountna 32bitové platformě nebo nižšími šesti bitycountna 64bitové platformě.
12.12 Relační operátory a operátory pro testování typů
12.12.2 Celočíselné relační operátory
Předdefinované celočíselné relační operátory jsou:
...
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 Logické operátory
12.12.2 Celočíselné logické operátory
Předdefinované celočíselné logické operátory jsou:
...
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 Konstantní výrazy
Konstantní výraz může být buď typ hodnoty, nebo odkazový typ. Pokud je konstantním výrazem typ hodnoty, musí to být jeden z následujících typů: sbyte, byte, short, ushort, int, uint, nint, nuint, long, ulong, char, float, double, decimal, bool, nebo jakýkoli typ výčtu.
[...]
Implicitní převod konstantního výrazu umožňuje převést konstantní výraz typu int na sbyte, byte, short, ushort, uint, ulong nebo , za předpokladu, že hodnota konstantního výrazu je v rozsahu cílového typu.
Přístup k elementu Array 17.4
K prvkům pole se přistupuje pomocí výrazů element_access formuláře A[I₁, I₂, ..., Iₓ], kde A je výraz typu pole a každý Iₑ je výraz typu int, uint, nint, nuint,long, ulongnebo lze implicitně převést na jeden nebo více těchto typů. Výsledkem přístupu k prvku pole je proměnná, konkrétně prvek pole vybraný indexy.
23.5 Převody ukazatelů
23.5.1 Obecné
[...]
Kromě toho je v nezabezpečeném kontextu rozšířena sada dostupných explicitních převodů tak, aby zahrnovala následující explicitní převody ukazatelů:
- Z jakéhokoli pointer_type do jakéhokoli jiného pointer_type.
- Z
sbyte,byte,short,ushort,int,uint, ,nint,nuint,,longneboulongna jakýkoli pointer_type. - Z libovolného pointer_type na
sbyte,byte,short,ushort,int,uint,nint,nuint,longneboulong.
Přístup k prvku ukazatele 23.6.4
[...] Při přístupu prvku ukazatele P[E]formuláře musí být P výrazem jiného typu ukazatele než void*a E musí být výraz, který lze implicitně převést na int, uint, nint, nuint,longnebo ulong.
23.6.7 Aritmetika ukazatele
V nebezpečném kontextu lze operátor + a operátor – použít na hodnoty všech typů ukazatelů s výjimkou void*. Proto pro každý typ ukazatele T*jsou implicitně definovány následující operátory:
[...]
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);
Výraz P typu ukazatele T* a výraz N typu int, uint, nint, nuint,longnebo ulong; výrazy P + N a N + P vypočítají hodnotu ukazatele typu T*, která vznikne přidáním N * sizeof(T) k adrese dané P. Podobně výraz P – N vypočítá hodnotu ukazatele typu T*, která má za následek odečtení N * sizeof(T) z adresy zadané P.
Různé aspekty
Zásadní změny
Jedním z hlavních dopadů tohoto návrhu je, že System.IntPtr a System.UIntPtr získají některé vestavěné operátory (převody, unární a binární).
Patří mezi ně checked operátory, což znamená, že následující operátory na těchto typech nyní vyvolají chybu při přetečení:
IntPtr + intIntPtr - intIntPtr -> intlong -> IntPtrvoid* -> IntPtr
Kódování metadat
Tento návrh znamená, že nint a nuint lze jednoduše vygenerovat jako System.IntPtr a System.UIntPtrbez použití System.Runtime.CompilerServices.NativeIntegerAttribute.
Podobně lze při načítání metadat NativeIntegerAttribute ignorovat.
C# feature specifications