См. Раздел 4.1.5 спецификации языка C # 4.0 .В частности, представляет интерес:
C # поддерживает девять целочисленных типов: sbyte, byte, short , ushort, int, uint, long, ulong и char.[пропущенный текст]
Унарные и двоичные операторы целочисленного типа всегда работают с 32-разрядной точностью со знаком, 32-разрядной точностью без знака, 64-разрядной точностью со знаком или 64-разрядной точностью без знака:
[пропущенные пункты]
Для двоичного файла +, -, *, /,%, &, ^, |, == ,! =,>, <,> = И <=, операнды преобразуются в тип T, где T - это первое из int, uint, long и ulong, которое может полностью представлять все возможные значения обоих операндов,Затем операция выполняется с использованием точности типа T, а тип результата - T (или bool для реляционных операторов).Не допускается, чтобы один операнд был типа long, а другой - типа ulong с бинарными операторами. </p>
Операции, использующие short, переводятся в int, и те,операции отменены для их равноправных аналогов.(Это приводит к разделам 7.3.6.2 и 7.3.7)
Хорошо, это по замыслу, но все еще не понимаю, почему они это делают, они оптимизируют добавление строкслишком много, поэтому оставьте числа в покое и добавьте больше кода для этого простого сравнения
Это просто способ, которым разработан язык, с учетом оптимизации в современной архитектуре.Не конкретно в этом контексте, но рассмотрим слова Эрика Липперта, как указано здесь
Арифметика никогда не выполняется в шортах в C #.Арифметика может быть выполнена в типах ints, uints, long и ulongs, но арифметика никогда не выполняется в шортах.Шорты повышаются до int, а арифметика выполняется в целых числах, потому что, как я уже говорил, подавляющее большинство арифметических вычислений укладывается в int.Подавляющее большинство не вписывается в короткие.Короткая арифметика, возможно, медленнее на современном оборудовании, которое оптимизировано для целых чисел, а короткая арифметика не занимает меньше места;это будет сделано в микросхемах или длиннах на чипе.
Ваше последнее обновление:
Я ожидаю, что компилятор сделает простую проверку с помощью .HasValue if (cTestA.HasValue) {} впо крайней мере, это то, что я делаю в своем коде после обнаружения этого преобразования.Так что это то, чего я действительно не понимаю, почему бы не подумать так просто, а добавить весь этот дополнительный код.Компилятор всегда пытается оптимизировать код - почему бы избежать этой простой проверки .HasValue.Я что-то здесь упускаю наверняка ...
Мне придется обратиться к специалисту по компилятору, чтобы сказать, почему он выбрал преобразование вместо немедленной проверки HasValue, за исключением того, что могпросто будьте порядком операций.В спецификации языка говорится, что бинарные операнды операторов повышаются, и это то, что они сделали в предоставленном фрагменте.Далее в спецификации языка говорится, что проверки с помощью x == null
, где x - это тип значения NULL, могут быть преобразованы в !x.HasValue
, и это также то, что они сделали.В представленном вами скомпилированном коде числовое продвижение просто имеет прецедент над обнуляемым поведением.
Что касается компилятора всегда , пытающегося оптимизировать код, опять же, эксперт может уточнить, но это не так.Есть оптимизации, которые он может сделать, и другие, которые он может отнести к джиттеру.Существуют оптимизации, которые компилятор или джиттер могут выполнять, а могут и не делать, в зависимости от того, является ли это отладкой по сравнению с версией выпуска, с присоединенным отладчиком или без него.И, несомненно, есть оптимизация, которую они могли бы сделать, которую они просто решили не делать, потому что затраты по сравнению с выгодами не заканчиваются.