2011-01-31 18 views
7

MSDN से:सी # प्रतिनिधियों और विधि हस्ताक्षर

कोई भी पद्धति जो प्रतिनिधि के हस्ताक्षर, वापसी प्रकार और मापदंडों के होते हैं जो मेल खाता है, प्रतिनिधि को सौंपा जा सकता है।

तो यह कैसे संभव है:

public delegate void AlarmEventHandler(object sender, EventArgs e); 
public event AlarmEventHandler Alarm; 

protected virtual void OnAlarm(EventArgs e) 
     { 
      AlarmEventHandler handler = Alarm; 
      if (handler != null) 
      { 
       // Invokes the delegates. 
       handler(this, e); 
      } 
     } 

प्रतिनिधि AlarmEventHander और घटना AlarmEventHandler अलग हस्ताक्षर अभी तक handlerAlarm को सौंपा जा सकता है।

शायद मैं कुछ हद तक प्रतिनिधियों को गलत समझ रहा हूं, और अगर कोई समझा सकता है कि मैं कहां गलत हो रहा हूं तो मैं बहुत आभारी हूं।

+0

मुझे लगता है कि आपने अपने कुछ प्रतीक नामों को भ्रमित कर दिया है। उपर्युक्त कोड में, प्रतिनिधि को 'अलार्मइवेंट हैंडलर' कहा जाता है और घटना, जो एक ही प्रकार की है, को 'अलार्म' कहा जाता है। चूंकि वे एक ही प्रकार के हैं, असाइनमेंट में कोई समस्या नहीं है। मुझे लगता है कि भ्रमित करने वाला क्या है आप 'ऑन अलार्म' विधि है जो शायद एक अलग प्रतिनिधि प्रकार के साथ एक अलग घटना का जवाब देने के लिए दिखाई देता है। –

+0

देखें: फ़ील्ड जैसी घटनाएं। http://msdn.microsoft.com/en-us/library/aa664455(v=vs.71).aspx – Ani

+0

मुझे यहां समस्या दिखाई नहीं दे रही है। प्रकार बिल्कुल मेल खाते हैं (दोनों 'अलार्मइवेंट हैंडलर' हैं), इसलिए कोई एक दूसरे को असाइन करने में सक्षम होने की उम्मीद करेगा। – finnw

उत्तर

7

एक प्रतिनिधि एक वर्ग की तरह है। एक घटना एक संपत्ति की तरह है। जब आप किसी कक्षा में event घोषित करते हैं, तो आप टाइप ईवेंट की घोषणा करते हैं। इस मामले में, AlarmEventHandler, जो शीर्ष स्तर के वर्ग के आंतरिक वर्ग है, यह एक हिस्सा है।

OnAlarm विधि में, आपको AlarmEventHandler कक्षा का उदाहरण मिलता है जिसे ईवेंट को सौंपा गया है, और इसे आमंत्रित किया गया है।

स्पष्ट करने के लिए बातें, अपने कोड के ऊपर इस के समान है, सामान्य वर्गों & संदर्भों का उपयोग:

public class InnerClass { 
    public void MyMethod() { /* ... */ } 
} 

public InnerClass MyProperty { get; set; } 

protected virtual void CallMyMethod() { 
    InnerClass cls = MyProperty; 
    if (cls != null) 
     cls.MyMethod(); 
} 
+0

मुझे जिस तरह से आपने समझाया है उसे पसंद है। यह मुझे कल्पना करता है कि यह कैसे बेहतर काम करता है – Notter

2

वास्तव में हस्ताक्षर एक ही हैं। प्रतिनिधियों के साथ .NET कार्यक्रमों में लागू किया जाता है।

public event AlarmEventHandler Alarm; 

तो कोड ऊपर वास्तव में के रूप में संकलक द्वारा संकलित किया गया है:

private AlarmEventHandler handler; 

public event AlarmEventHandler Alarm 
{ 
    add { handler += value; } 
    remove { handler -= value; } 
} 

तो घटना वास्तव में एक ही AlarmEventHandler प्रतिनिधि उपयोग करता है।

0
  1. आप प्रतिनिधि और घटनाओं को मिश्रित कर रहे हैं। हालांकि कार्यक्रम प्रतिनिधियों पर निर्भर हैं, वे पूरी तरह से अंतर अवधारणाएं हैं। तो अलग से लिया जाना चाहिए।
  2. प्रतिनिधि प्रकार की परिभाषा की तरह है। जहां आप इस प्रतिनिधि का उपयोग करते हैं वह स्थान वैरिएबल या प्रॉपर्टी जैसा है।
  3. घटना इस प्रतिनिधि को बाहर से अलग व्यवहार करती है। हस्ताक्षर अभी भी वही है।
-3

एक फ़ंक्शन जो बेस-क्लास (गैर संदर्भ) पैरामीटर के रूप में लेता है उसे एक प्रतिनिधि में परिवर्तित किया जा सकता है जो व्युत्पन्न कक्षा को पैरामीटर के रूप में लेता है। ऐसा इसलिए है क्योंकि आधार जो कार्य लेता है उसे सुरक्षित रूप से प्रतिस्थापित किया जा सकता है, जहां कभी भी एक व्युत्पन्न कक्षा ले जाने वाला एक फ़ंक्शन उपयोग किया जाता है।

void TakesObject(object o) 
{ 
... 
} 

Action<string> myAction=TakesObject; 

आप केवल एक स्ट्रिंग में गुजरकर myAction को कॉल कर सकते हैं। और चूंकि प्रत्येक स्ट्रिंग एक वस्तु है क्योंकि TakesObject के लिए अनुबंध पूरा हो गया है।

आपके मामले में काम करता है क्योंकि प्रत्येक AlarmEventArgs एक EventArgs भी है।तो आपके ईवेंटहैंडर की अनुबंध आवश्यकताओं घटना द्वारा उपयोग किए जाने वाले प्रतिनिधि प्रकार की अनुबंध गारंटी से कम सख्त हैं।

इसे सह-और अनुबंध-भिन्नता कहा जाता है। आपके पास रिटर्न-प्रकारों में सह-भिन्नता है, और पैरामीटर में कॉन्ट्रैक्ट भिन्नता है।

चेक MSDN पर इस लेख:
Using Variance in Delegates (C# and Visual Basic)

0

एक घटना सिर्फ एक प्रतिनिधि है। प्रतिनिधि के हेल्फ़्ट को केवल कक्षा के अंदर से ही पहुंचा जा सकता है। बाहर से, केवल जोड़ने और हटाने घटना के लिए कार्यक्षमता संभव है करने के लिए आप केवल यह कर सकते हैं:

myAlarm.Alarm+=new AlarmEventHandler(callPolice); 
// or 
myAlarm.Alarm-=new AlarmEventHandler(callPolice); 

लेकिन कक्षा के अंदर से, अलार्म बस प्रकार AlarmEventHandler के एक प्रतिनिधि तो है आप अपना कोड दिखा सकते हैं:

 AlarmEventHandler handler = Alarm; 
     if (handler != null) 
     { 
      // Invokes the delegates. 
      handler(this, e); 
     } 
संबंधित मुद्दे