प्रतिनिधियों और घटनाओं के बीच अंतर क्या हैं? दोनों ही ऐसे कार्यों के संदर्भ नहीं हैं जिन्हें निष्पादित किया जा सकता है?
प्रतिनिधियों और घटनाओं के बीच अंतर क्या हैं? दोनों ही ऐसे कार्यों के संदर्भ नहीं हैं जिन्हें निष्पादित किया जा सकता है?
जवाबों:
एक घटना घोषणा अमूर्त और पर सुरक्षा की एक परत जोड़ता प्रतिनिधि उदाहरण। यह सुरक्षा प्रतिनिधि के ग्राहकों को प्रतिनिधि और इसकी मंगलाचरण सूची को रीसेट करने से रोकती है और केवल आह्वान सूची से लक्ष्य जोड़ने या हटाने की अनुमति देती है।
मतभेदों को समझने के लिए आप इस 2 उदाहरणों को देख सकते हैं
प्रतिनिधि के साथ उदाहरण (इस मामले में, एक कार्य - यह एक प्रकार का प्रतिनिधि है जो मान वापस नहीं करता है)
public class Animal
{
public Action Run {get; set;}
public void RaiseEvent()
{
if (Run != null)
{
Run();
}
}
}
प्रतिनिधि का उपयोग करने के लिए, आपको कुछ इस तरह करना चाहिए:
Animal animal= new Animal();
animal.Run += () => Console.WriteLine("I'm running");
animal.Run += () => Console.WriteLine("I'm still running") ;
animal.RaiseEvent();
यह कोड अच्छी तरह से काम करता है लेकिन आपके पास कुछ कमजोर स्पॉट हो सकते हैं।
उदाहरण के लिए, अगर मैं यह लिखता हूं:
animal.Run += () => Console.WriteLine("I'm running");
animal.Run += () => Console.WriteLine("I'm still running");
animal.Run = () => Console.WriteLine("I'm sleeping") ;
कोड की अंतिम पंक्ति के साथ, मैंने पिछले व्यवहारों को केवल एक लापता के साथ ओवरराइड किया है +
(मैंने =
इसके बजाय उपयोग किया है +=
)
एक और कमजोर जगह यह है कि हर वर्ग जो आपकी Animal
कक्षा का उपयोग करता है, RaiseEvent
वह बस इसे कॉल कर सकता है animal.RaiseEvent()
।
इन कमजोर धब्बों से बचने के लिए आप events
c # का उपयोग कर सकते हैं ।
आपका पशु वर्ग इस तरह से बदल जाएगा:
public class ArgsSpecial : EventArgs
{
public ArgsSpecial (string val)
{
Operation=val;
}
public string Operation {get; set;}
}
public class Animal
{
// Empty delegate. In this way you are sure that value is always != null
// because no one outside of the class can change it.
public event EventHandler<ArgsSpecial> Run = delegate{}
public void RaiseEvent()
{
Run(this, new ArgsSpecial("Run faster"));
}
}
घटनाओं को कॉल करने के लिए
Animal animal= new Animal();
animal.Run += (sender, e) => Console.WriteLine("I'm running. My value is {0}", e.Operation);
animal.RaiseEvent();
अंतर:
टिप्पणियाँ:
EventHandler निम्नलिखित प्रतिनिधि के रूप में घोषित किया जाता है:
public delegate void EventHandler (object sender, EventArgs e)
यह एक प्रेषक (वस्तु प्रकार) और घटना तर्क लेता है। यदि यह स्थिर विधियों से आता है तो प्रेषक अशक्त है।
यह उदाहरण, जो उपयोग करता है EventHandler<ArgsSpecial>
, EventHandler
इसके बजाय का उपयोग करके भी लिखा जा सकता है ।
EventHandler के बारे में प्रलेखन के लिए यहाँ देखें
RaiseEvent
तब तक कॉल नहीं कर सकता जब तक कि कॉलिंग विधि animal
में उस कोड का एक उदाहरण तक पहुंच नहीं है जो घटना का उपयोग करता है?
animal.Run(this, new ArgsSpecial("Run faster");
?
सिंटैक्टिक और ऑपरेशनल गुणों के अलावा, एक शब्दार्थिक अंतर भी है।
प्रतिनिधि हैं, वैचारिक रूप से, फ़ंक्शन टेम्पलेट; यह है, वे एक अनुबंध व्यक्त करते हैं कि एक फ़ंक्शन को प्रतिनिधि के "प्रकार" के रूप में माना जाना चाहिए।
घटनाओं का प्रतिनिधित्व करते हैं ... अच्छी तरह से, घटनाओं। वे किसी को कुछ होने पर सचेत करने का इरादा रखते हैं और हाँ, वे एक प्रतिनिधि परिभाषा का पालन करते हैं लेकिन वे एक ही चीज़ नहीं हैं।
यहां तक कि अगर वे वास्तव में एक ही चीज थे (संयोगवश और आईएल कोड में) अभी भी शब्दार्थ अंतर रहेगा। सामान्य तौर पर मैं दो अलग-अलग अवधारणाओं के लिए दो अलग-अलग नाम रखना पसंद करता हूं, भले ही वे एक ही तरीके से लागू हों (जिसका मतलब यह नहीं है कि मुझे एक ही कोड दो बार पसंद है)।
यहाँ एक और अच्छा लिंक है। http://csharpindepth.com/Articles/Chapter2/Events.aspx
संक्षेप में, लेख से दूर ले जाओ - घटनाक्रम प्रतिनिधियों पर इनकैप्सुलेशन हैं।
लेख से उद्धरण:
मान लीजिए कि ईवेंट C # /। NET में एक अवधारणा के रूप में मौजूद नहीं थे। कोई अन्य वर्ग किसी घटना की सदस्यता कैसे लेगा? तीन विकल्प:
एक सार्वजनिक प्रतिनिधि चर
एक प्रतिनिधि चर एक संपत्ति द्वारा समर्थित है
AddXXXHandler और RemoveXXXHandler विधियों के साथ एक प्रतिनिधि चर
विकल्प 1 स्पष्ट रूप से भयानक है, सभी सामान्य कारणों से हम सार्वजनिक चर को घृणा करते हैं।
विकल्प 2 थोड़ा बेहतर है, लेकिन ग्राहकों को प्रभावी रूप से एक-दूसरे को ओवरराइड करने की अनुमति देता है - यह सब कुछ लिखना बहुत आसान होगा। जो एक नया जोड़ने के बजाय किसी भी मौजूदा ईवेंट हैंडलर की जगह लेगा। इसके अलावा, आपको अभी भी गुण लिखने की आवश्यकता है।
विकल्प 3 मूल रूप से क्या इवेंट आपको देता है, लेकिन एक गारंटीकृत कन्वेंशन (कंपाइलर द्वारा उत्पन्न और IL में अतिरिक्त झंडे द्वारा समर्थित) और एक "मुक्त" कार्यान्वयन के साथ यदि आप शब्दार्थ के साथ खुश हैं कि फ़ील्ड-जैसी ईवेंट आपको देते हैं। घटनाओं से सब्सक्राइब करना और अनसब्सक्राइब करना इवेंट हैंडलर की सूची में मनमानी पहुंच की अनुमति के बिना एनकैप्सुलेटेड है, और भाषाएं घोषणा और सदस्यता दोनों के लिए सिंटैक्स प्रदान करके चीजों को सरल बना सकती हैं।
public Delegate
चर "डेटा" को उजागर करेगा, लेकिन मेरे ज्ञान का सबसे अच्छा करने के लिए ओओपी ने कभी भी किसी अवधारणा का उल्लेख नहीं किया है जैसे कि Delegate
यह एक "वस्तु" या "संदेश" नहीं है) , और .NET वास्तव में मुश्किल से डेटा की तरह प्रतिनिधियों का व्यवहार करता है।
AddXXXHandler
साथ अपने तरीके बनाना private Delegate
एक अच्छा विकल्प हो सकता है। इस मामले में आप यह देख सकते हैं कि क्या हैंडलर पहले से सेट है, और उचित रूप से प्रतिक्रिया करें। यह भी एक अच्छा सेटअप हो सकता है यदि आपको Delegate
सभी हैंडलर को खाली करने में सक्षम होने के लिए ऑब्जेक्ट को रखने की आवश्यकता है ( event
आपको ऐसा करने का कोई तरीका नहीं देता है)।
नोट: यदि आपके पास C # 5.0 तक पहुंच है , तो दोनों के बीच के अंतरों को समझने के लिए "ईवेंट्स ऑफ प्लेज यूज ऑफ डेलिगेट्स" अध्याय 18 में "इवेंट्स" को पढ़ें।
यह हमेशा मुझे एक सरल, ठोस उदाहरण देने में मदद करता है। तो यहाँ समुदाय के लिए एक है। पहले मैं दिखाता हूं कि आप हमारे लिए ईवेंट्स का उपयोग करने के लिए अकेले प्रतिनिधियों का उपयोग कैसे कर सकते हैं। फिर मैं बताता हूं कि एक ही समाधान किस तरह के उदाहरण के साथ काम करेगा EventHandler
। और फिर मैं समझाता हूं कि हम ऐसा क्यों करना चाहते हैं जो मैं पहले उदाहरण में समझाता हूं। यह पोस्ट जॉन स्कीट के एक लेख से प्रेरित थी ।
उदाहरण 1: सार्वजनिक प्रतिनिधि का उपयोग करना
मान लीजिए कि मेरे पास एक एकल ड्रॉप-डाउन बॉक्स के साथ एक WinForms ऐप है। ड्रॉप डाउन एक के लिए बाध्य है List<Person>
। जहाँ व्यक्ति के पास Id, Name, NickName, HairColor के गुण हैं। मुख्य रूप पर एक कस्टम उपयोगकर्ता नियंत्रण है जो उस व्यक्ति के गुणों को दर्शाता है। जब कोई व्यक्ति चुने हुए व्यक्ति के गुणों को दिखाने के लिए उपयोगकर्ता नियंत्रण अद्यतन में ड्रॉप-डाउन में किसी व्यक्ति का चयन करता है।
यहाँ है कि कैसे काम करता है। हमारे पास तीन फाइलें हैं जो हमें इसे एक साथ रखने में मदद करती हैं:
यहाँ प्रत्येक वर्ग के लिए प्रासंगिक कोड दिया गया है:
class Mediator
{
public delegate void PersonChangedDelegate(Person p); //delegate type definition
public static PersonChangedDelegate PersonChangedDel; //delegate instance. Detail view will "subscribe" to this.
public static void OnPersonChanged(Person p) //Form1 will call this when the drop-down changes.
{
if (PersonChangedDel != null)
{
PersonChangedDel(p);
}
}
}
यहाँ हमारा उपयोगकर्ता नियंत्रण है:
public partial class DetailView : UserControl
{
public DetailView()
{
InitializeComponent();
Mediator.PersonChangedDel += DetailView_PersonChanged;
}
void DetailView_PersonChanged(Person p)
{
BindData(p);
}
public void BindData(Person p)
{
lblPersonHairColor.Text = p.HairColor;
lblPersonId.Text = p.IdPerson.ToString();
lblPersonName.Text = p.Name;
lblPersonNickName.Text = p.NickName;
}
}
अंत में हमारे Form1.cs में निम्न कोड है। यहां हम OnPersonChanged को कॉल कर रहे हैं, जो प्रतिनिधि को सब्सक्राइब किए गए किसी भी कोड को कॉल करता है।
private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
{
Mediator.OnPersonChanged((Person)comboBox1.SelectedItem); //Call the mediator's OnPersonChanged method. This will in turn call all the methods assigned (i.e. subscribed to) to the delegate -- in this case `DetailView_PersonChanged`.
}
ठीक है। तो यह है कि आप घटनाओं का उपयोग किए बिना और केवल प्रतिनिधियों का उपयोग किए बिना यह काम कैसे प्राप्त करेंगे । हम सिर्फ एक सार्वजनिक प्रतिनिधि को एक वर्ग में रखते हैं - आप इसे स्थिर या एक सिंगलटन या जो कुछ भी बना सकते हैं। महान।
लेकिन, BUT, लेकिन, हम वही नहीं करना चाहते हैं जो मैंने अभी ऊपर वर्णित किया है। क्योंकि सार्वजनिक क्षेत्र कई, कई कारणों से खराब हैं । तो हमारे विकल्प क्या हैं? जैसा कि जॉन स्कीट बताते हैं, यहां हमारे विकल्प हैं:
PersonChangedDel = null
से अन्य सभी सदस्यता को मिटा सकते हैं।) अन्य समस्या जो यहां बनी हुई है वह यह है कि चूंकि उपयोगकर्ताओं के पास प्रतिनिधि के पास पहुंच है, इसलिए वे मंगलाचरण सूची में लक्ष्यों को प्राप्त कर सकते हैं - हम नहीं चाहते कि बाहरी उपयोगकर्ता हमारे घटनाओं को बढ़ाएं।यह तीसरा विकल्प अनिवार्य रूप से एक घटना है जो हमें देता है। जब हम एक EventHandler घोषित करते हैं, तो यह हमें एक प्रतिनिधि के लिए पहुंच प्रदान करता है - सार्वजनिक रूप से नहीं, एक संपत्ति के रूप में नहीं, लेकिन इस चीज के रूप में हम एक घटना को कहते हैं जिसमें एक्सेसर्स को सिर्फ जोड़ना / निकालना है।
आइए देखें कि वही कार्यक्रम कैसा दिखता है, लेकिन अब सार्वजनिक प्रतिनिधि के बजाय एक ईवेंट का उपयोग कर रहा हूं (मैंने अपने मध्यस्थ को एक गायिका में बदल दिया है):
उदाहरण 2: एक सार्वजनिक प्रतिनिधि के बजाय EventHandler के साथ
मध्यस्थ:
class Mediator
{
private static readonly Mediator _Instance = new Mediator();
private Mediator() { }
public static Mediator GetInstance()
{
return _Instance;
}
public event EventHandler<PersonChangedEventArgs> PersonChanged; //this is just a property we expose to add items to the delegate.
public void OnPersonChanged(object sender, Person p)
{
var personChangedDelegate = PersonChanged as EventHandler<PersonChangedEventArgs>;
if (personChangedDelegate != null)
{
personChangedDelegate(sender, new PersonChangedEventArgs() { Person = p });
}
}
}
ध्यान दें कि यदि आप EventHandler पर F12 करते हैं, तो यह आपको दिखाएगा कि परिभाषा अतिरिक्त "प्रेषक" ऑब्जेक्ट के साथ एक सामान्य-ified प्रतिनिधि है:
public delegate void EventHandler<TEventArgs>(object sender, TEventArgs e);
उपयोगकर्ता नियंत्रण:
public partial class DetailView : UserControl
{
public DetailView()
{
InitializeComponent();
Mediator.GetInstance().PersonChanged += DetailView_PersonChanged;
}
void DetailView_PersonChanged(object sender, PersonChangedEventArgs e)
{
BindData(e.Person);
}
public void BindData(Person p)
{
lblPersonHairColor.Text = p.HairColor;
lblPersonId.Text = p.IdPerson.ToString();
lblPersonName.Text = p.Name;
lblPersonNickName.Text = p.NickName;
}
}
अंत में, यहाँ Form1.cs कोड है:
private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
{
Mediator.GetInstance().OnPersonChanged(this, (Person)comboBox1.SelectedItem);
}
क्योंकि EventHandler चाहता है और EventArgs एक पैरामीटर के रूप में, मैंने इस वर्ग को सिर्फ एक संपत्ति के साथ बनाया है:
class PersonChangedEventArgs
{
public Person Person { get; set; }
}
उम्मीद है कि आपको थोड़ा सा पता चलता है कि हमारे पास घटनाएँ क्यों हैं और वे कैसे भिन्न हैं - लेकिन कार्यात्मक रूप से समान हैं - प्रतिनिधियों के रूप में।
The other problem that remains here is that since the users have access to the delegate, they can invoke the targets in the invocation list -- we don't want external users having access to when to raise our events
। के नवीनतम संस्करण में Mediator
, आप अभी भी कॉल कर सकते हैं OnPersonChange
जब भी आपके पास सिंगलटन का संदर्भ हो। शायद आपको यह उल्लेख करना चाहिए कि Mediator
दृष्टिकोण उस विशेष व्यवहार को नहीं रोकता है, और एक घटना बस के करीब है।
आप इंटरफ़ेस घोषणाओं में घटनाओं का भी उपयोग कर सकते हैं, प्रतिनिधियों के लिए ऐसा नहीं है।
Action a { get; set; }
एक इंटरफ़ेस परिभाषा के अंदर हो सकते हैं ।
घटनाओं और प्रतिनिधियों के बीच एक बड़ी गलतफहमी क्या है !!! एक प्रतिनिधि एक TYPE निर्दिष्ट करता है (जैसे एक class
, या एक interface
करता है), जबकि एक घटना केवल एक प्रकार की प्रोफ़ाइल है (जैसे फ़ील्ड, गुण, आदि)। और, किसी अन्य सदस्य की तरह एक घटना भी एक प्रकार की होती है। फिर भी, किसी घटना के मामले में, एक प्रतिनिधि द्वारा घटना के प्रकार को निर्दिष्ट किया जाना चाहिए। उदाहरण के लिए, आप इंटरफ़ेस द्वारा परिभाषित एक प्रकार की एक घटना को घोषित नहीं कर सकते।
समापन, हम निम्नलिखित अवलोकन कर सकते हैं : एक प्रतिनिधि द्वारा परिभाषित किया जाना चाहिए एक घटना के प्रकार । यह एक घटना और एक प्रतिनिधि के बीच मुख्य संबंध है और खंड II.18 में ECMA-335 (CLI) विभाजन I से VI तक की घटनाओं को परिभाषित करते हुए वर्णित है :
विशिष्ट उपयोग में, टाइपस्पीक (यदि मौजूद है) एक प्रतिनिधि को पहचानता है जिसके हस्ताक्षर घटना की अग्नि विधि में पारित तर्कों से मेल खाते हैं।
हालाँकि, इस तथ्य का यह मतलब नहीं है कि एक घटना एक बैकिंग प्रतिनिधि क्षेत्र का उपयोग करती है । सच में, एक घटना आपकी पसंद के किसी भी अलग डेटा संरचना के समर्थन क्षेत्र का उपयोग कर सकती है। यदि आप C # में किसी घटना को स्पष्ट रूप से कार्यान्वित करते हैं, तो आप ईवेंट हैंडलर को स्टोर करने के तरीके को चुनने के लिए स्वतंत्र हैं (ध्यान दें कि ईवेंट हैंडलर घटना के प्रकार के उदाहरण हैं , जो बदले में अनिवार्य रूप से एक प्रतिनिधि प्रकार है --- पिछले अवलोकन से --- )। लेकिन, आप उन ईवेंट हैंडलर (जो प्रतिनिधि उदाहरण हैं) को डेटा संरचना में संग्रहीत कर सकते हैं जैसे कि List
या एक Dictionary
या किसी अन्य या किसी बैकिंग प्रतिनिधि क्षेत्र में भी। लेकिन यह मत भूलो कि यह अनिवार्य नहीं है कि आप एक प्रतिनिधि क्षेत्र का उपयोग करें।
एक .net में एक घटना ऐड विधि और एक निकालें विधि का एक निर्दिष्ट संयोजन है, जिसमें दोनों कुछ विशेष प्रकार के प्रतिनिधि की अपेक्षा करते हैं। C # और vb.net दोनों ऐड और रिमूव तरीकों के लिए कोड को ऑटो-जनरेट कर सकते हैं, जो इवेंट सब्सक्रिप्शन को होल्ड करने के लिए एक प्रतिनिधि को परिभाषित करेगा, और उस सब्सक्रिप्शन डेलिगेट से / में डेलीगेट में पास / ऐड को हटा देगा। VB.net सदस्यता सूची के साथ स्वतः उत्पन्न कोड (RaiseEvent स्टेटमेंट के साथ) होगा यदि और केवल अगर यह गैर-रिक्त है; किसी कारण के लिए, सी # बाद उत्पन्न नहीं करता है।
ध्यान दें कि जबकि मल्टीकास्ट डेलीगेट का उपयोग करके इवेंट सब्सक्रिप्शन को प्रबंधित करना आम है, ऐसा करने का एकमात्र साधन नहीं है। सार्वजनिक दृष्टिकोण से, एक-टू-इवेंट ईवेंट सब्सक्राइबर को यह जानने की आवश्यकता है कि किसी ऑब्जेक्ट को यह कैसे पता होना चाहिए कि वह ईवेंट प्राप्त करना चाहता है, लेकिन यह जानने की आवश्यकता नहीं है कि ईवेंट को ऊपर उठाने के लिए प्रकाशक किस तंत्र का उपयोग करेगा। यह भी ध्यान दें कि जिसने भी .net में डेटा संरचना को परिभाषित किया है, उसने स्पष्ट रूप से सोचा था कि उन्हें बढ़ाने का एक सार्वजनिक साधन होना चाहिए, न तो C # और न ही vb.net उस सुविधा का उपयोग करता है।
सरल तरीके से घटना के बारे में परिभाषित करने के लिए:
घटना दो प्रतिबंधों के साथ एक प्रतिनिधि के लिए एक संदर्भ है
दो से ऊपर प्रतिनिधियों के लिए कमजोर बिंदु हैं और यह घटना में संबोधित किया गया है। फिडलर में अंतर दिखाने के लिए पूरा कोड नमूना यहाँ है https://dotnetfiddle.net/5iR3fB ।
ईवेंट और डेलिगेट और क्लाइंट कोड के बीच की टिप्पणी को टॉगल करें जो अंतर को समझने के लिए प्रतिनिधि को आमंत्रित / असाइन करता है
यहाँ इनलाइन कोड है।
/*
This is working program in Visual Studio. It is not running in fiddler because of infinite loop in code.
This code demonstrates the difference between event and delegate
Event is an delegate reference with two restrictions for increased protection
1. Cannot be invoked directly
2. Cannot assign value to delegate reference directly
Toggle between Event vs Delegate in the code by commenting/un commenting the relevant lines
*/
public class RoomTemperatureController
{
private int _roomTemperature = 25;//Default/Starting room Temperature
private bool _isAirConditionTurnedOn = false;//Default AC is Off
private bool _isHeatTurnedOn = false;//Default Heat is Off
private bool _tempSimulator = false;
public delegate void OnRoomTemperatureChange(int roomTemperature); //OnRoomTemperatureChange is a type of Delegate (Check next line for proof)
// public OnRoomTemperatureChange WhenRoomTemperatureChange;// { get; set; }//Exposing the delegate to outside world, cannot directly expose the delegate (line above),
public event OnRoomTemperatureChange WhenRoomTemperatureChange;// { get; set; }//Exposing the delegate to outside world, cannot directly expose the delegate (line above),
public RoomTemperatureController()
{
WhenRoomTemperatureChange += InternalRoomTemperatuerHandler;
}
private void InternalRoomTemperatuerHandler(int roomTemp)
{
System.Console.WriteLine("Internal Room Temperature Handler - Mandatory to handle/ Should not be removed by external consumer of ths class: Note, if it is delegate this can be removed, if event cannot be removed");
}
//User cannot directly asign values to delegate (e.g. roomTempControllerObj.OnRoomTemperatureChange = delegateMethod (System will throw error)
public bool TurnRoomTeperatureSimulator
{
set
{
_tempSimulator = value;
if (value)
{
SimulateRoomTemperature(); //Turn on Simulator
}
}
get { return _tempSimulator; }
}
public void TurnAirCondition(bool val)
{
_isAirConditionTurnedOn = val;
_isHeatTurnedOn = !val;//Binary switch If Heat is ON - AC will turned off automatically (binary)
System.Console.WriteLine("Aircondition :" + _isAirConditionTurnedOn);
System.Console.WriteLine("Heat :" + _isHeatTurnedOn);
}
public void TurnHeat(bool val)
{
_isHeatTurnedOn = val;
_isAirConditionTurnedOn = !val;//Binary switch If Heat is ON - AC will turned off automatically (binary)
System.Console.WriteLine("Aircondition :" + _isAirConditionTurnedOn);
System.Console.WriteLine("Heat :" + _isHeatTurnedOn);
}
public async void SimulateRoomTemperature()
{
while (_tempSimulator)
{
if (_isAirConditionTurnedOn)
_roomTemperature--;//Decrease Room Temperature if AC is turned On
if (_isHeatTurnedOn)
_roomTemperature++;//Decrease Room Temperature if AC is turned On
System.Console.WriteLine("Temperature :" + _roomTemperature);
if (WhenRoomTemperatureChange != null)
WhenRoomTemperatureChange(_roomTemperature);
System.Threading.Thread.Sleep(500);//Every second Temperature changes based on AC/Heat Status
}
}
}
public class MySweetHome
{
RoomTemperatureController roomController = null;
public MySweetHome()
{
roomController = new RoomTemperatureController();
roomController.WhenRoomTemperatureChange += TurnHeatOrACBasedOnTemp;
//roomController.WhenRoomTemperatureChange = null; //Setting NULL to delegate reference is possible where as for Event it is not possible.
//roomController.WhenRoomTemperatureChange.DynamicInvoke();//Dynamic Invoke is possible for Delgate and not possible with Event
roomController.SimulateRoomTemperature();
System.Threading.Thread.Sleep(5000);
roomController.TurnAirCondition (true);
roomController.TurnRoomTeperatureSimulator = true;
}
public void TurnHeatOrACBasedOnTemp(int temp)
{
if (temp >= 30)
roomController.TurnAirCondition(true);
if (temp <= 15)
roomController.TurnHeat(true);
}
public static void Main(string []args)
{
MySweetHome home = new MySweetHome();
}
}
डेलिगेट एक प्रकार-सुरक्षित फ़ंक्शन पॉइंटर है। ईवेंट प्रतिनिधि का उपयोग करके प्रकाशक-ग्राहक डिज़ाइन पैटर्न का कार्यान्वयन है।
यदि आप इंटरमीडिएट भाषा की जांच करते हैं, तो आपको पता चल जाएगा कि .net कंपाइलर IL में सीलबंद क्लास को कुछ बिल्ड-इन फंक्शंस के साथ इन्वॉल्व करता है, जैसे कि इनवोक, startInvoke, endInvoke और डेलीगेट क्लास दूसरी क्लास से विरासत में मिला है, जिसे शायद "SystemMulticast" कहा जाता है। मुझे लगता है कि इवेंट कुछ अतिरिक्त गुणों के साथ डेलिगेट का एक बच्चा वर्ग है।
घटना और प्रतिनिधि के बीच अंतर है, आप घोषणा के बाहर घटना नहीं चला सकते हैं। यदि आप कक्षा A में किसी घटना की घोषणा करते हैं, तो आप केवल कक्षा A में इस घटना को चला सकते हैं। यदि आप कक्षा A में एक प्रतिनिधि की घोषणा करते हैं, तो आप कहीं भी इस प्रतिनिधि का उपयोग कर सकते हैं। मुझे लगता है कि यह उनके बीच एक मुख्य अंतर है