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

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

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

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

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

9 ответов

Решение

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

using System.Diagnostics;
...
Debug.Assert (i > 0);

я думаю, вы должны использовать его, только если вам не нужно приводить от uint к int или наоборот туда и обратно.

это нормально, но если целое число, которое вы приводите к uint, является отрицательным значением, то приведение его к uint установит для uint максимально возможное значение ( 2^32), что может привести к некоторым ошибкам.

Другие вопросы по тегам