Event invocation
Context: Only the class that declares the event can invoke it (raise the event). Invocation is done by calling the delegate field (with null check).
Standard invocation pattern
Section titled “Standard invocation pattern”public class Button{ public event EventHandler Clicked;
protected virtual void OnClicked() { Clicked?.Invoke(this, EventArgs.Empty); }
public void SimulateClick() { OnClicked(); }}Why protected virtual?
Section titled “Why protected virtual?”Derived classes can override the raising method to add custom behavior.
public class SpecialButton : Button{ protected override void OnClicked() { Console.WriteLine("Special logging"); base.OnClicked(); }}Thread safety
Section titled “Thread safety”Use a copy of the delegate to avoid null reference in multi‑threaded scenarios.
var handler = Clicked;if (handler != null) handler(this, EventArgs.Empty);Real-world usage example
Section titled “Real-world usage example”Custom event raising: In a Timer class, you raise the Elapsed event when time is up using OnElapsed().
Example: System.Timers.Timer raises the Elapsed event on a background thread.