Подтвердить что ты не робот

Строки конкатенации С# при компиляции

Пожалуйста, помогите понять это поведение. Когда я использую это:

bool a1 = (object)("string" + 1) == ("string" + 1);

Результат false

Но когда я использую этот

bool a2 = (object)("string" + "1") == ("string" + "1"); 

Результат true

Итак, почему a1 != a2?

4b9b3361

Ответ 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