Introduction
Delegates and events are powerful features in C# that enable developers to write flexible and reusable code. Delegates are similar to function pointers in C++ but are type-safe. Events provide a way for a class to notify other classes or objects when something of interest occurs.
Key Concepts
Delegates
- Definition: A delegate is a type that represents references to methods with a particular parameter list and return type.
- Usage: Delegates are used to pass methods as arguments to other methods, define callback methods, and implement event handling.
Events
- Definition: An event is a message sent by an object to signal the occurrence of an action.
- Usage: Events are used to provide notifications and are typically used in conjunction with delegates.
Delegates
Declaring a Delegate
Instantiating and Using a Delegate
using System; public class Program { // Delegate declaration public delegate void MyDelegate(string message); // Method that matches the delegate signature public static void DisplayMessage(string message) { Console.WriteLine(message); } public static void Main() { // Instantiating the delegate MyDelegate del = new MyDelegate(DisplayMessage); // Using the delegate del("Hello, World!"); } }
Explanation:
- The
MyDelegate
delegate is declared to accept a string parameter and return void. - The
DisplayMessage
method matches the delegate signature. - The delegate is instantiated and used to call the
DisplayMessage
method.
Multicast Delegates
Delegates can reference more than one method. These are called multicast delegates.
using System; public class Program { public delegate void MyDelegate(string message); public static void DisplayMessage(string message) { Console.WriteLine("DisplayMessage: " + message); } public static void LogMessage(string message) { Console.WriteLine("LogMessage: " + message); } public static void Main() { MyDelegate del = DisplayMessage; del += LogMessage; del("Hello, Multicast!"); } }
Explanation:
- The
MyDelegate
delegate references bothDisplayMessage
andLogMessage
methods. - When the delegate is invoked, both methods are called in sequence.
Events
Declaring an Event
public class Publisher { // Declare the delegate for the event public delegate void Notify(string message); // Declare the event using the delegate public event Notify OnNotify; }
Raising an Event
public class Publisher { public delegate void Notify(string message); public event Notify OnNotify; public void RaiseEvent(string message) { if (OnNotify != null) { OnNotify(message); } } }
Subscribing to an Event
using System; public class Subscriber { public void OnNotified(string message) { Console.WriteLine("Subscriber received: " + message); } } public class Program { public static void Main() { Publisher publisher = new Publisher(); Subscriber subscriber = new Subscriber(); // Subscribe to the event publisher.OnNotify += subscriber.OnNotified; // Raise the event publisher.RaiseEvent("Event triggered!"); } }
Explanation:
- The
Publisher
class declares an eventOnNotify
using theNotify
delegate. - The
RaiseEvent
method raises the event if there are any subscribers. - The
Subscriber
class has a methodOnNotified
that matches the delegate signature. - In the
Main
method, theSubscriber
subscribes to thePublisher
's event, and the event is raised.
Practical Exercises
Exercise 1: Basic Delegate
Task: Create a delegate that takes an integer and returns its square.
public delegate int SquareDelegate(int number); public class Program { public static int Square(int number) { return number * number; } public static void Main() { SquareDelegate del = Square; Console.WriteLine(del(5)); // Output: 25 } }
Exercise 2: Event Handling
Task: Create a simple event system where a Button
class raises a Clicked
event, and a Handler
class subscribes to it.
public class Button { public delegate void ClickHandler(); public event ClickHandler Clicked; public void Click() { if (Clicked != null) { Clicked(); } } } public class Handler { public void OnButtonClicked() { Console.WriteLine("Button was clicked!"); } } public class Program { public static void Main() { Button button = new Button(); Handler handler = new Handler(); button.Clicked += handler.OnButtonClicked; button.Click(); // Output: Button was clicked! } }
Common Mistakes and Tips
- Null Reference: Always check if the event is null before raising it to avoid
NullReferenceException
. - Delegate Signature: Ensure the method signature matches the delegate signature when assigning methods to delegates.
- Unsubscribing: Remember to unsubscribe from events to prevent memory leaks, especially in long-running applications.
Conclusion
Delegates and events are essential tools in C# for creating flexible and maintainable code. Delegates allow methods to be passed as parameters, while events provide a mechanism for implementing the observer pattern. Understanding these concepts will enable you to write more dynamic and responsive applications.
C# Programming Course
Module 1: Introduction to C#
- Introduction to C#
- Setting Up the Development Environment
- Hello World Program
- Basic Syntax and Structure
- Variables and Data Types
Module 2: Control Structures
Module 3: Object-Oriented Programming
- Classes and Objects
- Methods
- Constructors and Destructors
- Inheritance
- Polymorphism
- Encapsulation
- Abstraction
Module 4: Advanced C# Concepts
- Interfaces
- Delegates and Events
- Generics
- Collections
- LINQ (Language Integrated Query)
- Asynchronous Programming
Module 5: Working with Data
Module 6: Advanced Topics
- Reflection
- Attributes
- Dynamic Programming
- Memory Management and Garbage Collection
- Multithreading and Parallel Programming