2012-07-04 12 views
6

मैं एक कन्स्ट्रक्टर में वर्चुअल सदस्य को कॉल करने के प्रभावों का परीक्षण कर रहा था, और पाया कि उस सदस्य को कॉल करते समय परिणामस्वरूप अपवाद TargetInvocationException के भीतर लपेटा गया था।आभासी सदस्यों को प्रतिबिंब (सामान्य परिस्थितियों में) के माध्यम से बुलाया जाता है?

docs के अनुसार यह है:

अपवाद है कि प्रतिबिंब

के माध्यम से लागू तरीकों से फेंक दिया जाता है फिर भी मैं प्रतिबिंब के माध्यम से किसी भी invokations से अनभिज्ञ हूं। तो क्या यह का मतलब है आभासी सदस्यों को हमेशा प्रतिबिंब के माध्यम से बुलाया जाता है? यदि ऐसा नहीं है तो इस मामले में ऐसा क्यों है?

कोड:

class ClassA 
    { 
     public ClassA() 
     { 
      SplitTheWords(); 
     } 

     public virtual void SplitTheWords() 
     { 
      //I've been overidden 
     } 
    } 

class ClassB : ClassA 
    { 
     private readonly String _output; 

     public ClassB() 
     { 
      _output = "Constructor has occured"; 
     } 

     public override void SplitTheWords() 
     { 
      String[] something = _output.Split(new[]{' '}); //TargetInvocationException! 
     } 
    } 

उत्तर

5

नहीं, वर्चुअल विधियों को virtual dispatch के माध्यम से बुलाया जाता है।

प्रतिबिंब का उपयोग यहां नहीं किया जा रहा है। और न ही यह किसी वर्चुअल विधि कॉल के लिए है। मेरा मानना ​​है कि इस प्रकार के अपवादों के अपवाद के लिए प्रलेखन थोड़ा भ्रामक है प्रतिबिंब के माध्यम से लागू विधियों द्वारा फेंक दिया गया है, हालांकि विशेष रूप से ऐसा नहीं है।

यदि कोई इस बात का उत्सुक है कि प्रश्न में कोड अपवाद क्यों देता है, तो यह उस क्रम के कारण होता है जिसमें रचनाकारों को निष्पादित किया जाता है।

public ClassB() : base() 
{ 
    _output = "Constructor has occured"; 
} 

नोट base() करने के लिए कॉल, इस आधार निर्माता कॉल से पहले ClassB निर्माता चलाया जाता है और, इसलिए, _output से पहले असाइन किया गया है: ClassB निर्माता एक ही रूप है। SplitTheWords वर्चुअल विधि को बेस कन्स्ट्रक्टर में बुलाया जाता है, जो ClassB.SplitTheWords को हल करता है। यह विधि _output का उपयोग करने का प्रयास करती है, इसलिए त्रुटि।

रचनाकारों से वर्चुअल विधियों को क्यों नहीं कहा जाना चाहिए this SO question में कुछ उपयोगी जानकारी क्यों है। एरिक लिपर्ट का भी एक बहुत अच्छा ब्लॉग पोस्ट है, यह मामला here क्यों है।

+1

+1 "थोड़ा भ्रामक" के लिए +1, यह दस्तावेज़ों के कहने के लिए एक गहरी भ्रमित चीज है। कोई एक कंसोल ऐप लिख सकता है जिसने 'नया लक्ष्य इनवोकेशन अपवाद();' को छोड़कर कुछ भी नहीं किया; '- फिर प्रतिबिंब कहां होगा? – AakashM

+0

मैं समझता हूं कि _why_ वर्चुअल सदस्यों को कन्स्ट्रक्टर से नहीं बुलाया जाना चाहिए, यही कारण है कि मुझे –

+0

@ m.edmondson Apologies को आजमाने की कोशिश की गई, मैं इसे 'मैं के प्रभावों का परीक्षण कर रहा था' के बारे में आपकी लाइन से समझ गया, मैं मेरे जवाब को संवेदना देने का इरादा नहीं था (लेकिन मुझे लगता है कि यह अब हो सकता है), मैंने केवल इस उत्तर को देखने वाले अन्य लोगों के लिए पूर्णता के लिए अंतिम कुछ पैराग्राफ शामिल किए हैं। मैं rephrase करने की कोशिश करेंगे। –

0

आभासी सदस्यों प्रतिबिंब के माध्यम से कहा जाता है (सामान्य परिस्थितियों में)?

नहीं।

न ही एक निर्माता से, तो कुछ और चल रहा है। यह कोड को आपके द्वारा दिखाए गए कोड को कॉल करने और अपवाद से स्टैक ट्रेस को देखने में मदद करेगा।

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