Есть ли разница между следующими двумя частями кода?
class Test {
public readonly double Val;
public Test(bool src) {
this.Val = src ? 1 : 0;
}
}
class Test {
public readonly double Val;
public Test(bool src) {
this.Val = src ? 1D : 0D;
}
}
Я обнаружил, что наша кодовая база использует второй способ написания.
Ответы:
Здесь есть два вопроса, и важно отметить, что у них разные ответы.
Нет. Компилятор C # распознает, когда целочисленный литерал используется в контексте, где ожидается double, и изменяет ли тип во время компиляции, поэтому эти два фрагмента будут генерировать один и тот же код.
Да. Правило, согласно которому целочисленные константы автоматически изменяются на двойные, применяется только к константам и
src ? ...
не является константой . Компилятор сгенерирует первый, как будто вы написали:А второй как
То есть, в первом мы выбираем целое число, а затем конвертируем его в двойное, а во втором мы выбираем двойное.
К вашему сведению: компилятору C # или джиттеру разрешено распознавать, что первую программу можно оптимизировать во вторую, но я не знаю, так ли это на самом деле. C # компилятор делает иногда двигаться преобразованиями для поднятого арифметики в органы условных; Я написал этот код около восьми лет назад, но я не помню все детали.
источник
Там является разница в сгенерированном коде IL.
Этот класс:
Создает этот код IL для конструктора:
И этот класс:
Создает этот код IL для конструктора:
Как видите, в первой версии он должен вызывать
conv.r8
для преобразования int в double.Однако: (1) конечный результат идентичен и (2) компилятор JIT вполне может перевести оба этих кода в один и тот же машинный код.
Так что ответ: Да, есть разница - но не один , что вам нужно беспокоиться о.
Лично я бы пошел на вторую версию, так как она лучше выражает намерение программиста и может привести к очень немного более эффективному коду (в зависимости от того, что делает JIT-компилятор).
источник
Нет никакой разницы, компилятор достаточно умен, чтобы неявно делать преобразование или нет.
Однако, если вы используете
var
, вам нужно написать,var val = 42D;
чтобы убедиться, что переменная является double, а не int.источник