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