Dot Net TechnologyUnit 310 min read
Advanced C: Events, Delegates, Generics, Polymorphism & Static Classes
Unit 3 of Dot Net Technology covers C's advanced features—events/delegates, lambda expressions, static classes, sealed/abstract classes, compile-time polymorphism (method overloading), value/reference types, boxing/unboxing, indexers, and generics—with real-world examples from Nepalese apps (eSewa, Khalti) and code tra
Core Concepts & Definitions
1. Events and Delegates
Definition:
- Delegate: A type-safe function pointer that holds a reference to a method. Used to pass methods as arguments.
- Event: A message sent by an object to signal that something has happened. Events are based on delegates.
How it works:
classDiagram
class Publisher {
<<event>> OnClick
+Click()
}
class Subscriber {
+HandleClick()
}
Publisher --> Subscriber : "subscribes to"
Publisher --> Subscriber : "invokes"Example: Button Click in WinForms
// Step 1: Define a delegate
public delegate void ClickEventHandler(object sender, EventArgs e);
// Step 2: Define a class with an event
public class Button {
public event ClickEventHandler OnClick;
public void Click() {
OnClick?.Invoke(this, EventArgs.Empty); // Null-conditional operator
}
}
// Step 3: Subscribe to the event
Button btn = new Button();
btn.OnClick += (sender, e) => Console.WriteLine("Button clicked!");
btn.Click();
Trace:
| Step | Action | Output |
|---|---|---|
| 1 | Delegate definition | ClickEventHandler |
| 2 | Event declaration | OnClick event |
| 3 | Subscribe lambda | btn.OnClick += ... |
| 4 | Invoke Click() |
"Button clicked!" |
Real-world tie-in:
- eSewa App: When you click "Pay Bill," the app triggers an
OnPaymentInitiatedevent, which delegates to Khalti’s API handler. The event ensures secure payment processing without exposing internal logic.
2. Lambda Expressions and Generic Delegates
Definition:
- Lambda: Anonymous function written inline (e.g.,
x => x * 2). - Generic Delegate: A delegate that can hold any method signature (e.g.,
Func<T, TResult>).
Example: Sorting with Lambda
List<int> numbers = new List<int> { 5, 1, 9, 3 };
numbers.Sort((a, b) => b.CompareTo(a)); // Descending order
Trace:
| Step | Lambda Expression | Result (List) |
|---|---|---|
| 1 | a => a.CompareTo(b) |
[1, 3, 5, 9] |
| 2 | b.CompareTo(a) |
[9, 5, 3, 1] |
Real-world tie-in:
- Pathao Driver App: Uses
Func<Location, double>to dynamically calculate fares based on real-time traffic (e.g.,fare = (distance * baseRate) + (trafficFactor * distance)).
3. Static Classes and Constructors
Definition:
- Static Class: Cannot be instantiated; contains only static members (methods/properties).
- Static Constructor: Runs once when the class is first accessed (no access modifiers).
Example: Math Utilities
public static class MathUtils {
public static int Add(int a, int b) => a + b;
static MathUtils() {
Console.WriteLine("MathUtils initialized");
}
}
Trace:
| Step | Action | Output |
|---|---|---|
| 1 | Class definition | MathUtils (static) |
| 2 | First access (Add) |
"MathUtils initialized" |
Real-world tie-in:
- NTC Billing System: Uses a static
BillingCalculatorclass to compute electricity bills (e.g.,static double CalculateBill(int units)) without instantiation, ensuring thread safety.
4. Sealed and Abstract Classes
Comparison Table:
| Feature | Abstract Class | Sealed Class |
|---|---|---|
| Inheritance | Can be inherited | Cannot be inherited |
| Methods | Can have abstract methods | All methods are final |
| Constructor | Can have constructors | Can have constructors |
| Use Case | Define template (e.g., Shape) |
Prevent extension (e.g., String) |
Example: Abstract Shape
public abstract class Shape {
public abstract double Area();
}
public sealed class Circle : Shape {
public double Radius { get; set; }
public override double Area() => Math.PI * Radius * Radius;
}
Trace:
| Step | Action | Output |
|---|---|---|
| 1 | Define Shape (abstract) |
Area() method required |
| 2 | Circle inherits Shape |
Area() implemented |
| 3 | Circle sealed |
Cannot subclass Circle |
Real-world tie-in:
- NEPSE Stock API: Uses a sealed
StockDataclass to ensure no one modifies the core data structure while allowing derivedStockChartclasses to extend visualization.
5. Compile-Time Polymorphism (Method Overloading)
Definition: Multiple methods with the same name but different parameters.
classDiagram
class AreaCalculator {
+Area(double radius)
+Area(double length, double width)
}
AreaCalculator --> "Circle" : calls
AreaCalculator --> "Rectangle" : callsMethod overloading: Same name (Area) with different parameters for circles/rectangles
Example: Area Calculator
public class AreaCalculator {
public double Area(double radius) => Math.PI * radius * radius;
public double Area(double length, double width) => length * width;
}
Trace:
| Step | Method Call | Output |
|---|---|---|
| 1 | Area(5) |
78.54 (circle) |
| 2 | Area(4, 6) |
24 (rectangle) |
Real-world tie-in:
- Khalti Checkout: Overloads
ProcessPayment()to handle different payment types:public void ProcessPayment(string cardNumber) { ... } public void ProcessPayment(string phoneNumber) { ... } // For mobile wallets
6. Value Types vs. Reference Types
Comparison Table:
| Feature | Value Type (e.g., int) |
Reference Type (e.g., class) |
|---|---|---|
| Storage | Stack | Heap |
| Copy Behavior | Copies value | Copies reference |
| Boxing | Converts to object |
No conversion needed |
Example: Boxing/Unboxing
int num = 10; // Value type
object boxed = num; // Boxing
int unboxed = (int)boxed; // Unboxing
Trace:
| Step | Action | Memory Location |
|---|---|---|
| 1 | int num = 10 |
Stack: num = 10 |
| 2 | object boxed = num |
Heap: boxed points to 10 |
| 3 | (int)boxed |
Stack: unboxed = 10 |
Real-world tie-in:
- Daraz Order Queue: Uses reference types (
Orderclass) to track orders across threads, while value types (intfor quantity) are copied for thread safety.
7. Indexers and Generic Classes
Definition:
- Indexer: Allows instances to be indexed like arrays (e.g.,
myList[0]). - Generic Class: Reusable class with type parameters (e.g.,
List<T>).
Example: Generic KeyValuePair
public class KeyValuePair<TKey, TValue> {
public TKey Key { get; set; }
public TValue Value { get; set; }
}
KeyValuePair<string, int> pair = new KeyValuePair<string, int> {
Key = "Age", Value = 25
};
Trace:
| Step | Action | Output |
|---|---|---|
| 1 | Define KeyValuePair<TKey, TValue> |
Generic class |
| 2 | Instantiate with string, int |
pair.Key = "Age" |
Real-world tie-in:
- Ncell Billing: Uses
Dictionary<string, double>(generic class) to store user IDs (string) and balances (double), with indexers for quick lookups.
In the Real World
eSewa Payment Flow:
- Event Handling: When you click "Pay," the app raises a
PaymentInitiatedEvent, which delegates to Khalti’sProcessPaymentmethod. The event ensures secure, decoupled communication between UI and backend. - Lambda: The success callback uses a lambda to update the UI:
OnSuccess(() => UpdateBalance()).
- Event Handling: When you click "Pay," the app raises a
Pathao Driver Earnings:
- Generic Delegates: The app uses
Func<Location, double>to dynamically calculate fares based on traffic (e.g.,fare = distance * (1 + trafficFactor)). The delegate adapts to real-time data.
- Generic Delegates: The app uses
NTC Bill Calculation:
- Static Class: The
BillingCalculatorclass (static) computes bills without instantiation, ensuring thread safety across millions of users. Its static constructor initializes tax rates once.
- Static Class: The
Khalti Checkout Overloading:
- Method Overloading:
ProcessPayment()handles both card payments (string cardNumber) and mobile wallets (string phoneNumber), reducing code duplication.
- Method Overloading:
Daraz Order Processing:
- Reference Types: Orders are stored as
Orderobjects (reference types) in a queue, while order quantities (int) are copied for thread-safe updates.
- Reference Types: Orders are stored as
Exam Tip
Events/Delegates:
- Always show the delegate definition, event declaration, and subscription in code.
- Use
+=for adding and-=for removing event handlers.
Static Classes:
- Emphasize that they cannot be instantiated and their constructor runs only once.
Polymorphism:
- For overloading, list all method signatures in the answer. Include a table comparing parameters/return types.
Boxing/Unboxing:
- Draw the stack vs. heap diagram to show how value types are boxed into objects.
Generics:
- Use
List<T>orDictionary<K, V>in examples. Show how type parameters (T) are replaced at compile time.
- Use
Visual Summary:
Based on the TU BCA syllabus for Dot Net Technology (CACS408), unit 3.
Discussion
Loading…