+= for delegates calls Delegate.Combine. thermostat.OnTemperatureChange += cooler.OnTemperatureChanged; calls this twice: Once in Main and once in set_OnTemperatureChange. So it's a banal bug that causes the side effect two times.

thermostat.OnTemperatureChange += heater.OnTemperatureChanged takes Cooler, converts it into Cooler, Heater, then calls set which combines it with the old value causing this to become Cooler, Cooler, Heater.