Я должен использовать uint в C# для величин, которые не могут быть отрицательными?

Я только что попытался реализовать класс, где многочисленные свойства длины/количества, и т.д. uint вместо int. Однако при выполнении, таким образом, я заметил, что это на самом деле болезненно, чтобы сделать так, как то, как будто никто на самом деле не хочет сделать это.

Почти все, что раздает целочисленный тип возвраты int, поэтому требуя бросков в нескольких точках. Я хотел создать a StringBuffer с его длиной буфера принял значение по умолчанию к одному из полей в том классе. Требует броска также.

Таким образом, я задался вопросом, должен ли я просто вернуться к int здесь. Я, конечно, не использую весь диапазон так или иначе. Я просто думал начиная с того, с чем я имею дело там, просто не может быть отрицательным (если бы это было, то это была бы ошибка), это была бы хорошая идея на самом деле использовать uint.

P.S.: Я видел этот вопрос, и это, по крайней мере, объясняет, почему сама платформа всегда использует int но даже в собственном коде это является на самом деле громоздким для придерживаний uint который заставляет меня думать, что это, по-видимому, действительно не требуется.

75
задан Community 23 May 2017 в 12:18
поделиться

8 ответов

Хотя строго следует использовать uint для переменных, содержащих неотрицательное целое число, Вы натолкнулись на одну из причин, почему это не всегда возможно.

В данном случае я не думаю, что уменьшение читабельности, которое сопровождается необходимостью делать касты, стоит того.

41
ответ дан 24 November 2019 в 11:40
поделиться

Мое личное ощущение в том, что тебе, наверное, стоит просто держаться за int. Не стоит добавлять слепок практически к каждому доступу к свойствам только для того, чтобы восстановить числовой диапазон, который .NET вряд ли позволит вам использовать в любом случае.

3
ответ дан 24 November 2019 в 11:40
поделиться

Отрицательное значение часто используется для сигнализации состояния ошибки, а размер операции часто возвращается вызовом функции; поэтому отрицательное значение может сигнализировать об ошибке, не прибегая к механизму исключений.

Также обратите внимание, что .NET часто строится на прямых библиотеках Си, поэтому целесообразно продолжить эту конвенцию. Если вам требуется большее индексное пространство, вы можете нарушить это соглашение для различных механизмов сигнализации ошибок.

4
ответ дан 24 November 2019 в 11:40
поделиться

Если вы хотите проверить, что значение положительное, то лучший способ, вероятно, просто использовать assert (обратите внимание, что это всего лишь техника отладки - вы должны убедиться, что это никогда не произойдет в финальном коде).

using System.Diagnostics;
...
Debug.Assert (i > 0);
2
ответ дан 24 November 2019 в 11:40
поделиться

Использование int также полезно для обнаружения целочисленного переполнения в операциях.

3
ответ дан 24 November 2019 в 11:40
поделиться

К другим ответам я также добавлю, что использование uint в качестве типа общедоступного поля, свойства, метода, параметра и т. Д. Является нарушением правил спецификации общего языка и его следует избегать, когда это возможно.

58
ответ дан 24 November 2019 в 11:40
поделиться

Не плывите вверх по течению, если вам это не нужно. Если не загромождать код приведениями, он становится более читабельным. Кроме того, если ваши возможные значения соответствуют int, то использование int не является проблемой.

Если вы боитесь переполнить int, то во что бы то ни стало ... но не оптимизируйте преждевременно.

Я бы сказал, что улучшенная читаемость минимизации приведений перевешивает немного повышенный риск ошибки при использовании int.

2
ответ дан 24 November 2019 в 11:40
поделиться

IMO, недостатком использования uint является то, что оно скрывает условия ошибок. Эквиваленты следующего кода не так хороши:

if (len < 0)
    terminate_program("length attained impossible value.");

Конечно, ваши программы изначально не должны ничего просчитывать, но я считаю, что они также должны быть написаны для быстрого обнаружения числовых ошибок без распространения. В случае, когда достаточно MaxValue 2^31, я предлагаю использовать int вместе с правильным использованием System.Diagnostics.Debug.Assert() и соответствующих проверок на ошибки, как показано выше.

Если вы используете uint, используйте его вместе с checked для предотвращения переполнения и получите те же результаты. Однако я обнаружил, что check немного сложно применить к существующему коду, который использует касты для каких-то целей.

3
ответ дан 24 November 2019 в 11:40
поделиться
Другие вопросы по тегам:

Похожие вопросы: