2010-09-02 12 views
6

मान लें कि मेरे पास एक वर्ग (ClassA) है जिसमें एक विधि है जो किसी अन्य वर्ग के निर्माता को कॉल करती है, जैसे:अप्रयुक्त रचनाकारों में मुझे संदर्भों को संदर्भित करने के लिए क्यों मजबूर किया गया है?

public class ClassA 
{ 
    public void CallClassBConstructor() 
    { 
     using(ClassB myB = new ClassB()) {...} 
    } 
} 

कक्षा ClassB इस तरह दिखता है:

public class ClassB : IDisposable 
{ 
    public ClassB(){} 
    public ClassB(string myString){} 
    public ClassB(ClassC myC){} 
    public void Dispose() {...} 
} 

... और ClassC और भी सरल है:

public class ClassC{} 

अगर मैं इन वर्गों को अपनी असेंबली में डालता हूं और पूरे समाधान को संकलित करता हूं तो मुझे कोई त्रुटि नहीं मिलती है। लेकिन अगर मैं इसके साथ उपयोग कथन को प्रतिस्थापित करता हूं:

using(ClassB myB = new ClassB("mystring")){...} 

मुझे ClassA में [mynamespace].ClassC का संदर्भ जोड़ने के लिए एक संकलन त्रुटि मिलती है। चूंकि मैं ClassB(ClassC myC) को कॉल नहीं कर रहा हूं, इस पर मुझे कोई समझ नहीं आता - मुझे अन्य रचनाकारों के प्रकारों को शामिल क्यों करना है चाहे मैं उनका उपयोग करता हूं या नहीं? क्या होगा यदि ClassC को लाइसेंस प्राप्त या हार्ड-टू-एक्वायर असेंबली में शामिल किया गया हो? क्या यह खराब डिजाइन का एक उदाहरण है कि डेवलपर्स से बचना चाहिए या क्या मुझे यहां कुछ याद आ रहा है?

+3

यह पहली जगह संकलित नहीं हो सकता है, क्लासबी IDISposable लागू नहीं करता है। फिर इसका उपयोग किसी खंड में नहीं किया जा सकता है। –

+0

यह सी/सी ++ नहीं है जहां खंडकर्ता द्वारा अनुभागों को gc'd किया गया है, जहां अमान्य अप्रयुक्त कोड चुपचाप अनदेखा किया जाएगा। – leppie

+0

मैंने कोड संपादित किया ताकि इसे संकलित करना चाहिए –

उत्तर

9

ClassB कन्स्ट्रक्टर को कॉल करते समय इसे विधि अधिभार रिज़ॉल्यूशन के साथ करना होगा।

जब आप कोई पैरामीटर के साथ कन्स्ट्रक्टर को कॉल करते हैं, तो कोई विवाद नहीं होता है। केवल एक उम्मीदवार है, इसलिए इसे चुना जाता है। इस मामले में ClassC को संदर्भित करने के लिए ClassA के लिए आवश्यक नहीं है।

हालांकि, जब आप एक पैरामीटर के साथ कन्स्ट्रक्टर को कॉल करते हैं, तो शुरुआत में दोनों सिंगल-पैरामीटर कन्स्ट्रक्टर उम्मीदवार होते हैं। इस कॉल को हल करने के लिए, कंपाइलर को ClassC के बारे में पता होना चाहिए। आप सभी के लिए, ClassC में एक निहित रूपांतरण ऑपरेटर हो सकता है, उदाहरण के लिए।

(बेशक हम जानते हैं कि इस विशेष उदाहरण में इस तरह का एक निहित रूपांतरण ऑपरेटर किसी भी तरह से आग नहीं लगाएगा क्योंकि स्ट्रिंग लेने वाला एक आदर्श मैच है - लेकिन विधि अधिभार रिज़ॉल्यूशन नियमों को इस तरह से परिभाषित किया जाता है ताकि उन्हें बहुत अच्छी तरह से बनाया जा सके। - परिभाषित और अनुमानित। कल्पना कीजिए कि इस तरह से डिज़ाइन किया गया था कि संदर्भ जोड़ने से आपका कोड अचानक एक अलग कन्स्ट्रक्टर ओवरलोड को कॉल कर सकता है।)

+0

धन्यवाद टिमवी, मुझे लगता है कि सभी उत्तरों ने मुझे यह स्पष्ट किया है :-) –

+0

कैसे एक लापता 'उपयोग' कथन आओ संकलक के लिए पर्याप्त अधिभार जानने के लिए पर्याप्त नहीं है? मैं उलझन में हूं कि संदर्भ जोड़ने से संकलक खुश हो जाता है। – Stijn

+0

@Stijn: आप शायद ['उपयोग 'निर्देश] (http://msdn.microsoft.com/en-us/library/sf0df423.aspx) का मतलब है, * नहीं * [' कथन का उपयोग]] (http://msdn.microsoft.com/en-us/library/yh598w02.aspx)। लेकिन फिर भी, न तो प्रश्न और न ही मेरे उत्तर का उपयोग 'कथन' * या * 'उपयोग 'निर्देशों के साथ करने के लिए कुछ भी है। वे [अन्य असेंबली के संदर्भ] हैं [http://msdn.microsoft.com/en-us/library/wkze6zky%28v=vs.80%29.aspx)। 'उपयोग' घोषणा इस तरह के एक संदर्भ नहीं जोड़ती है। – Timwi

1

कन्स्ट्रक्टर ओवरलोड को हल करने के लिए, कंपाइलर को शामिल प्रकारों को जानने की आवश्यकता है। अर्थात। ClassB के लिए सही कन्स्ट्रक्टर ओवरलोड चुनने के लिए इसे ClassC जानने की आवश्यकता है।

+0

आपके उत्तर ब्रायन के लिए धन्यवाद - यह अन्य उत्तरों के साथ अच्छी तरह से सहमत है –

1

ऐसा इसलिए है क्योंकि ClassC, जिसे आपने एक अलग असेंबली में रखा है, ClassB के सार्वजनिक इंटरफेस का हिस्सा है क्योंकि यह रचनाकारों में से एक का पैरामीटर है। आपको इस प्रकार की असेंबली असेंबली का संदर्भ देना होगा अन्यथा संकलक को यह नहीं पता कि प्रकार की जानकारी को कैसे हल किया जाए। इस विशिष्ट मामले में कंपाइलर को सभी कन्स्ट्रक्टर ओवरलोड से सभी पैरामीटर प्रकारों को हल करना होगा ताकि यह सही चुन सकें, लेकिन यह प्रति सदस्य ओवरलोडिंग समस्या नहीं है। ऐसा तब होता है जब संकलक को प्रकार की जानकारी को हल करना होगा। यह रिटर्न प्रकारों पर भी हो सकता है।

+0

डाउनवोट क्यों? मेरे संपादन से पहले भी यह जवाब गलत नहीं था। –

+0

मुझे खेद है कि मैं स्टैक ओवरफ्लो पर नया हूं लेकिन मैंने कुछ भी क्लिक नहीं किया, बस पृष्ठ को पुनः लोड किया। शायद यही कारण है कि इसे कम किया गया था? –

+0

@ बुशशंका: नहीं, यह कुछ भी नहीं था जो आपने किया था। किसी ने सोचा कि यह जवाब उपयोगी से गलत या अधिक हानिकारक था। मैं अपने जवाब के पीछे खड़ा हूँ। –