Encapsulating the Subscription

// When code assigns OnHeaterTemperatureChanged to OnCoolerTemperatureChanged, 
// OnHeaterTemperatureChanged is cleared out because an entirely new chain is assigned to replace the previous one.
var thermostat = new Thermostat();
thermostat.OnTemperatureChange = OnHeaterTemperatureChanged;
// Bug: assignment operator overrides previous assignment.
thermostat.OnTemperatureChange = OnCoolerTemperatureChanged;

Encapsulating the Publication

var thermostat = new Thermostat();
var heater = new Heater(60);
var cooler = new Cooler(80);
thermostat.OnTemperatureChange += heater.OnTemperatureChanged;
thermostat.OnTemperatureChange += cooler.OnTemperatureChanged;
thermostat.OnTemperatureChange(42); // You can invoke it wherever you want.

Declaring an Event

public class Thermostat
{
    public delegate void TemperatureChangeHandler(object sender, TemperatureArgs newTemperature);
    public event TemperatureChangeHandler OnTemperatureChange = delegate { };

    public class TemperatureArgs : EventArgs
    {
        public float NewTemperature { get; set; }
        public TemperatureArgs(float newTemperature)
        {
            NewTemperature = newTemperature;
        }
    }        
}

EventHandler Delegate