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

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


person Leonardo    schedule 01.06.2015    source источник


Ответы (3)


Типы без знака несовместимы с CLS, поэтому Stream.Write не использует uint для смещения и счета.

См .: uint (справочник по C #)

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

Есть старая статья: Почему у нас нет неподписанных типов в CLS по Брэд Абрамс (2 сентября 2003 г.), объясняющий причину:

Однако возникает одна проблема: почему мы не разрешили беззнаковые типы (UInt32 и т.п.) в CLS?

Что ж, на этот вопрос действительно есть два ответа. На первом уровне некоторые языки (например, VB.NET) не предлагают полной поддержки беззнаковых типов. Например, у вас не может быть беззнаковых литералов в VB.NET…. Но, честно говоря, это не полностью удовлетворительный ответ, потому что, когда мы запускали CLS, вы также не могли создавать подклассы в VB.NET, но мы расширили этот язык для поддержки того, что, как мы знали, люди захотят. Мы могли бы сделать то же самое с беззнаковыми типами. Но мы этого не сделали. Почему нет? Что ж, у этого есть более глубокая причина. Фактически по той же причине, по которой ранние бета-версии языка C # не поддерживали беззнаковые типы (без ushort, uint и т.п.).

Многие из нас считают, что подавляющее большинство программирования выполняется со знаковыми типами. Всякий раз, когда вы переключаетесь на беззнаковые типы, вы вызываете переключение ментальной модели (и уродливое приведение). В худшем случае вы создаете целый параллельный мир API-интерфейсов, которые принимают беззнаковые типы. Чтобы избежать проверки «‹ 0 », не стоит включать универсальные шаблоны в CLS.

(Обратите внимание, что более новая версия VB.Net (начиная с VB 8) поддерживает беззнаковые типы).

Еще одна вещь, (возможно, не связанная с этим), которую следует добавить: 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"));
person Habib    schedule 01.06.2015

Только из uint MSDN

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

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

причины, указанные ShuggyCoUk, делают его более чистый:

  • uint не совместим с CLS, поэтому создание встроенного типа (массива), зависящего от него, было бы проблематичным.
  • The runtime as originally designed prohibits any object on the heap occupying more than 2GB of memory. Since the maximum sized array that would less than or equal to this limit would be new byte[int.MaxValue] it would be puzzling to people to be able to generate positive but illegal array lengths.
  • Исторически C # унаследовал большую часть своего синтаксиса и соглашений от C и C ++. В этих массивах используется простая арифметика с указателями, поэтому отрицательная индексация массива была возможна (хотя обычно незаконна и опасна). Поскольку большая часть существующего кода предполагает, что индекс массива отрицательный, это могло быть фактором
  • В связи с этим использование целых чисел со знаком для индексов массивов в C / C ++ означает, что взаимодействие с этими языками и неуправляемыми функциями в любом случае потребует использования целых чисел в этих обстоятельствах, что может сбить с толку из-за несогласованности.
  • Реализация BinarySearch (очень полезный компонент многих алгоритмов) полагается на возможность использовать отрицательный диапазон int, чтобы указать, что значение не было найдено и место, в которое такое значение должно быть вставлено. для поддержания сортировки.
  • При работе с массивом вполне вероятно, что вы захотите взять отрицательное смещение существующего индекса. Если вы использовали смещение, которое перенесет вас за пределы начала массива, использующего unit, то поведение обтекания сделает ваш индекс, возможно, законным (в том смысле, что он положительный). С int результат будет недопустимым (но безопасным, поскольку среда выполнения защитит от чтения недействительной памяти)
person Rahul Tripathi    schedule 01.06.2015

Вы не поверите, но целые числа без знака не часть Спецификации общего языка (CLS).

Запись MSDN для uint:

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

Таким образом, Microsoft использовала здесь int вместо uint в интересах совместимости с CLS.

person Stephen Kennedy    schedule 01.06.2015