Зачем это компилировать?
Я создал "const" для значения, ранее явно указанного несколько раз в моем коде:
private static readonly int QUARTER_HOUR_COUNT = 96;
Когда я выполнил поиск и замену 96 для QUARTER_HOUR_COUNT, я также случайно заменил объявление, поэтому он стал следующим:
private static readonly int QUARTER_HOUR_COUNT = QUARTER_HOUR_COUNT;
... но он скомпилирован. Я бы подумал, что это будет запрещено. Почему это было принято компилятором как действительное объявление?
Ответы
Ответ 1
Я бы подумал, что это будет запрещено. Почему это было принято компилятором как действительное объявление?
Предположительно, потому что это позволяет использовать спецификацию языка. У вас есть определенное правило в спецификации языка, которое, по вашему мнению, запрещает?
Если ваш вопрос действительно "почему спецификация языка не запрещает это", я подозреваю это, потому что, вероятно, довольно сложно убедиться, что вы только запрещаете то, что вы действительно хотите запретить, и фактически запрещаете все такие вещи.
Можно утверждать, что для простых случаев присваивания непосредственно назад к себе было бы полезно иметь специальный случай в спецификации языка, но это создало бы сложность в языке для относительно небольшой пользы.
Обратите внимание, что даже если вы не получили сообщение об ошибке, я ожидаю, что вы получите предупреждение - что-то вроде этого:
Test.cs(3,33): предупреждение CS1717: присвоение одной переменной; вы имели в виду присвоить что-то еще?
Также обратите внимание, что если вы сделаете это const
вместо просто статической переменной readonly, вы получите ошибку времени компиляции:
Test.cs(3,23): ошибка CS0110: оценка постоянного значения для "Program.QUARTER_HOUR_COUNT" включает круговое определение
Также обратите внимание, что в соглашениях об именах .NET это следует называть QuarterHourCount
, а не иметь SHOUTY_NAME.
Ответ 2
Код IL, сгенерированный кодом, таков:
IL_0007: ldsfld int32 Example.Quat::QUARTER_HOUR_COUNT//Load the value of a static field on the stack
IL_000c: stsfld int32 Example.Quat::QUARTER_HOUR_COUNT// Store the value from the stack in the static field
Так как значение по умолчанию QUARTER_HOUR_COUNT равно 0, то 0 присваивается QUARTER_HOUR_COUNT
Ответ 3
Поскольку переменная была инициализирована как 0, а затем установлена на себя.
Мое предположение было бы в том, что он будет делать новый Int() до установки для себя, который инициализирует его до нуля.
Ответ 4
Потому что компилятор сломает эту строку:
private static readonly int QUARTER_HOUR_COUNT = QUARTER_HOUR_COUNT;
В основном в эквивалент IL:
private static readonly int QUARTER_HOUR_COUNT;
QUARTER_HOUR_COUNT = QUARTER_HOUR_COUNT;
И тогда, очевидно, это тоже будет разбито, но приведенного выше достаточно, чтобы проиллюстрировать мою точку.
Таким образом, технически он будет существовать со значением по умолчанию, равным нулю в момент его использования.
Ответ 5
Поскольку другие типы значений, такие как int
, имеют значение по умолчанию, поэтому объявление переменной без явной инициализации означает, что она все еще имеет значение.
Вы можете узнать значение по умолчанию для любого типа:
int i = default(int);
Или в более общем плане:
T t = default(T);
Обратите внимание, что для ссылочных типов по умолчанию будет null
, только значения будут иметь значения по умолчанию.