C# డెలిగేట్స్ (Delegates), ఈవెంట్స్ & లాంబ్డా ఎక్స్ప్రెషన్స్ (=>)
ఫంక్షనల్ ప్రోగ్రామింగ్ పవర్హౌస్: డెలిగేట్స్, లాంబ్డా & ఈవెంట్స్! ⚡
సాధారణ వేరియబుల్స్లో సంఖ్యలు, అక్షరాలను దాస్తాం. మరి ఒక ఫంక్షన్ లేదా మెథడ్నే ఒక వేరియబుల్లో దాచి, ఇంకో మెథడ్కు పారామీటర్గా పంపించగలిగితే? ఒక బటన్ క్లిక్ అయినప్పుడు లేదా స్టాక్ ధర పెరిగినప్పుడు పది వేర్వేరు వ్యవస్థలకు ఏకకాలంలో నోటిఫికేషన్ పంపగలిగితే?
ఈ అద్భుతమైన ఫ్లెక్సిబిలిటీని C# లో అందించే త్రయమే Delegates, Events, మరియు Lambda Expressions.
ఆధునిక C# లో LINQ క్వెరీలు రాయాలన్నా, మైక్రోసర్వీసెస్ లో ఈవెంట్-డ్రివెన్ ఆర్కిటెక్చర్ నిర్మించాలన్నా, లేదా క్లౌడ్ మెసేజింగ్ బ్రోకర్లతో పనిచేయాలన్నా ఈ కాన్సెప్ట్స్ గుండెకాయ లాంటివి.
C# డెలిగేట్ల చరిత్ర నుండి ఆధునిక Func, Action మరియు లాంబ్డా మ్యాజిక్ వరకు ప్రతి సూక్ష్మాంశాన్ని ప్రాక్టికల్ కోడింగ్తో నేర్చుకుందాం!
1 🎯 డెలిగేట్ (Delegate) అంటే ఏమిటి? Type-Safe Function Pointer
C మరియు C++ భాషల్లో ఒక ఫంక్షన్ మెమరీ అడ్రస్ను పాయింట్ చేయడానికి ఫంక్షన్ పాయింటర్లు (Function Pointers) ఉండేవి. కానీ వాటికి టైప్ సేఫ్టీ ఉండేది కాదు (తప్పుడు పారామీటర్లు పంపినా కంపైలర్ ఆపలేకపోయేది, దీనివల్ల సిస్టమ్ క్రాష్ అయ్యేది).
ఈ సమస్యను పరిష్కరించడానికి C# అందించిన 100% టైప్-సేఫ్ & ఆబ్జెక్ట్-ఓరియెంటెడ్ ఫంక్షన్ పాయింటరే డెలిగేట్ (Delegate).
- ఒక డెలిగేట్ ఏ మెథడ్ను పాయింట్ చేస్తుందో ఆ మెథడ్ యొక్క Return Type మరియు Parameter Types ఖచ్చితంగా సరిపోవాలి.
- కంపైలర్ తెరవెనుక ప్రతి డెలిగేట్ కోసం
System.MulticastDelegateనుండి ఒక క్లాస్ను ఆటోమేటిక్గా జనరేట్ చేస్తుంది.
2 🏗️ డెలిగేట్ డిక్లరేషన్, ఇన్స్టాన్షియేషన్ & ఇన్వొకేషన్
డెలిగేట్తో పనిచేయడానికి 3 దశలు ఉంటాయి:
- డిక్లరేషన్ (Declaration):
public delegate void LogHandler(string msg); - ఇన్స్టాన్షియేషన్ (Binding):
LogHandler logger = PrintToConsole; - ఇన్వొకేషన్ (Invocation):
logger("హలో వరల్డ్");లేదాlogger.Invoke("హలో వరల్డ్");
// 1. డెలిగేట్ డిక్లరేషన్ (సిగ్నేచర్: 2 int పారామీటర్లు, int రిటర్న్)
public delegate int MathOperation(int a, int b);
public class Calculator
{
public static int Add(int x, int y) => x + y;
public static int Multiply(int x, int y) => x * y;
}
// 2. డెలిగేట్ వేరియబుల్కు మెథడ్ను బైండ్ చేయడం
MathOperation op = Calculator.Add;
int sum = op(10, 20); // Add మెథడ్ రన్ అవుతుంది
Console.WriteLine($"కూడిక ఫలితం: {sum}"); // 30
// డెలిగేట్ వేరియబుల్ను వేరే మెథడ్కు రీ-అసైన్ చేయవచ్చు!
op = Calculator.Multiply;
int product = op(10, 20); // Multiply మెథడ్ రన్ అవుతుంది
Console.WriteLine($"గుణకార ఫలితం: {product}"); // 200
3 📣 మల్టీకాస్ట్ డెలిగేట్స్ (Multicast Delegates `+=`, `-=`)
C# డెలిగేట్ల యొక్క అత్యంత శక్తివంతమైన లక్షణం — ఒకే ఒక్క డెలిగేట్ కాల్తో బహుళ మెథడ్స్ను ఒకేసారి పిలవడం (Broadcasting)!
+=ఆపరేటర్: డెలిగేట్ ఇన్వొకేషన్ లిస్ట్కు కొత్త మెథడ్ను జోడిస్తుంది (Subscribe).-=ఆపరేటర్: లిస్ట్ నుండి మెథడ్ను తొలగిస్తుంది (Unsubscribe).
public delegate void AlertNotifier(string message);
public class NotificationHub
{
public static void SendSms(string msg) => Console.WriteLine($"📱 SMS: {msg}");
public static void SendEmail(string msg) => Console.WriteLine($"📧 Email: {msg}");
public static void SendSlack(string msg) => Console.WriteLine($"💬 Slack: {msg}");
}
// మల్టీకాస్ట్ చైనింగ్
AlertNotifier notifier = NotificationHub.SendSms;
notifier += NotificationHub.SendEmail;
notifier += NotificationHub.SendSlack;
Console.WriteLine("--- 3 మెథడ్స్ చైన్ అయినప్పుడు ---");
notifier("సర్వర్ CPU వాడకం 95% దాటింది!"); // 3 మెథడ్స్ వరుసగా రన్ అవుతాయి!
// Slack ని అన్సబ్స్క్రైబ్ చేయడం
notifier -= NotificationHub.SendSlack;
Console.WriteLine("\n--- Slack తొలగించిన తర్వాత ---");
notifier("సర్వర్ సాధారణ స్థితికి వచ్చింది."); // కేవలం SMS మరియు Email మాత్రమే రన్ అవుతాయి
4 🎁 బిల్ట్-ఇన్ జెనెరిక్ డెలిగేట్లు: `Action`, `Func`, `Predicate`
ప్రతి చిన్న మెథడ్కు మనం మాన్యువల్గా public delegate ... అని రాసుకుంటూ వెళ్తే వేలాది డెలిగేట్లు తయారవుతాయి.
అందుకే .NET ఫ్రేమ్వర్క్ ప్రతి డెవలపర్కు అవసరమైన 3 రెడీమేడ్ జెనెరిక్ డెలిగేట్లను అందించింది:
| బిల్ట్-ఇన్ డెలిగేట్ | రిటర్న్ టైప్ | ఎప్పుడు వాడాలి? | ఉదాహరణ |
|---|---|---|---|
Action<T1, T2...> |
void (ఏమీ రిటర్న్ చేయదు) |
ప్రింటింగ్, లాగింగ్, ఈవెంట్ ఫైరింగ్ | Action<string> print = msg => Console.WriteLine(msg); |
Func<T1, T2, TResult> |
TResult (చివరి టైప్ రిటర్న్ అవుతుంది) |
గణనలు, ట్రాన్స్ఫార్మేషన్లు, డేటా రిటర్న్ | Func<int, int, int> add = (a, b) => a + b; |
Predicate<T> |
ఎల్లప్పుడూ bool మాత్రమే |
షరతులు, ఫిల్టర్లు, సరిచూడటం | Predicate<int> isEven = n => n % 2 == 0; |
// 1. Action: 1 పారామీటర్, void రిటర్న్
Action logger = message => Console.WriteLine($"[AUDIT]: {message}");
logger("యూజర్ లాగిన్ విజయవంతం");
// 2. Func: 2 ఇన్పుట్ డెసిమల్స్, 1 డెసిమల్ రిటర్న్
Func calculateGst = (basePrice, rate) => basePrice * (rate / 100m);
decimal tax = calculateGst(50000m, 18m);
Console.WriteLine($"జీఎస్టీ పన్ను: ₹{tax:N2}");
// 3. Predicate: 1 ఇన్పుట్, bool రిటర్న్
Predicate isSeniorCitizen = age => age >= 60;
Console.WriteLine($"రాయితీకి అర్హులా? {isSeniorCitizen(65)}"); // True
5 📜 అనామక మెథడ్స్ (Anonymous Methods) నుండి లాంబ్డా వైపు పరిణామం
C# 1.0 లో ఒక డెలిగేట్ వాడాలంటే వేరే చోట ఒక పేరున్న మెథడ్ను డిక్లేర్ చేయాల్సి వచ్చేది.
C# 2.0 లో delegate(int x) { return x * 2; } అనే అనామక మెథడ్స్ వచ్చాయి.
కానీ C# 3.0 లో వచ్చిన లాంబ్డా ఎక్స్ప్రెషన్స్ (Lambda Expressions) వాటన్నింటినీ తుడిచిపెట్టేసి, అత్యంత క్లీన్ ఫ్యాట్-యారో సింటాక్స్ను ప్రవేశపెట్టాయి.
6 🚀 లాంబ్డా ఎక్స్ప్రెషన్స్ (Lambda Expressions `=>`)
లాంబ్డా ఎక్స్ప్రెషన్ అనేది పేరు లేని ఒక చిన్న ఇన్లైన్ ఫంక్షన్. దీని సింటాక్స్:
లాంబ్డాలు రెండు రకాలు:
- Expression Lambda (ఒకే లైన్):
x => x * x(రిటర్న్ కీవర్డ్ మరియు కర్లీ బ్రేసెస్ అవసరం లేదు; ఆటోమేటిక్గా రిటర్న్ అవుతుంది). - Statement Lambda (బహుళ లైన్లు):
(x, y) => { int sum = x + y; return sum; }(కర్లీ బ్రేసెస్ మరియుreturnతప్పనిసరి).
7 🧠 క్లోజర్స్ (Closures) & వేరియబుల్ క్యాప్చరింగ్ మెకానిక్స్
ఒక లాంబ్డా ఎక్స్ప్రెషన్ తన లోపల లేని, బయటి మెథడ్లోని లోకల్ వేరియబుల్ను వాడినప్పుడు దానిని Captured Variable అంటారు. ఆ లాంబ్డా మరియు క్యాప్చర్డ్ వేరియబుల్ కలిసి ఏర్పరిచే జీవ వ్యవస్థను క్లోజర్ (Closure) అంటారు.
Func CreateMultiplier(int factor)
{
// 'factor' అనేది బయటి లోకల్ వేరియబుల్.
// ఈ మెథడ్ ముగిసినా సరే, లాంబ్డా ఆ 'factor' ను మెమరీలో సజీవంగా దాచిపెడుతుంది!
return x => x * factor;
}
var triple = CreateMultiplier(3);
Console.WriteLine(triple(10)); // 30
Console.WriteLine(triple(25)); // 75
CLR అంతర్గత రహస్యం: C# కంపైలర్ తెరవెనుక ఒక గుప్తమైన క్లాస్ను సృష్టించి, ఆ factor వేరియబుల్ను ఆ క్లాస్ లోని ఫీల్డ్గా మార్చి Heap పై దాస్తుంది!
8 🚨 `event` కీవర్డ్ — డెలిగేట్కు సెక్యూరిటీ గార్డు
డెలిగేట్స్ ఉన్నప్పుడు మళ్లీ ప్రత్యేకంగా event కీవర్డ్ ఎందుకు కావాలి?
ఈ క్రింది తీవ్రమైన భద్రతా లోపాన్ని గమనించండి:
public class UnsafePublisher
{
// పబ్లిక్ డెలిగేట్ (ఈవెంట్ కాదు!)
public Action OnPaymentCompleted;
}
UnsafePublisher pub = new UnsafePublisher();
pub.OnPaymentCompleted += msg => Console.WriteLine("సబ్స్క్రైబర్ 1");
// ❌ ప్రమాదం 1: బయటి కోడ్ ప్రమాదవశాత్తు మొత్తం లిస్ట్ను తుడిచేయవచ్చు!
pub.OnPaymentCompleted = null; // అందరు సబ్స్క్రైబర్లు పోయారు!
// ❌ ప్రమాదం 2: బయటి కోడ్ అనధికారికంగా ఈవెంట్ను ఫైర్ చేయవచ్చు!
pub.OnPaymentCompleted("డబ్బులు చెల్లించకుండానే నకిలీ నోటిఫికేషన్!");
పై రెండు ప్రమాదాలను అరికట్టడానికి event కీవర్డ్ వాడతాం:
మీరు event అని పెట్టిన క్షణమే:
1) బయటి కోడ్ కేవలం += మరియు -= మాత్రమే చేయగలదు (ఓవర్రైట్ చేయలేదు).
2) ఈవెంట్ను ఫైర్ చేసే అధికారం కేవలం ఆ పబ్లిషర్ క్లాస్ లోపల మాత్రమే ఉంటుంది!
9 🏛️ స్టాండర్డ్ .NET ఈవెంట్ ప్యాటర్న్ (`EventHandler`)
మైక్రోసాఫ్ట్ ఫ్రేమ్వర్క్ డిజైన్ గైడ్లైన్స్ ప్రకారం ప్రతి ప్రొఫెషనల్ C# ఈవెంట్ రెండు పారామీటర్లను కలిగి ఉండాలి:
object? sender: ఈవెంట్ను ఎవరు ఫైర్ చేశారు (Publisher instance).TEventArgs e: ఈవెంట్కు సంబంధించిన డేటాను మోసే క్లాస్ (Derived fromEventArgs).
// 1. కస్టమ్ ఈవెంట్ ఆర్గ్యుమెంట్స్
public class OrderEventArgs : EventArgs
{
public string OrderId { get; }
public decimal TotalAmount { get; }
public OrderEventArgs(string id, decimal amount)
{
OrderId = id;
TotalAmount = amount;
}
}
// 2. పబ్లిషర్ క్లాస్
public class OrderService
{
// స్టాండర్డ్ జెనెరిక్ ఈవెంట్ డిక్లరేషన్
public event EventHandler OrderPlaced;
public void CompleteOrder(string id, decimal amount)
{
Console.WriteLine($"📦 ఆర్డర్ {id} సిస్టమ్లో నమోదైంది.");
// 🌟 థ్రెడ్-సేఫ్ నల్ చెక్ తో ఈవెంట్ ఫైరింగ్
OrderPlaced?.Invoke(this, new OrderEventArgs(id, amount));
}
}
10 🧹 ఈవెంట్ మెమరీ లీక్స్ & అన్సబ్స్క్రైబింగ్ (`-=`)
.NET అప్లికేషన్లలో వచ్చే అత్యంత సాధారణ మెమరీ లీక్కు కారణం: ఈవెంట్లను అన్సబ్స్క్రైబ్ చేయకపోవడం!
ఒక లాంగ్-లివ్డ్ పబ్లిషర్ (ఉదా: గ్లోబల్ స్టాక్ ఫీడ్) కు ఒక షార్ట్-లివ్డ్ సబ్స్క్రైబర్ (ఉదా: ఒక తాత్కాలిక UI పేజీ) += చేసినప్పుడు,
పబ్లిషర్ తన ఇన్వొకేషన్ లిస్ట్లో ఆ సబ్స్క్రైబర్కు సంబంధించిన స్ట్రాంగ్ రిఫరెన్స్ను కలిగి ఉంటాడు.
దీనివల్ల సబ్స్క్రైబర్ పని అయిపోయినా సరే, Garbage Collector దానిని మెమరీ నుండి డిలీట్ చేయలేదు.
అందువల్ల ఆబ్జెక్ట్ నశించే సమయంలో (Dispose మెథడ్లో) ఖచ్చితంగా -= ద్వారా అన్సబ్స్క్రైబ్ చేయాలి!
11 ⚖️ Delegates vs Events vs Interfaces — ఎప్పుడు దేన్ని ఎంచుకోవాలి?
| ఫీచర్ | డెలిగేట్ (Delegate / Func / Action) | ఈవెంట్ (Event) | ఇంటర్ఫేస్ (Interface) |
|---|---|---|---|
| సబ్స్క్రైబర్లు | సాధారణంగా ఒక్క కాల్బ్యాక్ ఫంక్షన్ కోసం | ఎందరో సబ్స్క్రైబర్లు (Broadcast: 1 to Many) | ఒక క్లాస్ పూర్తి కాంట్రాక్ట్ను ఇంప్లిమెంట్ చేయడానికి |
| భద్రత | బయటి కోడ్ సులభంగా ఓవర్రైట్ చేయవచ్చు | కఠినమైన భద్రత (కేవలం +=, -= మాత్రమే) |
కాంపైల్-టైమ్ స్ట్రిక్ట్ టైపింగ్ |
| ఉత్తమ వినియోగం | LINQ ఫిల్టర్లు, చిన్న క్యాలిక్యులేషన్ పారామీటర్లు | UI బటన్ క్లిక్స్, స్టాక్ టిక్కర్లు, లాగిన్ అలర్ట్స్ | డేటాబేస్ రిపోజిటరీలు, భారీ సర్వీసులు, DI |
12 📈 రియల్-వరల్డ్ ప్రాజెక్ట్ — ఎంటర్ప్రైజ్ స్టాక్ మార్కెట్ టిక్కర్ & బాట్ అలర్ట్ సిస్టమ్
ఈ అధ్యాయంలో నేర్చుకున్న Delegates, Events, EventHandler<T>, Lambda Expressions,
మరియు Predicate<T> లన్నింటినీ ఏకీకృతం చేసి ఒక పూర్తి స్థాయి రియల్-టైమ్ స్టాక్ మార్కెట్ టిక్కర్ ఇంజిన్ (Stock Ticker Engine v1.0) నిర్మిద్దాం.
using System;
using System.Collections.Generic;
Console.OutputEncoding = System.Text.Encoding.UTF8;
Console.WriteLine("=================================================");
Console.WriteLine("📈 మన ట్రేడ్ - ఎంటర్ప్రైజ్ స్టాక్ టిక్కర్ & అలర్ట్ ఇంజిన్ v1.0");
Console.WriteLine("=================================================\n");
// 1. స్టాక్ ధర మార్పుల ఈవెంట్ డేటా
public class StockPriceChangedEventArgs(string symbol, decimal oldPrice, decimal newPrice) : EventArgs
{
public string Symbol { get; } = symbol;
public decimal OldPrice { get; } = oldPrice;
public decimal NewPrice { get; } = newPrice;
public decimal ChangePercent => ((newPrice - oldPrice) / oldPrice) * 100m;
}
// 2. Publisher: స్టాక్ మార్కెట్ ఫీడ్
public class StockMarketFeed
{
// పబ్లిక్ ఈవెంట్
public event EventHandler OnPriceChanged;
private readonly Dictionary _stocks = new();
public void RegisterStock(string symbol, decimal initialPrice)
{
_stocks[symbol] = initialPrice;
}
public void UpdatePrice(string symbol, decimal newPrice)
{
if (!_stocks.ContainsKey(symbol)) return;
decimal oldPrice = _stocks[symbol];
_stocks[symbol] = newPrice;
// థ్రెడ్-సేఫ్ పద్ధతిలో సబ్స్క్రైబర్లకు ఈవెంట్ ప్రసారం
OnPriceChanged?.Invoke(this, new StockPriceChangedEventArgs(symbol, oldPrice, newPrice));
}
}
// 3. Subscriber 1: SMS అలర్ట్ బోట్ (లాంబ్డా ఎక్స్ప్రెషన్లతో)
public class SmsAlertBot
{
public void OnStockUpdate(object sender, StockPriceChangedEventArgs e)
{
if (Math.Abs(e.ChangePercent) >= 5.0m)
{
string direction = e.ChangePercent > 0 ? "🚀 భారీగా పెరిగింది" : "⚠️ భారీగా పతనమైంది";
Console.WriteLine($" [📱 SMS అలర్ట్]: {e.Symbol} {direction}! పాత ధర: ₹{e.OldPrice:N2} -> కొత్త ధర: ₹{e.NewPrice:N2} ({e.ChangePercent:+0.00;-0.00}%)");
}
}
}
// 4. Subscriber 2: ఆటో-ట్రేడర్ రోబోట్ (Func & Action డెలిగేట్లతో)
public class AutoTraderBot
{
public void EvaluateMarket(object sender, StockPriceChangedEventArgs e)
{
// ధర 7% కంటే ఎక్కువ తగ్గితే ఆటోమేటిక్గా షేర్లు కొనుగోలు చేయడం (Buy the dip)
if (e.ChangePercent <= -7.0m)
{
Console.WriteLine($" [🤖 ఆటో ట్రేడర్]: {e.Symbol} భారీ పతనంలో ఉంది. ₹{e.NewPrice:N2} వద్ద 50 షేర్లు కొనుగోలు చేయబడ్డాయి!");
}
else if (e.ChangePercent >= 8.0m)
{
Console.WriteLine($" [🤖 ఆటో ట్రేడర్]: {e.Symbol} లాభాల స్వీకరణ! ₹{e.NewPrice:N2} వద్ద 25 షేర్లు విక్రయించబడ్డాయి.");
}
}
}
// డ్రైవర్ కోడ్: ఈవెంట్ సబ్స్క్రిప్షన్ & లైవ్ మార్కెట్ సిమ్యులేషన్
StockMarketFeed nse = new StockMarketFeed();
nse.RegisterStock("TCS", 3800.00m);
nse.RegisterStock("RELIANCE", 2900.00m);
nse.RegisterStock("INFY", 1500.00m);
SmsAlertBot smsBot = new SmsAlertBot();
AutoTraderBot autoTrader = new AutoTraderBot();
// ఈవెంట్లకు సబ్స్క్రైబ్ చేయడం (+=)
nse.OnPriceChanged += smsBot.OnStockUpdate;
nse.OnPriceChanged += autoTrader.EvaluateMarket;
// లాంబ్డా ద్వారా ఇన్లైన్ ఆడిట్ లాగర్ సబ్స్క్రిప్షన్
nse.OnPriceChanged += (sender, args) =>
Console.WriteLine($"📊 [టిక్కర్]: {args.Symbol} ట్రేడ్ అయ్యింది -> ₹{args.NewPrice:N2} ({args.ChangePercent:+0.00;-0.00}%)");
Console.WriteLine("🔔 మార్కెట్ బెల్ మోగింది! లైవ్ ట్రేడింగ్ ప్రారంభమైంది...\n");
// సిమ్యులేటెడ్ మార్కెట్ లావాదేవీలు
nse.UpdatePrice("TCS", 3820.00m); // చిన్న మార్పు
Console.WriteLine();
nse.UpdatePrice("RELIANCE", 2690.00m); // ~7.2% పతనం -> అలర్ట్ + ఆటో-బై ట్రిగ్గర్!
Console.WriteLine();
nse.UpdatePrice("INFY", 1635.00m); // ~9.0% జంప్ -> అలర్ట్ + ఆటో-సెల్ ట్రిగ్గర్!
Console.WriteLine("\n=================================================");
💻 ఈ ట్రేడింగ్ అలర్ట్ ఇంజిన్ను లైవ్ కంపైలర్లో రన్ చేసి చూడండి!
Publisher-Subscriber ఆర్కిటెక్చర్, += సబ్స్క్రిప్షన్లు, మరియు బహుళ బోట్ల ఆటోమేటిక్ ఈవెంట్ స్పందనను ప్రత్యక్షంగా పరిశీలించండి.
13 🎓 ఇంటర్వ్యూ ప్రశ్నలు, బెస్ట్ ప్రాక్టీసెస్ & 5 ఇంటరాక్టివ్ క్విజ్ ప్రశ్నలు
టాప్ ఇంటర్వ్యూ ప్రశ్నలు & సమాధానాలు:
Q1: C# లో Func కి మరియు Action కి మధ్య ప్రధాన తేడా ఏమిటి?
జవాబు: Action ఎల్లప్పుడూ void ని రిటర్న్ చేస్తుంది (ఏమీ రిటర్న్ చేయదు). Func ఎల్లప్పుడూ ఒక నిర్దిష్ట విలువను రిటర్న్ చేస్తుంది (దాని జెనెరిక్ టైప్ లిస్ట్లో చివరిది రిటర్న్ టైప్ అవుతుంది, ఉదా: Func<int, string> లో string రిటర్న్ అవుతుంది).
Q2: డెలిగేట్ ముందు event కీవర్డ్ చేర్చడం వల్ల కలిగే రక్షణ ఏమిటి?
జవాబు: event కీవర్డ్ ఎన్క్యాప్సులేషన్ను అమలు చేస్తుంది. బయటి క్లాసులు ఆ ఈవెంట్ను null తో ఓవర్రైట్ చేయలేవు మరియు బయటి నుండి ఈవెంట్ను అక్రమంగా ఫైర్ చేయలేవు. బయటి ప్రపంచానికి కేవలం += (subscribe) మరియు -= (unsubscribe) మాత్రమే అనుమతించబడతాయి.
🧠 మీ నాలెడ్జ్ చెక్ చేసుకోండి — 5 ఇంటరాక్టివ్ క్విజ్ ప్రశ్నలు
❓ ప్రశ్న 1: Predicate<string> డెలిగేట్ అంతిమంగా ఏ డేటా టైప్ను రిటర్న్ చేస్తుంది?
bool. ప్రెడికేట్ ఎల్లప్పుడూ ఒక ఇన్పుట్ పారామీటర్ను స్వీకరించి true లేదా false బూలియన్ విలువను మాత్రమే రిటర్న్ చేస్తుంది.
❓ ప్రశ్న 2: మల్టీకాస్ట్ డెలిగేట్కు కొత్త మెథడ్ను జోడించడానికి ఏ ఆపరేటర్ వాడాలి?
+=. తొలగించడానికి -= వాడాలి.
❓ ప్రశ్న 3: లాంబ్డా ఎక్స్ప్రెషన్లో వాడే => సింబల్ను ఏమని పిలుస్తారు?
❓ ప్రశ్న 4: లాంబ్డా ఎక్స్ప్రెషన్ బయటి లోకల్ వేరియబుల్ను క్యాప్చర్ చేసినప్పుడు ఏర్పడే భావనను ఏమంటారు?
❓ ప్రశ్న 5: ఒక ఈవెంట్ను సురక్షితంగా ఫైర్ చేయడానికి ఏ సింటాక్స్ సిఫార్సు చేయబడింది?
MyEvent?.Invoke(this, args);. నల్-కండిషనల్ ఆపరేటర్ ?. వల్ల ఎవరైనా సబ్స్క్రైబర్లు లేనప్పుడు (నల్ అయినప్పుడు) NullReferenceException రాకుండా సురక్షితంగా రక్షిస్తుంది.