Я пытаюсь понять, что делает компилятор с очень простым фрагментом кода:
if (group.ImageHeight > 1 && group.ImageWidth > 1)
{ //No code exists between the braces
}
После компиляции в Debug
конфигурации, затем декомпиляции я вижу это:
if (group.ImageHeight <= 1 || group.ImageWidth <= 1);
Декомпиляция Release
конфигурации приводит к
if (group.ImageHeight > 1)
{
int imageWidth = group.ImageWidth;
}
Более полный (оригинальный) код:
public class Group
{
public int ImageHeight { get; set; }
public int ImageWidth { get; set; }
}
//The following belongs to a different project than `Group`
static void Main(string[] args)
{
Group group = new Group();
MyMethod(group);
}
static void MyMethod(Group group)
{
if (group.ImageHeight > 1 && group.ImageWidth > 1)
{
}
}
Вот мои догадки и наблюдения:
- Когда я впервые начал это, я ожидал, что компилятор полностью отбросит весь оператор. Я думаю, что это не потому, что оценка свойств может иметь побочные эффекты.
- Я считаю, что важно, чтобы тип
group
принадлежал другому проекту в моем решении. Я говорю это потому, что компилятор, вероятно, не может «знать», какими могут быть побочные эффекты при оценке свойств в будущем. Например, я мог бы после компиляции заменить DLL, содержащую определение для group
.
- В конфигурации
Release
возможные побочные эффекты выглядят так же, как и мой код: ImageHeight
оценивается, и при выполнении условия > 1
оценивается ImageWidth
(хотя посредством назначения, а не сравнения)
Теперь, для моих конкретных вопросов:
- Почему в конфигурации
Release
используется назначение (int imageWidth = group.ImageWidth
), а не мое первоначальное сравнение? Это быстрее выполнить задание?
- Почему конфигурация
Debug
полностью меняет возможность побочных эффектов? В этой конфигурации всегда будут оцениваться значения ImageHeight
и ImageWidth
.