Почему Array.Length
int, а не a uint
. Это беспокоит меня (только немного), потому что значение длины никогда не может быть отрицательным.
Это также вынудило меня использовать int для свойства длины в моем собственном классе, потому что когда вы указываете int-значение, это должно быть приведено явно ...
Итак, главный вопрос: есть ли смысл для unsigned int ( uint
)? Кажется, даже Microsoft не использует их.
Неподписанный int не совместим с CLS и поэтому будет ограничивать использование свойства теми языками, которые реализуют a UInt
.
Посмотреть здесь:
Framework 1.1
Framework 2.0
Как правило, целочисленные значения являются знаковыми, если вам явно не нужно значение без знака. Это просто, как они используются. Возможно, я не согласен с этим выбором, но это так.
В настоящее время, с сегодняшними типичными ограничениями памяти, если вашему массиву или подобной структуре данных требуется длина UInt32, вы должны рассмотреть другие структуры данных.
Int32 предоставит вам 2 ГБ значений с массивом байтов
Я думаю, что это также может иметь отношение к упрощению вещей на более низком уровне, так как Array.Length, конечно, будет добавлен к отрицательному числу в некоторый момент, если Array.Length был беззнаковым, и добавлен к отрицательному int (дополнение к двум) Могут быть грязные результаты.
uint lenght = 3;int x = -4;Console.WriteLine(x+lenght);
дает -1 просто отлично. Похоже, никто не дал ответ на «окончательный вопрос».
Я полагаю, что основное использование неподписанных целочисленных объектов состоит в том, чтобы облегчить взаимодействие с внешними системами (P / Invoke и т. П.) И покрыть потребности различных языков, портируемых на .NET.
(HighPart << 16) + LowPart
, а один можно разделить UInt32 на два UInt16 через (Uint16)(Value >> 16)
и (Uint16)(Value & 65535)
. Такие операции были бы очень неудобными, если бы LowPart
они были подписанного типа. При этом взаимодействие между типами со знаком и без знака часто бывает запутанным и проблематичным. Неподписанные типы во многом должны рассматриваться как их собственный мир. Много причин:
- uint не соответствует CLS, поэтому создание зависимого от него встроенного типа (массива) было бы проблематичным
- Среда выполнения в первоначальном виде запрещает любой объект в куче, занимающий более 2 ГБ памяти. Поскольку массив максимального размера, который был бы меньше или равен этому пределу, был бы новым байтом [int.MaxValue], людям было бы непонятно, чтобы иметь возможность генерировать положительную, но недопустимую длину массива.
- Обратите внимание, что это ограничение было несколько снято в версии 4.5 , хотя стандартная длина как int остается.
- Исторически C # наследует большую часть своего синтаксиса и соглашения от C и C ++. В этих массивах есть просто арифметика указателей, поэтому возможна отрицательная индексация массива (хотя обычно это неправильно и опасно). Поскольку существующий код предполагает, что индекс массива подписан, это было бы фактором
- Относительно примечания: использование целых чисел со знаком для индексов массивов в C / C ++ означает, что взаимодействие с этими языками и неуправляемыми функциями в любом случае потребует использования int в этих условиях, что может привести к путанице из-за несоответствия.
- Реализация BinarySearch (очень полезный компонент многих алгоритмов) полагается на возможность использовать отрицательный диапазон типа int, чтобы указать, что значение не было найдено, и местоположение, в котором такое значение должно быть вставлено для поддержания сортировки.
- При работе с массивом вполне вероятно, что вы захотите принять отрицательное смещение существующего индекса. Если вы используете смещение, которое приведет вас к началу массива с использованием модуля, то поведение обтекания сделает ваш индекс, возможно, допустимым (в том смысле, что он положительный). С int результат будет недопустимым (но безопасным, поскольку среда выполнения защитит от чтения недопустимой памяти)
maxArrayLength
и maxBytesPerRead
которые ретроспективно делает много смысла с этой информацией. Соединяя точки ...