2009-07-14 11 views
18

वर्चुअल इवेंट कैसे काम करता है? आप इसे कैसे ओवरराइड करेंगे? यह कैसे काम करेगा? और आप किस मामले में ऐसा करेंगे?सी #: आभासी घटनाएं क्या हैं और उनका उपयोग कैसे किया जा सकता है?

उदाहरण के लिए यह संरक्षित OnEvent विधियों के लिए एक ठीक प्रतिस्थापन होगा? इसलिए विरासत कक्षाएं सिर्फ घटना को ओवरराइड कर सकती हैं और इसे सीधे बढ़ा सकती हैं? या यह गलत होगा या काम नहीं करेगा?

MSDN इसके बारे में इस का कहना है:

एक घटना आभासी कीवर्ड का उपयोग करके एक आभासी घटना के रूप में चिह्नित किया जा सकता है। यह ओवरराइड कीवर्ड का उपयोग करके ईवेंट व्यवहार को ओवरराइड करने के लिए व्युत्पन्न कक्षाओं को सक्षम बनाता है। वर्चुअल इवेंट को ओवरराइड करने वाली एक घटना को भी सील कर दिया जा सकता है, जो निर्दिष्ट करता है कि व्युत्पन्न कक्षाओं के लिए यह अब वर्चुअल नहीं है।

लेकिन इससे मुझे ज्यादा बुद्धिमान नहीं बनाया गया। मुहरबंद सामान हालांकि स्पष्ट है।

नोट: मैं How virtual events work in C# ? सवाल देखा है, लेकिन यह वास्तव में के बारे में कैसे आभासी घटनाओं काम नहीं था। इसके बजाए उस व्यक्ति को वह परिणाम मिला जो उन्हें इस्तेमाल करने से मिला। यह पता लगाने की कोशिश की कि आभासी घटनाएं उनके उदाहरण और उत्तरों से क्या थीं, लेकिन वास्तव में इसका अर्थ नहीं निकल सका।

+0

आलेख "सी # में वर्चुअल इवेंट्स: कुछ गलत हो गया" - http://www.viva64.com/en/b/0453/ –

उत्तर

23

एक आभासी घटना केवल एक है जो व्युत्पन्न कक्षा में ओवरराइड हो सकती है।

आप एक आभासी संपत्ति की अवधारणा के साथ खुश एक गेटर और सेटर जो अधिरोहित जा सकता है के साथ कर रहे हैं? यदि ऐसा है, तो आप एक वर्चुअल इवेंट के बारे में सोच सकते हैं: गेटटर और सेटर के बजाय, एक "एड" ऑपरेशन और "निकालें" ऑपरेशन है। ये आभासी हो सकते हैं, इसलिए polymorphically संभाला। आप उन्हें उसी तरह लागू करते हैं जैसे आप किसी अन्य आभासी/ओवरराइड सदस्य को लागू करते हैं।

उदाहरण:

using System; 

class Base 
{ 
    public virtual event EventHandler Foo 
    { 
     add 
     { 
      Console.WriteLine("Base Foo.add called"); 
     } 
     remove 
     { 
      Console.WriteLine("Base Foo.remove called"); 
     } 
    } 
} 

class Derived : Base 
{ 
    public override event EventHandler Foo 
    { 
     add 
     { 
      Console.WriteLine("Derived Foo.add called"); 
     } 
     remove 
     { 
      Console.WriteLine("Derived Foo.remove called"); 
     } 
    } 
} 

class Test 
{ 
    static void Main() 
    { 
     Base x = new Derived(); 

     x.Foo += (sender, args) => {}; 
    } 
} 

ध्यान दें कि घटना अपने आप में क्या होता है जब यह उठाया है के लिए जिम्मेदार नहीं है - बस जोड़ें/पक्ष को हटा दें। (सी # में, वैसे भी; सीएलआर में खुद को उठाने की धारणा है, लेकिन हम इस पल के लिए अनदेखा करेंगे।)

यदि आप किसी ईवेंट के बीच अंतर पर थोड़ा आलसी हैं तो आप my article on events पढ़ना भी चाहेंगे। एक प्रतिनिधि

व्यक्तिगत रूप से मुझे यह बहुत दुर्लभ लगता है कि मैं एक आभासी घटना चाहता हूं।

+0

यदि अभिभावक वर्ग ओवरराइड ईवेंट उठाता है, तो यह अभी भी वही घटना होगा, दाएं ? तो यदि आपके पास 'कक्षा ए' और 'कक्षा ए: बी' था, तो ग्राहक ए या बी के रूप में किए जाने पर दोनों ऑब्जेक्ट की उसी घटना की सदस्यता लेंगे? – Svish

+1

नहीं - उठाना पूरी तरह से अलग है। यदि कक्षा ए जोड़/निकालने को ओवरराइड करता है और कक्षा बी के जोड़/निकालने के लिए कॉल नहीं करता है, तो घटना को बढ़ाने के लिए कक्षा बी के तंत्र को बुलाया गया था, तो किसी भी हैंडलर को बुलाया नहीं जाएगा।सादे तरीकों के संदर्भ में सभी के बारे में सोचें - यह ईवेंट वर्चुअल हो सकता है जो जोड़/निकाला प्रदान करता है, लेकिन घटना को बढ़ाने के अर्थशास्त्र के बारे में कुछ भी निर्दिष्ट नहीं करता है। –

+0

तो इसके लिए ठीक से काम करने के लिए आपको base.add और base.remove या कुछ करना होगा? (यदि यह मौजूद है ...) – Svish

0

भी ध्यान रखें कि सी # में एक व्युत्पन्न वर्ग घटना विशुद्ध रूप से (कोई बात नहीं क्या संशोधक यह है) आधार वर्ग में परिभाषित आग करने में सक्षम नहीं है। तो हमें या तो व्युत्पन्न वर्ग के लिए एक नई या ओवरराइडिंग घटना की आवश्यकता है और ज्यादातर मामलों में एक ओवरराइडिंग को प्राथमिकता दी जाती है यदि एक ही घटना को निकाला जाना है।

+0

लेकिन इसे बेस क्लास में 'संरक्षित राइज ...' विधि बनाकर आसानी से हल किया जा सकता है और इसे व्युत्पन्न कक्षा से कॉल किया जा सकता है। – MarioDS

संबंधित मुद्दे

 संबंधित मुद्दे