Почему отладочная сборка приводит к еще одной переменной? - PullRequest
0 голосов
/ 03 февраля 2019

Это код:

Employee e = new Employee() { Name = "Jeff", Age = 45 };

А вот как он компилируется при сборке отладочной сборки:

Employee employee = new Employee();
employee.Name = "Jeff";
employee.Age = 45;
Employee employee2 = employee;

И вот как он компилируется при сборке релиза:

Employee employee = new Employee();
employee.Name = "Jeff";
employee.Age = 45;

Вопрос: почему отладочная сборка приводит к еще одной переменной, которая ссылается на тот же объект?

Ответы [ 2 ]

0 голосов
/ 03 февраля 2019

SharpLab берет скомпилированный IL и пытается преобразовать его обратно в читаемый C #, результирующий C # не всегда точно совпадает с исходным скомпилированным кодом.

Если вместо этого мы смотрим на IL, который былсгенерированный, в режиме отладки мы получаем следующее (я удалил некоторые инструкции nop (no-op), чтобы сохранить порядок:

.locals init (
    [0] class Employee
)

IL_0001: newobj instance void Employee::.ctor()
IL_0006: dup
IL_0007: ldstr "Jeff"
IL_000c: callvirt instance void Employee::set_Name(string)
IL_0012: dup
IL_0013: ldc.i4.s 45
IL_0015: callvirt instance void Employee::set_Age(int32)
IL_001b: stloc.0
IL_001c: ret

В релизе это почти идентично:

IL_0000: newobj instance void Employee::.ctor()
IL_0005: dup
IL_0006: ldstr "Jeff"
IL_000b: callvirt instance void Employee::set_Name(string)
IL_0010: dup
IL_0011: ldc.i4.s 45
IL_0013: callvirt instance void Employee::set_Age(int32)
IL_0018: pop
IL_0019: ret

Единственное реальное отличие состоит в том, что когда версия Debug выделяет локальную переменную для employee, версия Release не делает этого, поскольку она никогда не используется, и поэтому не требуется.

Как мы видим, "Дополнительная «переменная, которую вы видите в версии Debug, на самом деле не существует, это всего лишь артефакт попытки SharpLab преобразовать скомпилированный IL обратно в читаемый C #, и на самом деле версия Release« потеряла »локальную переменную, потому что она не былатребуется.

0 голосов
/ 03 февраля 2019

Полагаю, вам следует создать второй объект, подобный этому.

Employee employee2 = new Employee();

затем

employee2= employee;
...