यह C # के एक्सटेंशन विधियों और उनके डिज़ाइन दर्शन के बारे में एक प्रश्न है, इसलिए मुझे लगता है कि इस प्रश्न का उत्तर देने का सबसे अच्छा तरीका विस्तार विधियों के उद्देश्य पर MSDN के प्रलेखन को उद्धृत करना है :
एक्सटेंशन विधियाँ आपको नए व्युत्पन्न प्रकार बनाने, पुन: जमा करने, या अन्यथा मूल प्रकार को संशोधित किए बिना मौजूदा प्रकारों में "जोड़ने" के लिए सक्षम बनाती हैं। विस्तार विधियाँ एक विशेष प्रकार की स्थैतिक विधि होती हैं, लेकिन इन्हें वैसा ही कहा जाता है जैसे कि वे विस्तारित प्रकार पर उदाहरण के तरीके थे। C #, F # और विज़ुअल बेसिक में लिखे क्लाइंट कोड के लिए, एक एक्सटेंशन विधि और वास्तव में एक प्रकार से परिभाषित विधियों को कॉल करने के बीच कोई स्पष्ट अंतर नहीं है।
...
सामान्य तौर पर, हम अनुशंसा करते हैं कि आप विस्तार विधियों को संयम से लागू करें और केवल जब आपको करना हो। जब भी संभव हो, एक मौजूदा प्रकार का विस्तार करने वाले ग्राहक कोड को मौजूदा प्रकार से प्राप्त एक नया प्रकार बनाकर ऐसा करना चाहिए। अधिक जानकारी के लिए, विरासत देखें।
एक्सटेंशन विधि का उपयोग करते समय एक प्रकार जिसका स्रोत कोड आप नहीं बदल सकते हैं, आप जोखिम चलाते हैं कि प्रकार के कार्यान्वयन में परिवर्तन से आपकी एक्सटेंशन विधि टूट जाएगी।
यदि आप किसी दिए गए प्रकार के विस्तार के तरीकों को लागू करते हैं, तो निम्न बिंदुओं को याद रखें:
- एक विस्तार विधि को कभी भी नहीं कहा जाएगा यदि उसके प्रकार में परिभाषित विधि के समान हस्ताक्षर हैं।
- एक्सटेंशन विधियों को नाम स्थान स्तर पर दायरे में लाया जाता है। उदाहरण के लिए, यदि आपके पास कई स्थिर वर्ग हैं जिनमें नामांकित एकल नाम स्थान में विस्तार विधियां हैं
Extensions
, तो वे सभी using Extensions;
निर्देश द्वारा दायरे में लाए जाएंगे ।
संक्षेप में, एक्सटेंशन विधियों को एक विशेष प्रकार के उदाहरण के तरीकों को जोड़ने के लिए डिज़ाइन किया गया है, तब भी जब डेवलपर्स सीधे ऐसा नहीं कर सकते। और क्योंकि उदाहरण विधियाँ हमेशा एक्सटेंशन विधियों को ओवरराइड करेंगी यदि मौजूद हैं (यदि इंस्टेंस विधि सिंटैक्स का उपयोग करके कहा जाता है), तो यह केवल तभी किया जाना चाहिए जब आप सीधे एक विधि नहीं जोड़ सकते हैं या क्लास का विस्तार कर सकते हैं। *
दूसरे शब्दों में, एक विस्तार विधि को एक आवृत्ति विधि की तरह कार्य करना चाहिए, क्योंकि यह अंत में कुछ क्लाइंट द्वारा एक इंस्टेंस विधि बनाया जा सकता है। और क्योंकि एक इंस्टेंस मेथड को फेंकना चाहिए यदि ऑब्जेक्ट जिस पर कॉल किया जा रहा है null
, वह है एक्सटेंशन विधि।
जब सी # 3.0 जारी किया गया था, वहाँ पहले से ही उपयोग कर रहे थे कि ग्राहकों के लाखों लोगों थे: * एक तरफ ध्यान दें के रूप में, यह वास्तव में स्थिति यह है कि LINQ के डिजाइनरों का सामना करना पड़ा है System.Collections.IEnumerable
और System.Collections.Generic.IEnumerable<T>
अपने संग्रह में और दोनों में, foreach
छोरों। इन कक्षाओं लौटे IEnumerator
जिन वस्तुओं पर केवल दो तरीकों था Current
और MoveNext
है, इसलिए इस तरह के रूप में किसी भी अतिरिक्त आवश्यकता उदाहरण के तरीकों, जोड़ने Count
, Any
आदि, ग्राहकों के इन लाखों लोगों को तोड़ने की जाएगी। इसलिए, यह कार्यक्षमता प्रदान करने के लिए (विशेषकर जब से इसे Current
और MoveNext
रिश्तेदार आसानी से लागू किया जा सकता है), उन्होंने इसे विस्तार विधियों के रूप में जारी किया, जिसे वर्तमान में किसी भी लागू किया जा सकता है।IEnumerable
उदाहरण और अधिक कुशल तरीकों से कक्षाओं द्वारा भी लागू किया जा सकता है। अगर C # के डिजाइनरों ने पहले दिन LINQ जारी करने का निर्णय लिया होता, तो यह उदाहरण के तरीकों के रूप में प्रदान किया गया होता IEnumerable
, और संभवत: उन्होंने उन तरीकों के डिफ़ॉल्ट इंटरफ़ेस कार्यान्वयन प्रदान करने के लिए किसी प्रकार की प्रणाली को डिज़ाइन किया होता।