Похоже, у вас недостаточно юнит-тестов:]
К сожалению, ваше заявление
"Ничего в коде не изменилось, за исключением некоторых синтаксических ярлыков"
не так, и я думаю, вот в чем твоя проблема. (Это, безусловно, одна из ваших проблем!)
Да,
a *= b;
эквивалентно
a = a * b;
но
a *= b / c;
НЕ совпадает с
a = a * b / c;
вместо
a *= b / c; // equivalent to a = a * (b / c)
a = a * b / c; // equivalent to a = (a * b) / c
(см. c # приоритет оператора в msdn)
Я предполагаю, что вы столкнулись с проблемами, когда высота вашей цели не кратна первоначальной высоте прямоугольника (или одинаковой для ширины).
Тогда вы получите следующую ситуацию:
Предположим, что rect.Size = (8, 20), targetSize = (15, 25)
Используя исходный метод, вы получите следующий расчет:
rect.Width = rect.Width * targetSize.Height / rect.Height;
// = 8 * 25 / 20
// = 200 / 20 (multiplication happens first)
// = 10
// rect.Width = 10
Используя ваш новый код, вы получите
rect.Width *= targetSize.Height / rect.Height;
// *= 25 / 20
// *= 1 (it's integer division!)
// rect.Width = rect.Width * 1
// = 8
// rect.Width = 8
что не то же самое. (Становится хуже, если целевой размер меньше исходного размера; в этом случае целочисленное деление приведет к тому, что одно из измерений будет 0!)
Если «[ваши] модульные тесты проходят все», вам определенно потребуются некоторые дополнительные тесты, особенно те, которые работают с нецелыми кратными числами.
Также обратите внимание, что ваш расчет
else if(targetSize.Width * rect.Height >
rect.Width * targetSize.Height)
не надежно; для очень больших прямоугольников он может переполниться и дать неверные результаты. Вам было бы лучше привести к более крупному типу (то есть длинному) как часть умножения. (Опять же, для этого нужно провести несколько юнит-тестов)
Надеюсь, это поможет!