Подтвердить что ты не робот

Почему Stream.Write не принимает UInt?

Мне кажется нелогичным, что Stream.Write использует int вместо UInt... Есть ли объяснение другого чем "устаревший" код для этого факта? Кто-нибудь захочет написать -1 bytes?!?

4b9b3361

Ответ 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

Из только для MSDN

Тип uint не соответствует CLS. Используйте int по возможности.

Итак, Stream.Write использует int для смещения и подсчета.

Причины предоставленные ShuggyCoUk, делают это более понятным:

  • uint не соответствует CLS, поэтому создание зависимого от него встроенного типа (массива) было бы проблематичным.
  • Время выполнения как первоначально разработанная, запрещает любой объект в куче, занимающий больше чем 2 ГБ памяти. Поскольку массив максимального размера, который будет меньше, чем или равным этому пределу, будет новый байт [int.MaxValue], это будет озадачивает людей, чтобы иметь возможность генерировать позитивный, но незаконный массив длины.
  • Исторически С# наследует большая часть его синтаксиса и соглашения с C и С++. В этих массивах просто указательная арифметика, поэтому возможно отрицательное индексирование массива (хотя обычно незаконно и опасно). Поскольку существующий код предполагает, что индекс массива отрицательный, это было бы фактором
  • В соответствующей заметке использование знаковых целых чисел для индексов массивов в C/С++ означает, что взаимодействие с этими языками и неуправляемыми функциями в любом случае потребует использования ints в этих обстоятельствах, что может путают из-за несогласованности.
  • Реализация BinarySearch (очень полезный компонент многих алгоритмов) полагается на возможность используйте отрицательный диапазон int, чтобы указать, что значение не было найдено и местоположение, в которое такое значение должно быть вставлено в поддерживать сортировку.
  • При работе с массивом, вероятно, вы хотел бы принять отрицательное смещение существующего индекса. Если вы использовали смещение, которое приведет вас к началу массива с использованием единицы то обход вокруг поведения сделает ваш индекс, возможно, законным (в том смысле, что он положительный). С результатом int результат был бы незаконным (но безопасно, поскольку среда выполнения защитит от чтения недопустимой памяти).