मुझे पता है कि यह सवाल 10 साल से अधिक पुराना है, लेकिन यह मुझे प्रतीत होता है कि न केवल सबसे स्पष्ट उत्तर को संबोधित नहीं किया गया है, लेकिन शायद यह वास्तव में सवाल से अच्छी तरह से स्पष्ट नहीं है कि कवर के तहत क्या होता है। इसके अलावा, लेट बाइंडिंग के बारे में अन्य प्रश्न हैं और इसका मतलब है कि प्रतिनिधियों और लैम्ब्डा के संबंध में (उस पर बाद में)।
सबसे पहले कमरे, जब चुनने के लिए में 800 पौंड हाथी / गोरिल्ला को संबोधित करने के eventबनाम Action<T>/ Func<T>:
- एक कथन या विधि को निष्पादित करने के लिए एक लैम्ब्डा का उपयोग करें।
eventजब आप कई स्टेटमेंट्स / लैम्ब्डा / फंक्शन्स के साथ पब / सब मॉडल का अधिक उपयोग करना चाहते हैं जो निष्पादित होगा (यह
बल्ले से एक बड़ा अंतर है)।
- जब आप पेड़ों की अभिव्यक्ति के लिए बयानों / कार्यों को संकलित करना चाहते हैं तो एक लैम्ब्डा का उपयोग करें। जब आप प्रतिबिंब और COM इंटरॉप में उपयोग किए जाने वाले अधिक पारंपरिक देर बंधन में भाग लेना चाहते हैं, तो प्रतिनिधियों / घटनाओं का उपयोग करें।
एक घटना के उदाहरण के रूप में, निम्न प्रकार से एक छोटे कंसोल एप्लिकेशन का उपयोग करके घटनाओं के एक सरल और 'मानक' सेट को वायर करने देता है:
public delegate void FireEvent(int num);
public delegate void FireNiceEvent(object sender, SomeStandardArgs args);
public class SomeStandardArgs : EventArgs
{
public SomeStandardArgs(string id)
{
ID = id;
}
public string ID { get; set; }
}
class Program
{
public static event FireEvent OnFireEvent;
public static event FireNiceEvent OnFireNiceEvent;
static void Main(string[] args)
{
OnFireEvent += SomeSimpleEvent1;
OnFireEvent += SomeSimpleEvent2;
OnFireNiceEvent += SomeStandardEvent1;
OnFireNiceEvent += SomeStandardEvent2;
Console.WriteLine("Firing events.....");
OnFireEvent?.Invoke(3);
OnFireNiceEvent?.Invoke(null, new SomeStandardArgs("Fred"));
//Console.WriteLine($"{HeightSensorTypes.Keyence_IL030}:{(int)HeightSensorTypes.Keyence_IL030}");
Console.ReadLine();
}
private static void SomeSimpleEvent1(int num)
{
Console.WriteLine($"{nameof(SomeSimpleEvent1)}:{num}");
}
private static void SomeSimpleEvent2(int num)
{
Console.WriteLine($"{nameof(SomeSimpleEvent2)}:{num}");
}
private static void SomeStandardEvent1(object sender, SomeStandardArgs args)
{
Console.WriteLine($"{nameof(SomeStandardEvent1)}:{args.ID}");
}
private static void SomeStandardEvent2(object sender, SomeStandardArgs args)
{
Console.WriteLine($"{nameof(SomeStandardEvent2)}:{args.ID}");
}
}
आउटपुट निम्नानुसार दिखेगा:

यदि आपने ऐसा ही किया Action<int>या Action<object, SomeStandardArgs>, आप केवल SomeSimpleEvent2और केवल देखेंगे SomeStandardEvent2।
तो अंदर क्या चल रहा है event?
यदि हम विस्तार करते हैं FireNiceEvent, तो संकलक वास्तव में निम्नलिखित उत्पन्न कर रहा है (मैंने थ्रेड सिंक्रनाइज़ेशन के संबंध में कुछ विवरण छोड़ दिए हैं जो इस चर्चा के लिए प्रासंगिक नहीं है):
private EventHandler<SomeStandardArgs> _OnFireNiceEvent;
public void add_OnFireNiceEvent(EventHandler<SomeStandardArgs> handler)
{
Delegate.Combine(_OnFireNiceEvent, handler);
}
public void remove_OnFireNiceEvent(EventHandler<SomeStandardArgs> handler)
{
Delegate.Remove(_OnFireNiceEvent, handler);
}
public event EventHandler<SomeStandardArgs> OnFireNiceEvent
{
add
{
add_OnFireNiceEvent(value)
}
remove
{
remove_OnFireNiceEvent(value)
}
}
संकलक एक निजी प्रतिनिधि चर उत्पन्न करता है जो वर्ग नामस्थान में दिखाई नहीं देता है जिसमें यह उत्पन्न होता है। वह प्रतिनिधि जो सदस्यता प्रबंधन और देर से बाध्यकारी भागीदारी के लिए उपयोग किया जाता है, और जनता का सामना करने वाला इंटरफ़ेस परिचित +=और -=ऑपरेटर है जिसे हम सभी जानते हैं और प्यार करते हैं:)
आप FireNiceEventप्रतिनिधि के दायरे को संरक्षित में जोड़कर / हटाए हैंडलर्स के लिए कोड को अनुकूलित कर सकते हैं । यह अब डेवलपर्स को हुक में कस्टम हुक जोड़ने की अनुमति देता है, जैसे लॉगिंग या सुरक्षा हुक। यह वास्तव में कुछ बहुत ही शक्तिशाली सुविधाओं के लिए बनाता है जो अब उपयोगकर्ता भूमिकाओं के आधार पर सदस्यता के लिए अनुकूलित अभिगम्यता की अनुमति देता है, आदि क्या आप लैम्ब्डा के साथ ऐसा कर सकते हैं? (वास्तव में आप अभिव्यक्ति संकलन पेड़ों द्वारा कस्टम कर सकते हैं, लेकिन यह इस प्रतिक्रिया के दायरे से परे है)।
यहाँ कुछ प्रतिक्रियाओं से कुछ बिंदुओं को संबोधित करने के लिए:
आर्ग की सूची को बदलने और उससे Action<T>प्राप्त वर्ग में गुणों को बदलने के बीच 'भंगुरता' में वास्तव में कोई अंतर नहीं है EventArgs। या तो केवल एक संकलन परिवर्तन की आवश्यकता नहीं होगी, वे दोनों एक सार्वजनिक इंटरफ़ेस को बदल देंगे और संस्करण की आवश्यकता होगी। कोई फर्क नहीं।
जिसके संबंध में एक उद्योग मानक है, जो इस बात पर निर्भर करता है कि इसका उपयोग कहां और क्यों किया जा रहा है। Action<T>और ऐसा अक्सर IoC और DI में उपयोग किया जाता है, और eventअक्सर इसका उपयोग संदेश मार्ग जैसे GUI और MQ प्रकार के फ्रेमवर्क में किया जाता है। ध्यान दें कि मैंने अक्सर कहा , हमेशा नहीं ।
डेलिगेट्स में लंबोदर की तुलना में अलग-अलग जीवनकाल हैं। एक को पकड़ने के बारे में भी पता होना चाहिए ... न केवल बंद होने के साथ, बल्कि 'बिल्ली क्या खींचती है' की धारणा के साथ। यह स्मृति पदचिह्न / जीवनकाल और साथ ही प्रबंधन उर्फ लीक को प्रभावित करता है।
एक और बात, कुछ मैंने पहले संदर्भित किया था ... देर से बाध्यकारी की धारणा। LINQ जैसे ढांचे का उपयोग करते समय, लैम्बडा 'लाइव' हो जाने के बारे में आपको अक्सर यह दिखाई देगा। यह एक प्रतिनिधि के देर से बाध्यकारी से बहुत अलग है, जो एक से अधिक बार हो सकता है (यानी लंबोदर हमेशा होता है, लेकिन बाध्यकारी मांग पर होता है जितनी बार जरूरत होती है), एक लंबो के विपरीत, जो एक बार होता है, इसका किया जाता है - जादू चला गया है, और विधि (एस) / संपत्ति (ies) हमेशा बांध देगी। मन में कुछ रखने के लिए।