Должен ли я использовать Uint в C # для значений, которые не могут быть отрицательными? - PullRequest
73 голосов
/ 06 января 2010

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

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

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

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

Ответы [ 8 ]

57 голосов
/ 06 января 2010

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

40 голосов
/ 06 января 2010

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

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

4 голосов
/ 06 января 2010

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

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

3 голосов
/ 03 июня 2010

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

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

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

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

3 голосов
/ 06 января 2010

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

3 голосов
/ 06 января 2010

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

2 голосов
/ 03 июня 2010

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

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

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

2 голосов
/ 06 января 2010

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

using System.Diagnostics;
...
Debug.Assert (i > 0);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...