0Pricing
C# Academy · Lesson

Events: publish/subscribe, event keyword

Publish/subscribe with events: declare event, add/remove handlers, pass data via EventArgs, and raise with the OnX pattern.

Events: publish/subscribe, event keyword is a free C# Academy lesson on CoddyKit — lesson 2 of 3. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the C# Academy learning path, one of 3 lessons in the course, and your progress syncs across the web and the CoddyKit app.

Events overview

Goal: Publish/subscribe with events.

  • Declare an event on the publisher
  • Subscribe with +=, unsubscribe with -=
  • Raise safely in the publisher
  • Pass data using EventArgs

Basic event usage

Expose an event and let listeners attach/detach. Only the publisher invokes it.

using System;

public class Button
{
  public event EventHandler Click;

  public void SimulateClick()
  {
    // Safe raise: copy then invoke if not null (C# 6-safe)
    EventHandler h = Click;
    if (h != null) h(this, EventArgs.Empty);
  }
}

public class Program
{
  static void OnClick(object sender, EventArgs e)
  {
    Console.WriteLine("Clicked!");
  }

  public static void Main(string[] args)
  {
    Button b = new Button();
    b.Click += OnClick;    // subscribe
    b.SimulateClick();     // prints "Clicked!"

    b.Click -= OnClick;    // unsubscribe
    b.SimulateClick();     // no output
  }
}

Event with data

Use EventArgs (or EventHandler<TEventArgs>) to pass useful data to subscribers.

using System;

// Data for the event
public sealed class PriceChangedEventArgs : EventArgs
{
  public decimal OldPrice { get; private set; }
  public decimal NewPrice { get; private set; }
  public PriceChangedEventArgs(decimal oldP, decimal newP)
  {
    OldPrice = oldP; NewPrice = newP;
  }
}

public sealed class Product
{
  private decimal _price;
  public event EventHandler<PriceChangedEventArgs> PriceChanged;

  public decimal Price
  {
    get { return _price; }
    set
    {
      if (value != _price)
      {
        decimal old = _price;
        _price = value;
        EventHandler<PriceChangedEventArgs> h = PriceChanged;
        if (h != null) h(this, new PriceChangedEventArgs(old, _price));
      }
    }
  }
}

public class Program
{
  public static void Main(string[] args)
  {
    Product p = new Product();
    p.PriceChanged += delegate(object s, PriceChangedEventArgs e)
    {
      Console.WriteLine("Price: " + e.OldPrice + " -> " + e.NewPrice);
    };
    p.Price = 10m;
    p.Price = 12m;
  }
}

Multicast & lambdas

Events are multicast: multiple handlers run in subscription order. Use named or anonymous handlers.

using System;

public class Alarm
{
  public event EventHandler Ring;

  public void Trigger()
  {
    EventHandler h = Ring;
    if (h != null) h(this, EventArgs.Empty);
  }
}

public class Program
{
  static void HandlerA(object s, EventArgs e) { Console.WriteLine("A"); }
  static void HandlerB(object s, EventArgs e) { Console.WriteLine("B"); }

  public static void Main(string[] args)
  {
    Alarm a = new Alarm();
    a.Ring += HandlerA;                           // named
    a.Ring += delegate(object s, EventArgs e) { Console.WriteLine("lambda"); }; // anon
    a.Ring += HandlerB;

    a.Trigger(); // prints A, lambda, B (multicast order)
  }
}

OnX raise pattern

Use a protected OnX method to raise events. Copy the delegate to a local and check for null before invoking.

using System;

public class Ticker
{
  public event EventHandler Tick;

  protected virtual void OnTick()
  {
    EventHandler h = Tick;          // copy to local
    if (h != null) h(this, EventArgs.Empty);
  }

  public void RunOnce()
  {
    // do work...
    OnTick(); // raise via protected method
  }
}

public class Program
{
  static void Show(object s, EventArgs e) { Console.WriteLine("Tick!"); }

  public static void Main(string[] args)
  {
    Ticker t = new Ticker();
    t.Tick += Show;
    t.RunOnce();
  }
}

Event tips & pitfalls

Tips:

  • Always unsubscribe ( -= ) when a subscriber is no longer needed.
  • Keep handlers short; long work should be queued.
  • Use EventArgs (or a subclass) to pass data.
  • Only the publisher should raise the event.

event keyword role

Quick check: Which C# keyword exposes a delegate for subscribe/unsubscribe while preventing outside code from invoking it directly?

Recap

Recap: Declare an event, let listeners attach/detach, pass data with EventArgs, and raise via a protected OnX method.

Frequently asked questions

Is the “Events: publish/subscribe, event keyword” lesson free?

Yes — the full text of “Events: publish/subscribe, event keyword” is free to read here on the web, and the C# Academy course includes 3 lessons in total. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the C# Academy course, upgrade to CoddyKit PRO.

What will I learn in “Events: publish/subscribe, event keyword”?

Publish/subscribe with events: declare event, add/remove handlers, pass data via EventArgs, and raise with the OnX pattern. You practise C# Academy with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.

Do I need any experience to start C# Academy?

No prior experience is required. C# Academy on CoddyKit is structured for beginners through advanced learners; this is — lesson 2 of 3, so you can start here or from the beginning and move at your own pace.

How long does the “Events: publish/subscribe, event keyword” lesson take?

Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.

Can I write and run code in this C# Academy lesson?

Yes. Every C# Academy lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.

All lessons in this course

  1. delegate, Action/Func, closures
  2. Events: publish/subscribe, event keyword
  3. Event patterns, pitfalls (memory leaks)
← Back to C# Academy