Я только что попытался реализовать класс, где многочисленные свойства длины/количества, и т.д. uint
вместо int
. Однако при выполнении, таким образом, я заметил, что это на самом деле болезненно, чтобы сделать так, как то, как будто никто на самом деле не хочет сделать это.
Почти все, что раздает целочисленный тип возвраты int
, поэтому требуя бросков в нескольких точках. Я хотел создать a StringBuffer
с его длиной буфера принял значение по умолчанию к одному из полей в том классе. Требует броска также.
Таким образом, я задался вопросом, должен ли я просто вернуться к int
здесь. Я, конечно, не использую весь диапазон так или иначе. Я просто думал начиная с того, с чем я имею дело там, просто не может быть отрицательным (если бы это было, то это была бы ошибка), это была бы хорошая идея на самом деле использовать uint
.
P.S.: Я видел этот вопрос, и это, по крайней мере, объясняет, почему сама платформа всегда использует int
но даже в собственном коде это является на самом деле громоздким для придерживаний uint
который заставляет меня думать, что это, по-видимому, действительно не требуется.
Хотя строго следует использовать uint
для переменных, содержащих неотрицательное целое число, Вы натолкнулись на одну из причин, почему это не всегда возможно.
В данном случае я не думаю, что уменьшение читабельности, которое сопровождается необходимостью делать касты, стоит того.
Мое личное ощущение в том, что тебе, наверное, стоит просто держаться за int. Не стоит добавлять слепок практически к каждому доступу к свойствам только для того, чтобы восстановить числовой диапазон, который .NET вряд ли позволит вам использовать в любом случае.
Отрицательное значение часто используется для сигнализации состояния ошибки, а размер операции часто возвращается вызовом функции; поэтому отрицательное значение может сигнализировать об ошибке, не прибегая к механизму исключений.
Также обратите внимание, что .NET часто строится на прямых библиотеках Си, поэтому целесообразно продолжить эту конвенцию. Если вам требуется большее индексное пространство, вы можете нарушить это соглашение для различных механизмов сигнализации ошибок.
Если вы хотите проверить, что значение положительное, то лучший способ, вероятно, просто использовать assert (обратите внимание, что это всего лишь техника отладки - вы должны убедиться, что это никогда не произойдет в финальном коде).
using System.Diagnostics;
...
Debug.Assert (i > 0);
Использование int также полезно для обнаружения целочисленного переполнения в операциях.
К другим ответам я также добавлю, что использование uint в качестве типа общедоступного поля, свойства, метода, параметра и т. Д. Является нарушением правил спецификации общего языка и его следует избегать, когда это возможно.
Не плывите вверх по течению, если вам это не нужно. Если не загромождать код приведениями, он становится более читабельным. Кроме того, если ваши возможные значения соответствуют int, то использование int не является проблемой.
Если вы боитесь переполнить int, то во что бы то ни стало ... но не оптимизируйте преждевременно.
Я бы сказал, что улучшенная читаемость минимизации приведений перевешивает немного повышенный риск ошибки при использовании int.
IMO, недостатком использования uint
является то, что оно скрывает условия ошибок. Эквиваленты следующего кода не так хороши:
if (len < 0)
terminate_program("length attained impossible value.");
Конечно, ваши программы изначально не должны ничего просчитывать, но я считаю, что они также должны быть написаны для быстрого обнаружения числовых ошибок без распространения. В случае, когда достаточно MaxValue 2^31, я предлагаю использовать int
вместе с правильным использованием System.Diagnostics.Debug.Assert()
и соответствующих проверок на ошибки, как показано выше.
Если вы используете uint
, используйте его вместе с checked
для предотвращения переполнения и получите те же результаты. Однако я обнаружил, что check немного сложно применить к существующему коду, который использует касты для каких-то целей.