Строки конкатенации С# при компиляции
Пожалуйста, помогите понять это поведение. Когда я использую это:
bool a1 = (object)("string" + 1) == ("string" + 1);
Результат false
Но когда я использую этот
bool a2 = (object)("string" + "1") == ("string" + "1");
Результат true
Итак, почему a1 != a2
?
Ответы
Ответ 1
Отбрасывание до object
приводит к сравнительному сравнению.
В первом случае во время выполнения генерируются два разных объекта string
. Поскольку они являются разными экземплярами, результат является ложным.
Во втором случае компилятор замечает, что "string" + "1"
всегда будет "string1"
и ставит строку и использует одну и ту же ссылку в обоих местах. Поскольку это одна и та же строковая ссылка, результат верен.
Ответ 2
Здесь происходит две важные вещи:
Во-первых, выражение "string" + 1
оценивается во время выполнения, а "string" + "1"
- во время компиляции.
Во-вторых, вы используете сравнение ссылок. Строки, созданные во время выполнения, фактически ссылаются на другой объект, в то время как строки, сгенерированные во время компиляции, ссылаются на один и тот же объект, поэтому первое выражение false
, а второе выражение true
.
Если вам интересно, сгенерированный IL:
// bool a1 = (object)("string" + 1) == ("string" + 1);
// bool a2 = (object)("string" + "1") == ("string" + "1");
IL_0000: ldstr "string"
IL_0005: ldc.i4.1
IL_0006: box System.Int32
IL_000B: call System.String.Concat
IL_0010: ldstr "string"
IL_0015: ldc.i4.1
IL_0016: box System.Int32
IL_001B: call System.String.Concat
IL_0020: ceq
IL_0022: stloc.0 // a1
IL_0023: ldstr "string1"
IL_0028: ldstr "string1"
IL_002D: ceq
IL_002F: stloc.1 // a2