مثال ساده زیر راه استاندارد اعلان رویدادها در یک کلاس پایه ای را نشان می دهد، در نتیجه آنها می توانند از طریق کلاس های مشتق شده هم برپا شوند. این الگو بطور گسترده ای در کلاس های Windows Form در کتابخانه کلاس دات نت فریم وورک استفاده شده اند.
وقتی که شما یک کلاس می سازید که توانایی استفاده به عنوان کلاس پایه برای دیگر کلاس ها را دارد، می بایست به این حقیقت توجه داشته باشید که رویدادها نوعی خاص از وکیل ها هستند که فقط می توانند از داخل کلاسی که آنها را اعلان کرده فراخوانی شوند. کلاس های مشتق شده نمی توانند مستقیما" رویداد هایی که در داخل کلاس پایه تعریف شده است را فراخوانی کنند. هرچند در بعضی مواقع شما ممکن است رویدادی را بخواهید که فقط توانایی فراخوانی توسط کلاس پایه را داشته باشد، در اکثر مواقع، شما می بایست کلاس مشتق شده را قادر سازید که رویدادهای کلاس پایه را فراخوانی کند. برای انجام این کار، شما می توانید یک متد فراخواننده محافظت شده (protected) در کلاس پایه بسازید، بگونه ای که رویداد را دربر بگیرد.کلاس های مشتق شده می توانند با صدا زدن یا بازنویسی (override) کردن این متد فراخواننده، رویداد را بصورت غیر مستقیم فراخوانی نمایند.
نکته
اعلان رویدادهای مجازی در کلاس پایه و بازنویسی آنها در کلاس مشتق شده را انجام ندهید. در مایکروسافت ویژوال استودیو 2010، کامپایلر #C این روش (اعلان مجازی و بازنویسی) را بدرستی مدیریت نمی کند و این کار در مواقعی که یک متعهد به رویداد مشتق شده بخواهد در واقع به رویداد کلاس پایه متعهد شود، دارای پیامدهای غیرقابل پیش بینی است.
مثال
namespace BaseClassEvents { using System; using System.Collections.Generic; // Special EventArgs class to hold info about Shapes. public class ShapeEventArgs : EventArgs { private double newArea; public ShapeEventArgs(double d) { newArea = d; } public double NewArea { get { return newArea; } } } // Base class event publisher public abstract class Shape { protected double area; public double Area { get { return area; } set { area = value; } } // The event. Note that by using the generic EventHandler<T> event type // we do not need to declare a separate delegate type. public event EventHandler<ShapeEventArgs> ShapeChanged; public abstract void Draw(); //The event-invoking method that derived classes can override. protected virtual void OnShapeChanged(ShapeEventArgs e) { // Make a temporary copy of the event to avoid possibility of // a race condition if the last subscriber unsubscribes // immediately after the null check and before the event is raised. EventHandler<ShapeEventArgs> handler = ShapeChanged; if (handler != null) { handler(this, e); } } } public class Circle : Shape { private double radius; public Circle(double d) { radius = d; area = 3.14 * radius * radius; } public void Update(double d) { radius = d; area = 3.14 * radius * radius; OnShapeChanged(new ShapeEventArgs(area)); } protected override void OnShapeChanged(ShapeEventArgs e) { // Do any circle-specific processing here. // Call the base class event invocation method. base.OnShapeChanged(e); } public override void Draw() { Console.WriteLine("Drawing a circle"); } } public class Rectangle : Shape { private double length; private double width; public Rectangle(double length, double width) { this.length = length; this.width = width; area = length * width; } public void Update(double length, double width) { this.length = length; this.width = width; area = length * width; OnShapeChanged(new ShapeEventArgs(area)); } protected override void OnShapeChanged(ShapeEventArgs e) { // Do any rectangle-specific processing here. // Call the base class event invocation method. base.OnShapeChanged(e); } public override void Draw() { Console.WriteLine("Drawing a rectangle"); } } // Represents the surface on which the shapes are drawn // Subscribes to shape events so that it knows // when to redraw a shape. public class ShapeContainer { List<Shape> _list; public ShapeContainer() { _list = new List<Shape>(); } public void AddShape(Shape s) { _list.Add(s); // Subscribe to the base class event. s.ShapeChanged += HandleShapeChanged; } // ...Other methods to draw, resize, etc. private void HandleShapeChanged(object sender, ShapeEventArgs e) { Shape s = (Shape)sender; // Diagnostic message for demonstration purposes. Console.WriteLine("Received event. Shape area is now {0}", e.NewArea); // Redraw the shape here. s.Draw(); } } class Test { static void Main(string[] args) { //Create the event publishers and subscriber Circle c1 = new Circle(54); Rectangle r1 = new Rectangle(12, 9); ShapeContainer sc = new ShapeContainer(); // Add the shapes to the container. sc.AddShape(c1); sc.AddShape(r1); // Cause some events to be raised. c1.Update(57); r1.Update(7, 7); // Keep the console window open in debug mode. System.Console.WriteLine("Press any key to exit."); System.Console.ReadKey(); } } } /* Output: Received event. Shape area is now 10201.86 Drawing a circle Received event. Shape area is now 49 Drawing a rectangle */