Ответ 1
a=b+(b=a)*0;
То, что (b=a)
в середине является установкой оператора присваивания b
текущему значению a
с побочным эффектом, что его результат (окончательное значение) b
. Когда это умножается на 0, вы получаете 0, но назначение все равно произошло.
Внешний бит устанавливает a
в b
плюс результат (b=a)*0
(который равен нулю). Поскольку исходный b
уже использовался для начала установки a
до назначения в бит (b=a)
, назначение не влияет на a
. Другими словами, это атомный a = b; b = a;
, заменяющий два значения.
С# оценивает вещи в строгом порядке слева направо (в отличие от C и С++), чтобы избежать большого класса тонких ошибок. Обратите внимание, что компилятор может оценивать их в другом порядке, но только если он может определить, что он не будет иметь эффекта (это не так).
Отсканированный вами фрагмент работает, но также является отвратительным и не очень хорошая идея, особенно если вы можете использовать гораздо более читаемые:
int t = a; a = b; b = t;
Трюки, как то, что вы видите здесь, и трюк с заменой XOR, и устройство Duff не имеют места в достойном, поддерживаемом коде. Обычно это способ, чтобы кодеры показывали, насколько они умны, но обычно показывают, насколько они плохи.
Если вы когда-нибудь увидите что-то подобное в производственном кодексе, я не думаю, что какое-либо жюри в мире обвинило бы вас в том, что вы охотитесь за преступником и избиваете их до смерти с помощью списка свернутых программ.
Вы должны написать свой код, как будто следующий человек, который должен его поддерживать, - это психопат, который знает, где вы живете, - в моем случае вы были бы наполовину правы - я понятия не имею, где вы живете: -)