Почему Array. Длина int, а не uint
Почему Array.Length
Int, а не uint
, Это беспокоит меня (только немного), потому что значение длины никогда не может быть отрицательным.
Это также вынудило меня использовать int для свойства длины в моем собственном классе, потому что когда вы указываете int-значение, это должно быть приведено явно...
Итак, главный вопрос: есть ли смысл для неподписанного типа int (uint
)? Кажется, даже Microsoft не использует их.
5 ответов
Неподписанный int не совместим с CLS и поэтому будет ограничивать использование свойства теми языками, которые реализуют UInt
,
Посмотреть здесь:
Framework 1.1
Framework 2.0
Много причин:
- uint не соответствует CLS, поэтому создание зависимого от него встроенного типа (массива) было бы проблематичным
- Среда выполнения в том виде, в котором она была изначально разработана, запрещает любой объект в куче, занимающий более 2 ГБ памяти. Поскольку массив максимального размера, который был бы меньше или равен этому пределу, был бы новым байтом [int.MaxValue], людям было бы непонятно, чтобы иметь возможность генерировать положительные, но недопустимые длины массивов.
- Обратите внимание, что это ограничение было несколько снято в версии 4.5, хотя стандартная длина как int остается.
- Исторически C# наследует большую часть своего синтаксиса и соглашения от C и C++. В этих массивах есть просто арифметика указателей, поэтому возможна отрицательная индексация массива (хотя обычно это неправильно и опасно). Поскольку существующий код предполагает, что индекс массива подписан, это было бы фактором
- Относительно примечания: использование целых чисел со знаком для индексов массива в C/C++ означает, что взаимодействие с этими языками и неуправляемыми функциями в любом случае потребует использования int в этих условиях, что может привести к путанице из-за несоответствия.
- Реализация BinarySearch (очень полезный компонент многих алгоритмов) полагается на возможность использовать отрицательный диапазон типа int, чтобы указать, что значение не было найдено, и местоположение, в котором такое значение должно быть вставлено для поддержания сортировки.
- При работе с массивом вполне вероятно, что вы захотите принять отрицательное смещение существующего индекса. Если вы используете смещение, которое приведет вас к началу массива с использованием модуля, то поведение обтекания сделает ваш индекс, возможно, допустимым (в том смысле, что он положительный). С int результат будет недопустимым (но безопасным, поскольку среда выполнения защитит от чтения недопустимой памяти)
Я думаю, что это также может быть связано с упрощением вещей на более низком уровне, так как Array.Length, конечно, будет добавлен к отрицательному числу в некоторый момент, если Array.Length был беззнаковым, и добавлен к отрицательному int (дополнение к двум) Могут быть грязные результаты.
Похоже, никто не дал ответ на "окончательный вопрос".
Я считаю, что основное использование неподписанных целочисленных объектов заключается в том, чтобы обеспечить более простое взаимодействие с внешними системами (P/Invoke и т. П.) И удовлетворить потребности различных языков, портируемых на.NET.
Обычно целочисленные значения являются знаковыми, если только вам явно не нужно значение без знака. Это просто, как они используются. Возможно, я не согласен с этим выбором, но это так.
В настоящее время, с сегодняшними типичными ограничениями памяти, если вашему массиву или подобной структуре данных требуется длина UInt32, вы должны рассмотреть другие структуры данных.
С массивом байтов Int32 даст вам 2 ГБ значений