Мне кажется нелогичным, что Stream.Write использует int
вместо UInt
... Есть ли объяснение другого чем "устаревший" код для этого факта? Кто-нибудь захочет написать -1
bytes?!?
Почему Stream.Write не принимает UInt?
Ответ 1
Неподписанные типы не совместимы с CLS, поэтому Stream.Write
не использует uint
для смещения и подсчета.
Смотрите: uint (ссылка на С#)
Тип uint не соответствует CLS. Используйте int по возможности.
Существует старая статья: Почему у нас нет неподписанных типов в CLS от Brad Abrams (2 сентября 2003), что объясняет причину:
Однако есть одна проблема, которая продолжает расти: почему мы не допустили неподписанные типы (UInt32 и т.п.) в CLS?
Ну, на этот вопрос есть действительно два ответа. При первом уровне некоторых языков (например, VB.NET) не предлагают полной поддержки для unsigned types. Например, вы не можете иметь неподписанные литералы в VB.NET.... Но, честно говоря, это не вполне удовлетворительный ответ потому что, когда мы начали CLS, вы не могли подкласса в VB.NET либо, но мы расширили этот язык для поддержки того, что мы знали людей хотели бы. Мы могли бы сделать то же самое с неподписанными типами. Но мы этого не сделали. Почему нет? Ну, это имеет более глубокую причину. по факту та же самая причина, почему ранние бета-версии языка С# не поддерживали неподписанные типы (no ushort, uint и т.п.).
Общее чувство среди многих из нас заключается в том, что подавляющее большинство программирования с подписанными типами. Всякий раз, когда вы переключаетесь на неподписанные типы, вы умный модельный переключатель (и уродливый литье). В худшем фильме, который вы строите для всего параллельного мира API, которые используют неподписанные типы. Значение избежания проверки "< 0" не стоит включать дженерики в CLS.
(Обратите внимание, что более новая версия VB.Net(VB 8 onwards) поддерживает неподписанные типы).
Еще одна вещь (возможно, не связанная) для добавления, Stream.Write
реализация имеет проверки на отрицательные значения:
[System.Security.SecuritySafeCritical] // auto-generated
public override void Write(byte[] array, int offset, int count) {
if (array==null)
throw new ArgumentNullException("array", Environment.GetResourceString("ArgumentNull_Buffer"));
if (offset < 0)
throw new ArgumentOutOfRangeException("offset", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
if (count < 0)
throw new ArgumentOutOfRangeException("count", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
if (array.Length - offset < count)
throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen"));
Ответ 2
Тип uint не соответствует CLS. Используйте int по возможности.
Итак, Stream.Write
использует int для смещения и подсчета.
Причины предоставленные ShuggyCoUk, делают это более понятным:
- uint не соответствует CLS, поэтому создание зависимого от него встроенного типа (массива) было бы проблематичным.
- Время выполнения как первоначально разработанная, запрещает любой объект в куче, занимающий больше чем 2 ГБ памяти. Поскольку массив максимального размера, который будет меньше, чем или равным этому пределу, будет новый байт [int.MaxValue], это будет озадачивает людей, чтобы иметь возможность генерировать позитивный, но незаконный массив длины.
- Обратите внимание, что это ограничение было несколько удалено в версии 4.5, хотя стандартная длина как int остается.
- Исторически С# наследует большая часть его синтаксиса и соглашения с C и С++. В этих массивах просто указательная арифметика, поэтому возможно отрицательное индексирование массива (хотя обычно незаконно и опасно). Поскольку существующий код предполагает, что индекс массива отрицательный, это было бы фактором
- В соответствующей заметке использование знаковых целых чисел для индексов массивов в C/С++ означает, что взаимодействие с этими языками и неуправляемыми функциями в любом случае потребует использования ints в этих обстоятельствах, что может путают из-за несогласованности.
- Реализация BinarySearch (очень полезный компонент многих алгоритмов) полагается на возможность используйте отрицательный диапазон int, чтобы указать, что значение не было найдено и местоположение, в которое такое значение должно быть вставлено в поддерживать сортировку.
- При работе с массивом, вероятно, вы хотел бы принять отрицательное смещение существующего индекса. Если вы использовали смещение, которое приведет вас к началу массива с использованием единицы то обход вокруг поведения сделает ваш индекс, возможно, законным (в том смысле, что он положительный). С результатом int результат был бы незаконным (но безопасно, поскольку среда выполнения защитит от чтения недопустимой памяти).
Ответ 3
Верьте или нет, целые числа без знака не являются частью Common Language Specification (CLS).
Тип uint не соответствует CLS. Используйте int по возможности.
Таким образом, Microsoft использовала int
здесь вместо uint
в интересах CLS-compliancy.