Ескертпе
Бұл бетке кіру үшін қатынас шегін айқындау қажет. Жүйеге кіруді немесе каталогтарды өзгертуді байқап көруге болады.
Бұл бетке кіру үшін қатынас шегін айқындау қажет. Каталогтарды өзгертуді байқап көруге болады.
Заметка
Эта статья является спецификацией компонентов. Спецификация служит проектным документом для функции. Она включает предлагаемые изменения спецификации, а также информацию, необходимую во время проектирования и разработки функции. Эти статьи публикуются до тех пор, пока предложенные изменения спецификации не будут завершены и включены в текущую спецификацию ECMA.
Может возникнуть некоторое несоответствие между спецификацией компонентов и завершенной реализацией. Эти различия отражены в соответствующих заседаниях, посвящённых проектированию языка (LDM).
Дополнительные сведения о процессе внедрения спецификаций функций в стандарт языка C# см. в статье о спецификациях .
Выпуск чемпиона: https://github.com/dotnet/csharplang/issues/6065
Сводка
Это редакция функции начальных собственных целых чисел (спецификации), где типы nint/nuint отличались от базовых типов System.IntPtr/System.UIntPtr.
Короче говоря, теперь мы рассматриваем nint/nuint как псевдонимы простых типов System.IntPtr/System.UIntPtr, подобно тому как мы делаем для int относительно System.Int32. Флаг функции среды выполнения System.Runtime.CompilerServices.RuntimeFeature.NumericIntPtr активирует это новое поведение.
Дизайн
8.3.5 Простые типы
C# предоставляет набор стандартных struct типов, называемых простыми типами. Простые типы определяются с помощью ключевых слов, но эти ключевые слова являются просто псевдонимами для предопределенных типов struct в пространстве имен System, как описано в таблице ниже.
| Ключевое слово | Псевдоним типа |
|---|---|
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 Целочисленные типы
C# поддерживает одиннадцать целочисленных типов: sbyte, byte, short, ushort, int, uint, nint, nuint, long, ulongи char. [...]
8.8 Неуправляемые типы
Другими словами, unmanaged_type является одним из следующих:
-
sbyte,byte,shortushort,int,uint,nint,nuint,long,ulong,char,float,double,decimalилиbool. - Любая enum_type.
- Любая определяемая пользователем структура типа, которая не является сконструированным типом и содержит только поля типа unmanaged_type.
- В небезопасном коде любые pointer_type.
10.2.3 Неявные числовые преобразования
Неявные числовые преобразования:
- От
sbyteдоshort,int,nint,long,float,doubleилиdecimal. - От
byteдоshort,ushort,int,uint,nint,nuint,long,ulong,floatdoubleилиdecimal. - От
shortдоint,nint,long,float,doubleилиdecimal. - От
ushortдоint,uint,nint,nuint,long,ulong,float,doubleилиdecimal. - От
intдоnint,long,float,doubleилиdecimal. - От
uintдоnuint,long,ulong,float,doubleилиdecimal. -
от
nintдоlong,float,doubleилиdecimal. -
от
nuintдоulong,float,doubleилиdecimal. - От
longдоfloat,doubleилиdecimal. - От
ulongдоfloat,doubleилиdecimal. - От
charдоushort,int,uint,nint,nuint,long,ulong,float,doubleилиdecimal. - От
floatдоdouble.
[...]
Преобразования неявных константных выражений 10.2.11
Неявное преобразование константного выражения позволяет выполнить следующие преобразования:
-
constant_expression типа
intможно преобразовать в типsbyte,byte,short,ushort,uint,nint,nuintилиulong, если значение constant_expression находится в диапазоне целевого типа. [...]
10.3.2 Явные числовые преобразования
Явные числовые преобразования — это преобразования из numeric_type в другую numeric_type, для которой неявное числовое преобразование еще не существует:
- От
sbyteдоbyte,ushort,uint,nuint,ulongилиchar. - От
byteдоsbyteилиchar. - От
shortдоsbyte,byte,ushort,uint,nuint,ulongилиchar. - От
ushortдоsbyte,byte,shortилиchar. - От
intдоsbyte,byte,short,ushort,uint,nuint,ulongилиchar. - От
uintдоsbyte,byte,short,ushort,int,nintилиchar. - От
longдоsbyte,byte,short,ushort,int,uint,nint,nuint,ulongилиchar. -
от
nintдоsbyte,byte,short,ushort,int,uint,nuint,ulongилиchar. -
от
nuintдоsbyte,byte,short,ushort,int,uint,nint,longилиchar. - От
ulongдоsbyte,byte,short,ushort,int,uint,nint,nuint,longилиchar. - От
charдоsbyte,byteилиshort. - От
floatдоsbyte,byte,short,ushort,int,uint,nint,nuint,long,ulong,charилиdecimal. - От
doubleдоsbyte,byte,short,ushort,int,uint,nint,nuint,long,ulong,char,floatилиdecimal. - От
decimalдоsbyte,byte,short,ushort,int,uint,nint,nuint,long,ulong,char,floatилиdouble.
[...]
10.3.3 Явные преобразования типов перечисления
Конкретные преобразования перечисления:
- От
sbyte,byte,short,ushort,int,uint, ,nint,nuint,,long,ulong,char,float,doubleилиdecimalв любое enum_type. - От любого enum_type до
sbyte,byte,short,ushort,int,uint,nint,nuintlong,ulong,char,float,doubleилиdecimal. - От любого enum_type до любого другого enum_type.
12.6.4.7 Лучший целевой объект преобразования
Учитывая два типа T₁ и T₂, T₁ — это лучший целевой объект преобразования, чем T₂, если выполняется одно из следующих условий:
- Неявное преобразование из
T₁вT₂существует и неявное преобразование изT₂вT₁не существует. -
T₁- этоTask<S₁>,T₂- этоTask<S₂>, иS₁является более подходящей целью для преобразования, чемS₂ -
T₁S₁илиS₁?, гдеS₁является подписанным целочисленным типом,T₂S₂илиS₂?, гдеS₂является целочисленным типом без знака. В частности: [...]
12.8.12 Доступ к элементу
[...] Число выражений в argument_list должно совпадать с рангом array_type, а каждое выражение должно быть типом int, uint, nint, nuint, longили ulong, или неявно преобразовано в один или несколько этих типов.
Доступ к массиву 11.8.12.2
[...] Число выражений в argument_list должно совпадать с рангом array_type, а каждое выражение должно быть типом int, uint, nint, nuint, longили ulong, или неявно преобразовано в один или несколько этих типов.
[...] Обработка обращения к массиву формы P[A], где P является primary_no_array_creation_expression типа array_type, а A является argument_list, состоит из следующих шагов: [...]
- Выражения индекса argument_list вычисляются по порядку слева направо. После оценки каждого выражения индекса выполняется неявное преобразование в один из следующих типов:
int,uint,nint,nuint,long,ulong. Первый тип в этом списке, для которого существует неявное преобразование, выбирается. [...]
12.8.16 Операторы постфиксного инкремента и декремента
Разрешение перегрузки унарного оператора применяется для выбора конкретной реализации оператора. Стандартные операторы ++ и -- существуют для следующих типов: sbyte, byte, short, ushort, int, uint, ,nint, nuint,,long, ulong, char, float, double, decimalи любого типа перечисления.
Оператор 12.9.2 Unary plus
Стандартные унарные операторы плюс:
...
nint operator +(nint x);
nuint operator +(nuint x);
12.9.3 Оператор унарного минуса
Стандартные унарные операторы минус:
Целочисленное отрицание:
... nint operator –(nint x);
12.8.16 Операторы постфиксного инкремента и декремента
Стандартные операторы ++ и -- существуют для следующих типов: sbyte, byte, short, ushort, int, uint, nint, nuint, long, ulong, char, float, double, decimalи любого типа перечисления.
Выражения значений по умолчанию 11.7.19
Кроме того, default_value_expression является константным выражением, если тип является одним из следующих типов значений: sbyte, byte, short, ushort, int, uint, nint, nuint, long, ulong, char, float, double, decimal, bool, или любого типа перечисления.
Оператор дополнения 12.9.5 Bitwise
Стандартные операторы битового дополнения:
...
nint operator ~(nint x);
nuint operator ~(nuint x);
12.9.6 Префиксные инкрементные и декрементные операторы
Стандартные операторы ++ и -- существуют для следующих типов: sbyte, byte, short, ushort, int, uint, nint, nuint, long, ulong, char, float, double, decimalи любого типа перечисления.
12.10 Арифметические операторы
Оператор умножения 12.10.2
Ниже перечислены предопределенные операторы умножения. Все операторы вычисляют продукт x и y.
Целочисленное умножение:
... nint operator *(nint x, nint y); nuint operator *(nuint x, nuint y);
12.10.3 Оператор деления
Ниже перечислены предопределенные операторы деления. Все операторы вычисляют частное x на y.
Целочисленное деление
... nint operator /(nint x, nint y); nuint operator /(nuint x, nuint y);
Оператор остатка 12.10.4
Ниже перечислены предопределенные операторы остатка. Все операторы вычисляют оставшуюся часть деления между x и y.
Остаток целочисленного числа:
... nint operator %(nint x, nint y); nuint operator %(nuint x, nuint y);
Оператор сложения 12.10.5
Добавление целых чисел:
... nint operator +(nint x, nint y); nuint operator +(nuint x, nuint y);
12.10.6 Оператор вычитания
Вычитание целочисленного числа:
... nint operator –(nint x, nint y); nuint operator –(nuint x, nuint y);
Операторы сдвига 12.11
Ниже перечислены предопределенные операторы смены.
Сдвиг влево
... nint operator <<(nint x, int count); nuint operator <<(nuint x, int count);Сдвиг вправо:
... nint operator >>(nint x, int count); nuint operator >>(nuint x, int count);Оператор
>>сдвигаетxвправо на несколько битов, вычисляемых, как описано ниже.Если
xимеет типint,nintилиlong, то младшие битыxудаляются, оставшиеся биты сдвигаются вправо, а старшие пустые позиции устанавливаются в ноль, еслиxне является отрицательным, и устанавливаются в единицу, еслиxотрицательное.Если
xимеет типuint,nuintилиulong, то биты с низким порядкомxудаляются, остальные биты сдвигаются вправо, а пустые позиции с высоким порядком пустых битов равны нулю.Беззнаковый сдвиг вправо:
... nint operator >>>(nint x, int count); nuint operator >>>(nuint x, int count);
Для предопределенных операторов число битов для смены вычисляется следующим образом: [...]
- Если тип
x—nintилиnuint, число сдвигов определяется пятью младшими битамиcountна 32-разрядной платформе или шестью младшими битамиcountна 64-разрядной платформе.
Операторы реляционного и типового тестирования 12.12
Операторы сравнения целых чисел 12.12.2
Стандартные операторы сравнения целых чисел:
...
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
12.12.2 Целочисленные логические операторы
Стандартные логические операторы целого числа:
...
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 Константные выражения
Константное выражение может быть либо типом значения, либо ссылочным типом. Если константное выражение является типом значения, оно должно быть одним из следующих типов: sbyte, byte, short, ushort, int, uint, nint, nuint, long, ulong, char, float, double, decimal, bool, или любого типа перечисления.
[...]
Преобразование неявного константного выражения позволяет преобразовать константное выражение типа int в sbyte, byte, short, ushort, uint, nint, nuint или ulong, если значение константного выражения находится в диапазоне конечного типа.
Доступ к элементу массива 17.4
Доступ к элементам массива осуществляется с использованием element_access выражений в форме A[I₁, I₂, ..., Iₓ], где A является выражением типа массива, а каждое Iₑ — выражение типа int, uint, nint, nuint,long, ulongили может быть неявно преобразовано в один или несколько этих типов. Результатом доступа к элементу массива является переменная, а именно элемент массива, выбранный индексами.
23.5 Преобразования указателей
23.5.1 Общие
[...]
Кроме того, в небезопасном контексте набор доступных явных преобразований расширяется, чтобы включить следующие явные преобразования указателя:
- От любого указателя типа к любому другому указателю типа.
- От
sbyte,byte,short,ushort,int,uint, ,nint,nuint,longилиulongв любой pointer_type. - От любого pointer_type до
sbyte,byte,short,ushort,int,uint,nint,nuint,longилиulong.
Доступ к элементу указателя 23.6.4
[...] В доступе к элементу формы P[E]P должен быть выражением типа указателя, отличного от void*, и E должно быть выражением, которое может быть неявно преобразовано в int, uint, nint, nuint,longили ulong.
23.6.7 Арифметика указателей
В небезопасном контексте оператор + и – можно применять к значениям всех типов указателей, кроме void*. Таким образом, для каждого типа указателя T*неявно определены следующие операторы:
[...]
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);
Учитывая выражение P типа указателя T* и выражение N типа int, uint, nint, nuint,longили ulong, выражения P + N и N + P вычисляют значение указателя типа T*, которое приводит к добавлению N * sizeof(T) в адрес, заданный P. Аналогичным образом, выражение P – N вычисляет значение указателя типа T*, которое получается в результате вычитания N * sizeof(T) из адреса, заданного P.
Различные соображения
Серьезные изменения
Одним из основных последствий этого дизайна является то, что System.IntPtr и System.UIntPtr получают некоторые встроенные операторы (преобразования, унарные и двоичные).
К ним относятся операторы checked, что означает, что следующие операторы для этих типов теперь будут вызываться при переполнении:
IntPtr + intIntPtr - intIntPtr -> intlong -> IntPtrvoid* -> IntPtr
Кодировка метаданных
Это проектирование означает, что nint и nuint могут быть просто переданы как System.IntPtr и System.UIntPtr, без использования System.Runtime.CompilerServices.NativeIntegerAttribute.
Аналогичным образом, при загрузке метаданных NativeIntegerAttribute следует игнорировать.
C# feature specifications