विस्तार विधि: Difference between revisions

From Vigyanwiki
No edit summary
No edit summary
Line 6: Line 6:


== क्रमादेशन भाषाओं में समर्थन ==
== क्रमादेशन भाषाओं में समर्थन ==
विस्तार विधियाँ सी#, जावा वाया मैनिफोल्ड या लोम्बोक, गोसु, जावास्क्रिप्ट, ऑक्सीजन, रूबी, स्मॉलटाक, कोटलिन, डार्ट, विज़ुअल बेसिक.नेट और ज़ोजो सहित कई भाषाओं की विशेषताएं हैं। पायथन जैसी गतिशील भाषाओं में, एक विस्तार पद्धति की अवधारणा अनावश्यक है क्योंकि कक्षाओं को बिना किसी विशेष सिंटैक्स के बढ़ाया जा सकता है (एक दृष्टिकोण जिसे "मंकी-पैचिंग" के रूप में जाना जाता है, जैसे लाइब्रेरी में नियोजित)।
विस्तार विधियाँ सी#, जावा वाया मैनिफोल्ड या लोम्बोक, गोसु, जावास्क्रिप्ट, ऑक्सीजन, रूबी, स्मॉलटाक, कोटलिन, डार्ट, विज़ुअल बेसिक.नेट और ज़ोजो सहित कई भाषाओं की विशेषताएं हैं। पायथन जैसी गतिशील भाषाओं में, एक विस्तार पद्धति की अवधारणा अनावश्यक है क्योंकि क्लासओं को बिना किसी विशेष सिंटैक्स के बढ़ाया जा सकता है (एक दृष्टिकोण जिसे "मंकी-पैचिंग" के रूप में जाना जाता है, जैसे लाइब्रेरी में नियोजित)।


VB.NET और ऑक्सीजेन में, उन्हें  "<code>extension</code>" कीवर्ड या विशेषता की उपस्थिति से पहचाना जाता है। Xojo में "Extends" कीवर्ड का उपयोग वैश्विक विधियों के साथ किया जाता है।
VB.NET और ऑक्सीजेन में, उन्हें  "<code>extension</code>" कीवर्ड या विशेषता की उपस्थिति से पहचाना जाता है। Xojo में "Extends" कीवर्ड का उपयोग वैश्विक विधियों के साथ किया जाता है।


सी # में वे स्थिर कक्षाओं में स्थिर विधियों के रूप में कार्यान्वित किए जाते हैं, जिसमें पहला तर्क विस्तारित वर्ग का होता है और इससे पहले होता है<code>this</code>कीवर्ड।
C # में वे स्थिर क्लासओं में स्थिर विधियों के रूप में कार्यान्वित किए जाते हैं, जिसमें पहला तर्क विस्तारित वर्ग का होता है और इससे पहले <code>this</code>कीवर्ड होता है।


जावा में आप [http://manifold.systems/ Manifold] के माध्यम से विस्तार विधियाँ जोड़ते हैं, एक जार फ़ाइल जिसे आप अपने प्रोजेक्ट के क्लासपाथ में जोड़ते हैं। सी # के समान एक जावा एक्सटेंशन विधि को एक [http://manifold.systems/docs.html#extension-classes @Extension] वर्ग में स्थिर घोषित किया जाता है, जहां पहले तर्क में विस्तारित वर्ग के समान प्रकार होता है और इसके साथ एनोटेट किया जाता है <code>@This</code>.
जावा में आप मैनिफोल्ड के माध्यम से विस्तारक विधियों को जोड़ते हैं, एक जार फ़ाइल जिसे आप अपने परियोजनाओं  के क्लासपाथ में जोड़ते हैं। C# के समान एक जावा विस्तारक विधि को @Extension क्लास में स्थिर घोषित किया जाता है जहां पहले तर्क में विस्तारित वर्ग के समान प्रकार होता है और इसे  <code>@This</code>.के साथ एनोटेट किया जाता है।


स्मॉलटाक में, कोई भी कोड किसी भी समय किसी भी वर्ग के लिए एक विधि निर्माण संदेश भेजकर एक विधि जोड़ सकता है (जैसे <code>methodsFor:</code>) उस वर्ग तक जिसे उपयोगकर्ता विस्तारित करना चाहता है। स्मॉलटॉक विधि श्रेणी को पारंपरिक रूप से उस पैकेज के नाम पर रखा गया है जो विस्तार प्रदान करता है, जो तारांकन से घिरा हुआ है। उदाहरण के लिए, जब Etoys एप्लिकेशन कोड कोर लाइब्रेरी में कक्षाओं का विस्तार करता है, तो जोड़े गए तरीके इसमें डाल दिए जाते हैं <code>*etoys*</code> वर्ग।
स्मॉलटाक में, कोई भी कूट किसी भी समय किसी भी वर्ग के लिए एक विधि निर्माण संदेश भेजकर एक विधि जोड़ सकता है (जैसे <code>methodsFor:</code>) उस वर्ग तक जिसे उपयोगकर्ता विस्तारित करना चाहता है। स्मॉलटॉक विधि श्रेणी को पारंपरिक रूप से उस पैकेज के नाम पर रखा गया है जो विस्तार प्रदान करता है, जो तारांकन से घिरा हुआ है। उदाहरण के लिए, जब Etoys एप्लिकेशन कूट कोर लाइब्रेरी में क्लासओं का विस्तार करता है, तो जोड़े गए तरीके इसमें <code>*etoys*</code> वर्ग डाल दिए जाते हैं।


रूबी में, स्मॉलटाक की तरह, विस्तार के लिए कोई विशेष भाषा सुविधा नहीं है, क्योंकि रूबी किसी भी समय कक्षाओं को फिर से खोलने की अनुमति देता है <code>class</code> कीवर्ड, इस मामले में, नए तरीके जोड़ने के लिए। रूबी समुदाय अक्सर एक विस्तार विधि का वर्णन एक प्रकार के बंदर पैच के रूप में करता है। [https://docs.ruby-lang.org/en/2.5.0/syntax/refinements_rdoc.html Refinements] नामक वस्तुओं में सुरक्षित/स्थानीय एक्सटेंशन जोड़ने के लिए एक नई सुविधा भी है, लेकिन इसे जाना जाता है कम इस्तेमाल किया।
रूबी में, स्मॉलटाक की तरह, विस्तार के लिए कोई विशेष भाषा सुविधा नहीं है, क्योंकि रूबी किसी भी समय क्लासओं को फिर से <code>class</code> कीवर्ड खोलने की अनुमति देता है, इस मामले में नए तरीके जोड़ने के लिए रूबी समुदाय अक्सर एक विस्तार विधि का वर्णन एक प्रकार के मंकी पैच के रूप में करता है। [https://docs.ruby-lang.org/en/2.5.0/syntax/refinements_rdoc.html Refinements] नामक वस्तुओं में सुरक्षित/स्थानीय विस्तारक जोड़ने के लिए एक नई सुविधा भी है, लेकिन इसे जाना जाता है इस्तेमाल किया कम जाता है।


स्विफ्ट में, <code>extension</code> कीवर्ड एक वर्ग-जैसी संरचना को चिह्नित करता है जो मौजूदा वर्ग में विधियों, कन्स्ट्रक्टर और फ़ील्ड को जोड़ने की अनुमति देता है, जिसमें मौजूदा कक्षा में एक नया इंटरफ़ेस/प्रोटोकॉल लागू करने की क्षमता भी शामिल है।<ref>{{Cite web |title=Extensions — The Swift Programming Language (Swift 5.7) |url=https://docs.swift.org/swift-book/LanguageGuide/Extensions.html |access-date=2022-06-12 |website=docs.swift.org}}</ref>
स्विफ्ट में, <code>extension</code> कीवर्ड एक वर्ग-जैसी संरचना को चिह्नित करता है जो मौजूदा वर्ग में विधियों, कन्स्ट्रक्टर और फ़ील्ड को जोड़ने की अनुमति देता है, जिसमें मौजूदा क्लास में एक नया अंतरापृष्ठ/प्रोटोकॉल लागू करने की क्षमता भी शामिल है।<ref>{{Cite web |title=Extensions — The Swift Programming Language (Swift 5.7) |url=https://docs.swift.org/swift-book/LanguageGuide/Extensions.html |access-date=2022-06-12 |website=docs.swift.org}}</ref>




==विस्तार विधियों को सक्षम करने वाली सुविधा के रूप में ==
==विस्तार विधियों को सक्षम करने वाली सुविधा के रूप में ==
एक्सटेंशन विधियों के आगे दूसरों द्वारा लिखे गए कोड को नीचे वर्णित अनुसार विस्तारित करने की अनुमति देने के बाद, एक्सटेंशन विधियां उन पैटर्नों को सक्षम करती हैं जो स्वयं के अधिकार में भी उपयोगी होती हैं। विस्तार विधियों को पेश करने का मुख्य कारण [[भाषा एकीकृत क्वेरी]] (LINQ) था। एक्सटेंशन विधियों के लिए कंपाइलर समर्थन पुराने कोड के साथ LINQ के गहरे एकीकरण की अनुमति देता है, साथ ही साथ C Sharp सिंटैक्स#क्वेरी सिंटैक्स के लिए समर्थन जो फिलहाल प्राथमिक Microsoft .NET भाषाओं के लिए अद्वितीय है।
विस्तारक विधियों के आगे दूसरों द्वारा लिखे गए कूट को नीचे वर्णित अनुसार विस्तारित करने की अनुमति देने के बाद, विस्तारक विधियां उन पैटर्नों को सक्षम करती हैं जो स्वयं के अधिकार में भी उपयोगी होती हैं। विस्तार विधियों को पेश करने का मुख्य कारण [[भाषा एकीकृत क्वेरी]] (LINQ) था। विस्तारक विधियों के लिए संकलक समर्थन पुराने कूट के साथ LINQ के गहरे एकीकरण की अनुमति देता है, साथ ही साथ C Sharp सिंटैक्स#क्वेरी सिंटैक्स के लिए समर्थन जो फिलहाल प्राथमिक Microsoft .NET भाषाओं के लिए अद्वितीय है।


<syntaxhighlight lang="csharp">
<syntaxhighlight lang="csharp">
Line 32: Line 32:


=== सामान्य व्यवहार को केंद्रीकृत करें ===
=== सामान्य व्यवहार को केंद्रीकृत करें ===
हालाँकि, विस्तार विधियाँ सुविधाओं को एक बार उन तरीकों से लागू करने की अनुमति देती हैं जो [[ वंशानुक्रम (वस्तु-उन्मुख प्रोग्रामिंग) ]] या [[वर्चुअल फंक्शन]] इनवोकेशन के ओवरहेड की आवश्यकता के बिना पुन: उपयोग करने में सक्षम हैं, या किसी [[प्रोटोकॉल (ऑब्जेक्ट-ओरिएंटेड प्रोग्रामिंग)|प्रोटोकॉल (वस्तु-ओरिएंटेड प्रोग्रामिंग)]] के कार्यान्वयनकर्ताओं की आवश्यकता के लिए या तो लागू करने के लिए तुच्छ या बुरी तरह जटिल कार्यक्षमता।
हालाँकि, विस्तार विधियाँ सुविधाओं को एक बार उन तरीकों से लागू करने की अनुमति देती हैं जो [[ वंशानुक्रम (वस्तु-उन्मुख प्रोग्रामिंग) ]] या [[Index.php?title=आभासी विधि|आभासी विधि]] उत्क्रियण के उपरिव्यय की आवश्यकता के बिना पुन: उपयोग करने में सक्षम हैं, या किसी [[Index.php?title=प्रोटोकॉल (वस्तु-उन्मुख क्रमादेशन)|प्रोटोकॉल (वस्तु-उन्मुख क्रमादेशन)]] के कार्यान्वयनकर्ताओं की आवश्यकता होती है।


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


निम्नलिखित कोड पर विचार करें और मान लें कि यह क्लास लाइब्रेरी में निहित एकमात्र कोड है। फिर भी, ILogger इंटरफ़ेस के प्रत्येक कार्यान्वयनकर्ता को MyCoolLogger कथन का उपयोग करके, इसे एक बार लागू किए बिना और ILogger के कार्यान्वयन प्रदान किए गए क्लास लाइब्रेरी को उप-वर्ग करने की आवश्यकता के बिना, एक स्वरूपित स्ट्रिंग लिखने की क्षमता प्राप्त होगी।
निम्नलिखित कूट पर विचार करें और मान लें कि यह क्लास लाइब्रेरी में निहित एकमात्र कूट है। फिर भी, ILogger अंतरापृष्ठ के प्रत्येक कार्यान्वयनकर्ता को MyCoolLogger कथन का उपयोग करके, इसे एक बार लागू किए बिना और ILogger के कार्यान्वयन प्रदान किए गए क्लास लाइब्रेरी को उप-वर्ग करने की आवश्यकता के बिना, एक स्वरूपित स्ट्रिंग लिखने की क्षमता प्राप्त होगी।


<syntaxhighlight lang="csharp">
<syntaxhighlight lang="csharp">
Line 67: Line 67:


===बेहतर ढीला युग्मन===
===बेहतर ढीला युग्मन===
विस्तार विधियाँ कक्षा पुस्तकालयों के उपयोगकर्ताओं को उस पुस्तकालय से आने वाले किसी प्रकार के तर्क, चर, या किसी अन्य चीज़ की घोषणा करने से परहेज करने की अनुमति देती हैं। कक्षा पुस्तकालय में उपयोग किए जाने वाले प्रकारों का निर्माण और रूपांतरण विस्तार विधियों के रूप में कार्यान्वित किया जा सकता है। रूपांतरणों और कारखानों को ध्यान से लागू करने के बाद, एक क्लास लाइब्रेरी से दूसरे में स्विच करना उतना ही आसान बनाया जा सकता है जितना कि यूज़िंग स्टेटमेंट को बदलना जो कंपाइलर को बाइंड करने के लिए विस्तार विधि उपलब्ध कराता है।
विस्तार विधियाँ क्लास लाइब्रेरी के उपयोगकर्ताओं को उस लाइब्रेरी से आने वाले किसी प्रकार के तर्क, चर, या किसी अन्य चीज़ की घोषणा करने से परहेज करने की अनुमति देती हैं। क्लास लाइब्रेरी में उपयोग किए जाने वाले प्रकारों का निर्माण और रूपांतरण विस्तार विधियों के रूप में कार्यान्वित किया जा सकता है। रूपांतरणों और फैक्टरी को ध्यान से लागू करने के बाद, एक क्लास लाइब्रेरी से दूसरे में स्विचन करना उतना ही आसान बनाया जा सकता है जितना कि यूज़िंग स्टेटमेंट को बदलना जो संकलक को संगठित करने के लिए विस्तार विधि उपलब्ध कराता है।


===धाराप्रवाह अनुप्रयोग प्रोग्रामर के इंटरफेस ===
===धाराप्रवाह अनुप्रयोग क्रमादेशक के अंतरापृष्ठ ===
तथाकथित धाराप्रवाह इंटरफेस को लागू करने में विस्तार विधियों का विशेष उपयोग होता है। एक उदाहरण माइक्रोसॉफ्ट का एंटिटी फ्रेमवर्क कॉन्फ़िगरेशन एपीआई है, जो उदाहरण के लिए कोड लिखने की अनुमति देता है जो नियमित अंग्रेजी के समान व्यवहारिक रूप से मिलता-जुलता है।
तथाकथित धाराप्रवाह अंतरापृष्ठ को लागू करने में विस्तार विधियों का विशेष उपयोग होता है। एक उदाहरण माइक्रोसॉफ्ट का इकाई संरचना संरूपण एपीआई है, जो उदाहरण के लिए कूट लिखने की अनुमति देता है जो नियमित अंग्रेजी के समान व्यवहारिक रूप से मिलता-जुलता है।


कोई यह तर्क दे सकता है कि विस्तार विधियों के बिना यह उतना ही संभव है, लेकिन कोई यह पाएगा कि व्यवहार में, विस्तार विधियां एक बेहतर अनुभव प्रदान करती हैं क्योंकि इसे काम करने के लिए वर्ग पदानुक्रम पर कम बाधाएं रखी जाती हैं - और वांछित के रूप में पढ़ा जाता है।
कोई यह तर्क दे सकता है कि विस्तार विधियों के बिना यह उतना ही संभव है, लेकिन कोई यह पाएगा कि व्यवहार में, विस्तार विधियां एक बेहतर अनुभव प्रदान करती हैं क्योंकि इसे काम करने के लिए वर्ग पदानुक्रम पर कम बाधाएं रखी जाती हैं - और वांछित के रूप में पढ़ा जाता है।


निम्न उदाहरण एंटिटी फ्रेमवर्क का उपयोग करता है और डेटाबेस तालिका में संग्रहीत करने के लिए TodoList क्लास को कॉन्फ़िगर करता है और प्राथमिक और विदेशी कुंजी को सूचीबद्ध करता है और परिभाषित करता है। कोड को कमोबेश इस तरह समझा जाना चाहिए: एक TodoList के पास कुंजी TodoListID है, इसकी इकाई सेट का नाम सूचियाँ है और इसमें कई TodoItem हैं जिनमें से प्रत्येक के लिए एक आवश्यक TodoList है।
निम्न उदाहरण इकाई संरचना का उपयोग करता है और आँकड़ासंचय तालिका में संग्रहीत करने के लिए TodoList क्लास को समनुरूप करता है और प्राथमिक और बाह्य कुंजी को सूचीबद्ध करता है और परिभाषित करता है। कूट को कमोबेश इस तरह समझा जाना चाहिए: एक TodoList के पास कुंजी TodoListID है, इसकी इकाई सेट का नाम सूचियाँ है और इसमें कई TodoItem हैं जिनमें से प्रत्येक के लिए एक आवश्यक TodoList है।


<syntaxhighlight lang="csharp">
<syntaxhighlight lang="csharp">
Line 96: Line 96:


=== उत्पादकता ===
=== उत्पादकता ===
उदाहरण के लिए विचार करें [http://msdn.microsoft.com/en-us/library/system.collections.ienumerable.aspx IEnumerable] और इसकी सादगी पर ध्यान दें - केवल एक विधि है, फिर भी यह LINQ का कम या ज्यादा आधार है . Microsoft .NET में इस इंटरफ़ेस के कई कार्यान्वयन हैं। फिर भी, जाहिर है, [http://msdn.microsoft.com/en-us/library/system.linq.aspx सिस्टम में परिभाषित तरीकों की पूरी श्रृंखला को लागू करने के लिए इनमें से प्रत्येक कार्यान्वयन की आवश्यकता बोझिल होगी। .Linq नामस्थान] IEnumerables पर काम करने के लिए, भले ही Microsoft के पास सभी स्रोत कोड हों। इससे भी बदतर, इसके लिए Microsoft के अलावा सभी को उन सभी तरीकों को लागू करने के लिए IEnumerable का उपयोग करने पर विचार करने की आवश्यकता होगी, जो इस बहुत ही सामान्य इंटरफ़ेस के व्यापक उपयोग को देखते हुए बहुत ही विरोधी होते। इसके बजाय, इस इंटरफ़ेस की एक विधि को लागू करके, LINQ को तुरंत कम या ज्यादा इस्तेमाल किया जा सकता है। विशेष रूप से व्यावहारिक रूप से अधिकांश मामलों में देखने पर IEnumerable की GetEnumerator विधि को एक निजी संग्रह, सूची या सरणी के GetEnumerator कार्यान्वयन के लिए प्रत्यायोजित किया जाता है।
उदाहरण के लिए विचार करें [http://msdn.microsoft.com/en-us/library/system.collections.ienumerable.aspx IEnumerable] और इसकी सादगी पर ध्यान दें - केवल एक विधि है, फिर भी यह LINQ का कम या ज्यादा आधार है . Microsoft .NET में इस अंतरापृष्ठ के कई कार्यान्वयन हैं। फिर भी, जाहिर है, [http://msdn.microsoft.com/en-us/library/system.linq.aspx सिस्टम में परिभाषित तरीकों की पूरी श्रृंखला को लागू करने के लिए इनमें से प्रत्येक कार्यान्वयन की आवश्यकता बोझिल होगी। .Linq नामस्थान] IEnumerables पर काम करने के लिए, भले ही Microsoft के पास सभी स्रोत कूट हों। इससे भी बदतर, इसके लिए Microsoft के अलावा सभी को उन सभी तरीकों को लागू करने के लिए IEnumerable का उपयोग करने पर विचार करने की आवश्यकता होगी, जो इस बहुत ही सामान्य अंतरापृष्ठ के व्यापक उपयोग को देखते हुए बहुत ही विरोधी होते। इसके बजाय, इस अंतरापृष्ठ की एक विधि को लागू करके, LINQ को तुरंत कम या ज्यादा इस्तेमाल किया जा सकता है। विशेष रूप से व्यावहारिक रूप से अधिकांश मामलों में देखने पर IEnumerable की GetEnumerator विधि को एक निजी संग्रह, सूची या सरणी के GetEnumerator कार्यान्वयन के लिए प्रत्यायोजित किया जाता है।


<syntaxhighlight lang="csharp">
<syntaxhighlight lang="csharp">
Line 121: Line 121:


=== प्रदर्शन ===
=== प्रदर्शन ===
उस ने कहा, प्रदर्शन को बेहतर बनाने के लिए, या अलग-अलग कार्यान्वित इंटरफ़ेस कार्यान्वयन से निपटने के लिए एक विस्तार विधि द्वारा प्रदान की गई सुविधा के अतिरिक्त कार्यान्वयन को जोड़ा जा सकता है, जैसे कि कंपाइलर को विशेष रूप से सरणियों के लिए IEnumerable का कार्यान्वयन प्रदान करना (System.SZArrayHelper में), जो कि यह स्वचालित रूप से सरणी टाइप किए गए संदर्भों पर एक्सटेंशन विधि कॉल के लिए चयन करेगा, क्योंकि उनका तर्क एक्सटेंशन विधि की तुलना में अधिक विशिष्ट होगा (यह टी [] मान) उसी नाम के साथ एक्सटेंशन विधि से जो IEnumerable इंटरफ़ेस (यह IEnumerable मान) के उदाहरणों पर संचालित होता है।
उस ने कहा, प्रदर्शन को बेहतर बनाने के लिए, या अलग-अलग कार्यान्वित अंतरापृष्ठ कार्यान्वयन से निपटने के लिए एक विस्तार विधि द्वारा प्रदान की गई सुविधा के अतिरिक्त कार्यान्वयन को जोड़ा जा सकता है, जैसे कि संकलक को विशेष रूप से सरणियों के लिए IEnumerable का कार्यान्वयन प्रदान करना (System.SZArrayHelper में), जो कि यह स्वचालित रूप से सरणी टाइप किए गए संदर्भों पर विस्तारक विधि कॉल के लिए चयन करेगा, क्योंकि उनका तर्क विस्तारक विधि की तुलना में अधिक विशिष्ट होगा (यह T [] मान) उसी नाम के साथ विस्तारक विधि से जो IEnumerable अंतरापृष्ठ (यह IEnumerable मान) के उदाहरणों पर संचालित होता है।


=== एक सामान्य आधार वर्ग === की आवश्यकता को कम करना
=== एक सामान्य आधार वर्ग की आवश्यकता को कम करना ===
सामान्य वर्गों के साथ, विस्तार विधियां सामान्य आधार वर्ग से प्राप्त करने की आवश्यकता के बिना सामान्य प्रकार के सभी तात्कालिकताओं के लिए उपलब्ध व्यवहार के कार्यान्वयन की अनुमति देती हैं, और प्रकार के मापदंडों को एक विशिष्ट वंशानुक्रम शाखा तक सीमित किए बिना। यह एक बड़ी जीत है, क्योंकि जिन स्थितियों में यह तर्क होता है, उन्हें केवल साझा सुविधा को लागू करने के लिए एक गैर-जेनेरिक आधार वर्ग की आवश्यकता होती है - जिसके लिए जेनेरिक उपवर्ग को [[बॉक्सिंग (प्रोग्रामिंग)]] और/या जब भी उपयोग किया जाता है, तब कास्ट करने की आवश्यकता होती है। प्रकार तर्क।
सामान्य वर्गों के साथ, विस्तार विधियां सामान्य आधार वर्ग से प्राप्त करने की आवश्यकता के बिना सामान्य प्रकार के सभी तात्कालिकताओं के लिए उपलब्ध व्यवहार के कार्यान्वयन की अनुमति देती हैं, और प्रकार के मापदंडों को एक विशिष्ट वंशानुक्रम शाखा तक सीमित किए बिना। यह एक बड़ी जीत है, क्योंकि जिन स्थितियों में यह तर्क होता है, उन्हें केवल साझा सुविधा को लागू करने के लिए एक गैर सामान्य आधार वर्ग की आवश्यकता होती है - जिसके लिए सामान्य उपवर्ग को [[बॉक्सिंग (प्रोग्रामिंग)]] और/या जब भी उपयोग किया जाता है, तब कास्ट करने की आवश्यकता होती है।


=== रूढ़िवादी उपयोग ===
=== रूढ़िवादी उपयोग ===
पुन: उपयोग और उचित वस्तु-उन्मुख डिजाइन प्राप्त करने के अन्य साधनों पर विस्तार विधियों को प्राथमिकता देने पर ध्यान दिया जाना चाहिए।
पुन: उपयोग और उचित वस्तु-उन्मुख अभिकलन प्राप्त करने के अन्य साधनों पर विस्तार विधियों को प्राथमिकता देने पर ध्यान दिया जाना चाहिए।
एक्सटेंशन विधियां कोड संपादकों की स्वत: पूर्ण होने वाली विशेषताओं को 'अव्यवस्था' कर सकती हैं, जैसे कि विज़ुअल स्टूडियो का इंटेलीसेंस, इसलिए उन्हें या तो अपने स्वयं के नामस्थान में होना चाहिए ताकि डेवलपर उन्हें चुनिंदा रूप से आयात कर सकें या उन्हें एक प्रकार पर परिभाषित किया जाना चाहिए जो कि विशिष्ट के लिए पर्याप्त है IntelliSense में प्रकट होने की विधि केवल तभी जब वास्तव में प्रासंगिक हो और ऊपर दी गई हो, इस बात पर विचार करें कि यदि डेवलपर उनसे अपेक्षा करता है तो उन्हें खोजना मुश्किल हो सकता है, लेकिन लापता उपयोग कथन के कारण उन्हें IntelliSense से याद कर सकते हैं, क्योंकि डेवलपर ने विधि को संबद्ध नहीं किया हो सकता है उस वर्ग के साथ जो इसे परिभाषित करता है, या यहां तक ​​​​कि नामस्थान जिसमें यह रहता है - बल्कि उस प्रकार के साथ जो इसे विस्तारित करता है और नामस्थान जो टाइप करता है।
विस्तारक विधियां कूट संपादकों की स्वत: पूर्ण होने वाली विशेषताओं को 'अव्यवस्था' कर सकती हैं, जैसे कि विज़ुअल स्टूडियो का इंटेलीसेंस, इसलिए उन्हें या तो अपने स्वयं के नामस्थान में होना चाहिए ताकि विकासक उन्हें चुनिंदा रूप से आयात कर सकें या उन्हें एक प्रकार पर परिभाषित किया जाना चाहिए जो कि विशिष्ट के लिए पर्याप्त है इंटेलीसेंस में प्रकट होने की विधि केवल तभी जब वास्तव में प्रासंगिक हो और ऊपर दी गई हो, इस बात पर विचार करें कि यदि विकासक उनसे अपेक्षा करता है तो उन्हें खोजना मुश्किल हो सकता है, लेकिन लापता उपयोग कथन के कारण उन्हें इंटेलीसेंस से याद कर सकते हैं, क्योंकि विकासक ने विधि को संबद्ध नहीं किया हो सकता है उस वर्ग के साथ जो इसे परिभाषित करता है, या यहां तक ​​​​कि नामस्थान जिसमें यह रहता है - बल्कि उस प्रकार के साथ जो इसे विस्तारित करता है और नामस्थान जो टाइप करता है।


== समस्या ==
== समस्या ==
प्रोग्रामिंग में, ऐसी परिस्थितियाँ उत्पन्न होती हैं जहाँ किसी मौजूदा वर्ग में कार्यक्षमता जोड़ना आवश्यक होता है - उदाहरण के लिए एक नई विधि जोड़कर। आम तौर पर प्रोग्रामर मौजूदा वर्ग के स्रोत कोड को संशोधित करेगा, लेकिन यह प्रोग्रामर को इन नए परिवर्तनों के साथ सभी [[निष्पादन]] योग्य को संकलित करने के लिए मजबूर करता है और इसके लिए आवश्यक है कि प्रोग्रामर वर्ग को संशोधित करने में सक्षम हो, जो हमेशा संभव नहीं होता है, उदाहरण के लिए तीसरे से कक्षाओं का उपयोग करते समय -पार्टी [[असेंबली (सीएलआई)]]। यह आम तौर पर तीन तरीकों में से एक में काम किया जाता है, जिनमें से सभी कुछ हद तक सीमित और अनजान हैं {{citation needed|date=August 2014}}:
प्रोग्रामिंग में, ऐसी परिस्थितियाँ उत्पन्न होती हैं जहाँ किसी मौजूदा वर्ग में कार्यक्षमता जोड़ना आवश्यक होता है - उदाहरण के लिए एक नई विधि जोड़कर, आम तौर पर क्रमादेशित्र मौजूदा वर्ग के स्रोत कूट को संशोधित करेगा, लेकिन यह क्रमादेशित्र को इन नए परिवर्तनों के साथ सभी [[निष्पादन]] योग्य को संकलित करने के लिए मजबूर करता है और इसके लिए आवश्यक है कि क्रमादेशित्र वर्ग को संशोधित करने में सक्षम हो, जो हमेशा संभव नहीं होता है, उदाहरण के लिए तीसरे से क्लास का उपयोग करते समय -पार्टी [[Index.php?title=कोड़ांतरण (सीएलआई)|कोड़ांतरण (सीएलआई)]]। यह आम तौर पर तीन तरीकों में से एक में काम किया जाता है, जिनमें से सभी कुछ हद तक सीमित और अनजान हैं {{citation needed|date=August 2014}}:
# क्लास को इनहेरिट करें और फिर व्युत्पन्न क्लास में इंस्टेंस मेथड में कार्यक्षमता को लागू करें।
# क्लास को इनहेरिट करें और फिर व्युत्पन्न क्लास में उदाहरण विधि में कार्यक्षमता को लागू करें।
# सहायक वर्ग में जोड़े गए स्थिर तरीकों में कार्यक्षमता को लागू करें।
# सहायक वर्ग में जोड़े गए स्थिर तरीकों में कार्यक्षमता को लागू करें।
# विरासत (कंप्यूटर विज्ञान) के बजाय वस्तु रचना # एकत्रीकरण का उपयोग करें।
# विरासत (अभिकलित्र विज्ञान) के बजाय वस्तु रचना # एकत्रीकरण का उपयोग करें।


== वर्तमान सी # समाधान ==
== वर्तमान C # समाधान ==
पहला विकल्प सैद्धांतिक रूप से आसान है, लेकिन दुर्भाग्य से यह इस तथ्य से सीमित है कि कई वर्ग कुछ सदस्यों की विरासत को प्रतिबंधित करते हैं या इसे पूरी तरह से प्रतिबंधित करते हैं। इसमें सी # में सीलबंद वर्ग और विभिन्न आदिम डेटा प्रकार शामिल हैं जैसे कि इंटेगर (कंप्यूटर साइंस), [[ तैरनेवाला स्थल ]] और [[ स्ट्रिंग (कंप्यूटर विज्ञान) ]]। दूसरी ओर, दूसरा विकल्प इन प्रतिबंधों को साझा नहीं करता है, लेकिन यह कम सहज ज्ञान युक्त हो सकता है क्योंकि इसमें सीधे वर्ग के तरीकों का उपयोग करने के बजाय एक अलग वर्ग के संदर्भ की आवश्यकता होती है।
पहला विकल्प सैद्धांतिक रूप से आसान है, लेकिन दुर्भाग्य से यह इस तथ्य से सीमित है कि कई वर्ग कुछ सदस्यों की विरासत को प्रतिबंधित करते हैं या इसे पूरी तरह से प्रतिबंधित करते हैं। इसमें सी # में सीलबंद वर्ग और विभिन्न आदिम डेटा प्रकार शामिल हैं जैसे कि इंटेगर (कंप्यूटर साइंस), [[ तैरनेवाला स्थल ]] और [[ स्ट्रिंग (कंप्यूटर विज्ञान) ]]। दूसरी ओर, दूसरा विकल्प इन प्रतिबंधों को साझा नहीं करता है, लेकिन यह कम सहज ज्ञान युक्त हो सकता है क्योंकि इसमें सीधे वर्ग के तरीकों का उपयोग करने के बजाय एक अलग वर्ग के संदर्भ की आवश्यकता होती है।


Line 144: Line 144:
string y = Utility.Reverse(x);
string y = Utility.Reverse(x);
</syntaxhighlight>
</syntaxhighlight>
हालाँकि, उपयोगिता विधियों और कक्षाओं के पुस्तकालय के रूप में नेविगेट करना तेजी से कठिन हो सकता है, विशेष रूप से नए लोगों के लिए। स्थान भी कम सहज है, क्योंकि अधिकांश स्ट्रिंग विधियों के विपरीत, यह स्ट्रिंग क्लास का सदस्य नहीं होगा, बल्कि पूरी तरह से अलग वर्ग में होगा। इसलिए एक बेहतर सिंटैक्स निम्नलिखित होगा:
हालाँकि, उपयोगिता विधियों और क्लासओं के लाइब्रेरी के रूप में नेविगेट करना तेजी से कठिन हो सकता है, विशेष रूप से नए लोगों के लिए। स्थान भी कम सहज है, क्योंकि अधिकांश स्ट्रिंग विधियों के विपरीत, यह स्ट्रिंग क्लास का सदस्य नहीं होगा, बल्कि पूरी तरह से अलग वर्ग में होगा। इसलिए एक बेहतर सिंटैक्स निम्नलिखित होगा:
<syntaxhighlight lang="csharp">
<syntaxhighlight lang="csharp">
string x = "some string value";
string x = "some string value";
Line 157: Line 157:
x.Reverse()  
x.Reverse()  
</syntaxhighlight>
</syntaxhighlight>
क्योंकि विज़ुअल बेसिक स्रोत वस्तु को संदर्भ द्वारा पारित करने की अनुमति देता है, इसलिए किसी अन्य चर को बनाने की आवश्यकता के बिना सीधे स्रोत वस्तु में परिवर्तन करना संभव है। यह अधिक सहज भी है क्योंकि यह कक्षाओं के मौजूदा तरीकों के अनुरूप काम करता है।
क्योंकि विज़ुअल बेसिक स्रोत वस्तु को संदर्भ द्वारा पारित करने की अनुमति देता है, इसलिए किसी अन्य चर को बनाने की आवश्यकता के बिना सीधे स्रोत वस्तु में परिवर्तन करना संभव है। यह अधिक सहज भी है क्योंकि यह क्लासओं के मौजूदा तरीकों के अनुरूप काम करता है।


== विस्तार के तरीके ==
== विस्तार के तरीके ==
सी # 3.0 में विस्तार विधियों की नई भाषा सुविधा, हालांकि, बाद वाले कोड को संभव बनाती है। इस दृष्टिकोण के लिए निम्नानुसार एक स्थिर वर्ग और एक स्थिर विधि की आवश्यकता होती है।
सी # 3.0 में विस्तार विधियों की नई भाषा सुविधा, हालांकि, बाद वाले कूट को संभव बनाती है। इस दृष्टिकोण के लिए निम्नानुसार एक स्थिर वर्ग और एक स्थिर विधि की आवश्यकता होती है।


<syntaxhighlight lang="csharp">
<syntaxhighlight lang="csharp">
Line 175: Line 175:
परिभाषा में, पहले तर्क से पहले संशोधक 'यह' निर्दिष्ट करता है कि यह एक विस्तार विधि है (इस मामले में 'स्ट्रिंग' टाइप करने के लिए)। एक कॉल में, पहला तर्क 'पास इन' नहीं होता है क्योंकि इसे पहले से ही 'कॉलिंग' वस्तु (डॉट से पहले की वस्तु) के रूप में जाना जाता है।
परिभाषा में, पहले तर्क से पहले संशोधक 'यह' निर्दिष्ट करता है कि यह एक विस्तार विधि है (इस मामले में 'स्ट्रिंग' टाइप करने के लिए)। एक कॉल में, पहला तर्क 'पास इन' नहीं होता है क्योंकि इसे पहले से ही 'कॉलिंग' वस्तु (डॉट से पहले की वस्तु) के रूप में जाना जाता है।


कॉलिंग एक्सटेंशन विधियों और स्टेटिक हेल्पर विधियों को कॉल करने के बीच प्रमुख अंतर यह है कि स्थिर विधियों को [[ पोलिश संकेतन ]] में कहा जाता है, जबकि एक्सटेंशन विधियों को [[ इंफिक्स नोटेशन ]] में कहा जाता है। उत्तरार्द्ध अधिक पठनीय कोड की ओर जाता है जब एक ऑपरेशन के परिणाम का उपयोग दूसरे ऑपरेशन के लिए किया जाता है।
कॉलिंग विस्तारक विधियों और स्टेटिक हेल्पर विधियों को कॉल करने के बीच प्रमुख अंतर यह है कि स्थिर विधियों को [[ पोलिश संकेतन ]] में कहा जाता है, जबकि विस्तारक विधियों को [[ इंफिक्स नोटेशन ]] में कहा जाता है। उत्तरार्द्ध अधिक पठनीय कूट की ओर जाता है जब एक ऑपरेशन के परिणाम का उपयोग दूसरे ऑपरेशन के लिए किया जाता है।


स्थिर विधियों के साथ: <syntaxhighlight lang="csharp">HelperClass.Operation2(HelperClass.Operation1(x, arg1), arg2)</syntaxhighlight>
स्थिर विधियों के साथ: <syntaxhighlight lang="csharp">HelperClass.Operation2(HelperClass.Operation1(x, arg1), arg2)</syntaxhighlight>

Revision as of 12:38, 28 May 2023

वस्तु-उन्मुख अभिकलित्र क्रमादेशन में, एक विस्तार विधि एक विधि (अभिकलित्र क्रमादेशन) है जो मूल वस्तु केसंकलक होने के बाद किसी वस्तु में जोड़ा जाता है। संशोधित वस्तु अक्सर एक वर्ग, एक आदिप्ररूप या एक प्रकार होतE है। विस्तार विधियाँ कुछ वस्तु-उन्मुख क्रमादेशन भाषाओं की विशेषताएं हैं। विस्तार विधि को कॉल करने और टाइप परिभाषा में घोषित तरीके को कॉल करने के बीच कोई वाक्य रचना संबंधी अंतर नहीं है।[1]

हालाँकि, सभी भाषाएँ विस्तार विधियों को समान रूप से सुरक्षित तरीके से लागू नहीं करती हैं। उदाहरण के लिए, C#, जावा जैसी भाषाएं ( Manifold या Lombok द्वारा), और कोटलिन किसी भी तरह से विस्तारित वर्ग में परिवर्तन नहीं करते हैं, क्योंकि ऐसा करने से वर्ग पदानुक्रम टूट सकता है और आभासी विधि प्रेषण में बाधा उत्पन्न हो सकती है। यही कारण है कि ये भाषाएं विस्तार विधियों को सख्ती से वैधानिक रूप से लागू करती हैं और उन्हें आमंत्रित करने के लिए स्थिर प्रेषण का उपयोग करती हैं।

क्रमादेशन भाषाओं में समर्थन

विस्तार विधियाँ सी#, जावा वाया मैनिफोल्ड या लोम्बोक, गोसु, जावास्क्रिप्ट, ऑक्सीजन, रूबी, स्मॉलटाक, कोटलिन, डार्ट, विज़ुअल बेसिक.नेट और ज़ोजो सहित कई भाषाओं की विशेषताएं हैं। पायथन जैसी गतिशील भाषाओं में, एक विस्तार पद्धति की अवधारणा अनावश्यक है क्योंकि क्लासओं को बिना किसी विशेष सिंटैक्स के बढ़ाया जा सकता है (एक दृष्टिकोण जिसे "मंकी-पैचिंग" के रूप में जाना जाता है, जैसे लाइब्रेरी में नियोजित)।

VB.NET और ऑक्सीजेन में, उन्हें "extension" कीवर्ड या विशेषता की उपस्थिति से पहचाना जाता है। Xojo में "Extends" कीवर्ड का उपयोग वैश्विक विधियों के साथ किया जाता है।

C # में वे स्थिर क्लासओं में स्थिर विधियों के रूप में कार्यान्वित किए जाते हैं, जिसमें पहला तर्क विस्तारित वर्ग का होता है और इससे पहले thisकीवर्ड होता है।

जावा में आप मैनिफोल्ड के माध्यम से विस्तारक विधियों को जोड़ते हैं, एक जार फ़ाइल जिसे आप अपने परियोजनाओं के क्लासपाथ में जोड़ते हैं। C# के समान एक जावा विस्तारक विधि को @Extension क्लास में स्थिर घोषित किया जाता है जहां पहले तर्क में विस्तारित वर्ग के समान प्रकार होता है और इसे @This.के साथ एनोटेट किया जाता है।

स्मॉलटाक में, कोई भी कूट किसी भी समय किसी भी वर्ग के लिए एक विधि निर्माण संदेश भेजकर एक विधि जोड़ सकता है (जैसे methodsFor:) उस वर्ग तक जिसे उपयोगकर्ता विस्तारित करना चाहता है। स्मॉलटॉक विधि श्रेणी को पारंपरिक रूप से उस पैकेज के नाम पर रखा गया है जो विस्तार प्रदान करता है, जो तारांकन से घिरा हुआ है। उदाहरण के लिए, जब Etoys एप्लिकेशन कूट कोर लाइब्रेरी में क्लासओं का विस्तार करता है, तो जोड़े गए तरीके इसमें *etoys* वर्ग डाल दिए जाते हैं।

रूबी में, स्मॉलटाक की तरह, विस्तार के लिए कोई विशेष भाषा सुविधा नहीं है, क्योंकि रूबी किसी भी समय क्लासओं को फिर से class कीवर्ड खोलने की अनुमति देता है, इस मामले में नए तरीके जोड़ने के लिए रूबी समुदाय अक्सर एक विस्तार विधि का वर्णन एक प्रकार के मंकी पैच के रूप में करता है। Refinements नामक वस्तुओं में सुरक्षित/स्थानीय विस्तारक जोड़ने के लिए एक नई सुविधा भी है, लेकिन इसे जाना जाता है इस्तेमाल किया कम जाता है।

स्विफ्ट में, extension कीवर्ड एक वर्ग-जैसी संरचना को चिह्नित करता है जो मौजूदा वर्ग में विधियों, कन्स्ट्रक्टर और फ़ील्ड को जोड़ने की अनुमति देता है, जिसमें मौजूदा क्लास में एक नया अंतरापृष्ठ/प्रोटोकॉल लागू करने की क्षमता भी शामिल है।[2]


विस्तार विधियों को सक्षम करने वाली सुविधा के रूप में

विस्तारक विधियों के आगे दूसरों द्वारा लिखे गए कूट को नीचे वर्णित अनुसार विस्तारित करने की अनुमति देने के बाद, विस्तारक विधियां उन पैटर्नों को सक्षम करती हैं जो स्वयं के अधिकार में भी उपयोगी होती हैं। विस्तार विधियों को पेश करने का मुख्य कारण भाषा एकीकृत क्वेरी (LINQ) था। विस्तारक विधियों के लिए संकलक समर्थन पुराने कूट के साथ LINQ के गहरे एकीकरण की अनुमति देता है, साथ ही साथ C Sharp सिंटैक्स#क्वेरी सिंटैक्स के लिए समर्थन जो फिलहाल प्राथमिक Microsoft .NET भाषाओं के लिए अद्वितीय है।

Console.WriteLine(new[] { Math.PI, Math.E }.Where(d => d > 3).Select(d => Math.Sin(d / 2)).Sum());
// Output:
// 1


सामान्य व्यवहार को केंद्रीकृत करें

हालाँकि, विस्तार विधियाँ सुविधाओं को एक बार उन तरीकों से लागू करने की अनुमति देती हैं जो वंशानुक्रम (वस्तु-उन्मुख प्रोग्रामिंग) या आभासी विधि उत्क्रियण के उपरिव्यय की आवश्यकता के बिना पुन: उपयोग करने में सक्षम हैं, या किसी प्रोटोकॉल (वस्तु-उन्मुख क्रमादेशन) के कार्यान्वयनकर्ताओं की आवश्यकता होती है।

एक विशेष रूप से उपयोगी परिदृश्य यह है कि यदि सुविधा एक ऐसे अंतरापृष्ठ पर चलती है जिसके लिए कोई ठोस कार्यान्वयन नहीं है या क्लास लाइब्रेरी लेखक द्वारा उपयोगी कार्यान्वयन प्रदान नहीं किया गया है, उदा। जैसा कि लाइब्रेरी में अक्सर होता है जो विकासक्स को एक प्लगइन वास्तुकी या समान कार्यक्षमता प्रदान करता है।

निम्नलिखित कूट पर विचार करें और मान लें कि यह क्लास लाइब्रेरी में निहित एकमात्र कूट है। फिर भी, ILogger अंतरापृष्ठ के प्रत्येक कार्यान्वयनकर्ता को MyCoolLogger कथन का उपयोग करके, इसे एक बार लागू किए बिना और ILogger के कार्यान्वयन प्रदान किए गए क्लास लाइब्रेरी को उप-वर्ग करने की आवश्यकता के बिना, एक स्वरूपित स्ट्रिंग लिखने की क्षमता प्राप्त होगी।

namespace MyCoolLogger;

public interface ILogger
{
    void Write(string text);
}

public static class LoggerExtensions
{
    public static void Write(this ILogger logger, string format, params object[] args)
    {
        if (logger != null)
            logger.Write(string.Format(format, args));
    }
}
  • के रूप में उपयोग :
    var logger = new MyLoggerImplementation();
    logger.Write("{0}: {1}", "kiddo sais", "Mam mam mam mam ...");
    logger.Write("{0}: {1}", "kiddo sais", "Ma ma ma ma... ");
    logger.Write("{0}: {1}", "kiddo sais", "Mama mama mama mama ");
    logger.Write("{0}: {1}", "kiddo sais", "Mamma mamma mamma ... ");
    logger.Write("{0}: {1}", "kiddo sais", "Elisabeth Lizzy Liz...");
    logger.Write("{0}: {1}", "mamma sais", "WHAT?!?!!!");
    logger.Write("{0}: {1}", "kiddo sais", "hi.");
    


बेहतर ढीला युग्मन

विस्तार विधियाँ क्लास लाइब्रेरी के उपयोगकर्ताओं को उस लाइब्रेरी से आने वाले किसी प्रकार के तर्क, चर, या किसी अन्य चीज़ की घोषणा करने से परहेज करने की अनुमति देती हैं। क्लास लाइब्रेरी में उपयोग किए जाने वाले प्रकारों का निर्माण और रूपांतरण विस्तार विधियों के रूप में कार्यान्वित किया जा सकता है। रूपांतरणों और फैक्टरी को ध्यान से लागू करने के बाद, एक क्लास लाइब्रेरी से दूसरे में स्विचन करना उतना ही आसान बनाया जा सकता है जितना कि यूज़िंग स्टेटमेंट को बदलना जो संकलक को संगठित करने के लिए विस्तार विधि उपलब्ध कराता है।

धाराप्रवाह अनुप्रयोग क्रमादेशक के अंतरापृष्ठ

तथाकथित धाराप्रवाह अंतरापृष्ठ को लागू करने में विस्तार विधियों का विशेष उपयोग होता है। एक उदाहरण माइक्रोसॉफ्ट का इकाई संरचना संरूपण एपीआई है, जो उदाहरण के लिए कूट लिखने की अनुमति देता है जो नियमित अंग्रेजी के समान व्यवहारिक रूप से मिलता-जुलता है।

कोई यह तर्क दे सकता है कि विस्तार विधियों के बिना यह उतना ही संभव है, लेकिन कोई यह पाएगा कि व्यवहार में, विस्तार विधियां एक बेहतर अनुभव प्रदान करती हैं क्योंकि इसे काम करने के लिए वर्ग पदानुक्रम पर कम बाधाएं रखी जाती हैं - और वांछित के रूप में पढ़ा जाता है।

निम्न उदाहरण इकाई संरचना का उपयोग करता है और आँकड़ासंचय तालिका में संग्रहीत करने के लिए TodoList क्लास को समनुरूप करता है और प्राथमिक और बाह्य कुंजी को सूचीबद्ध करता है और परिभाषित करता है। कूट को कमोबेश इस तरह समझा जाना चाहिए: एक TodoList के पास कुंजी TodoListID है, इसकी इकाई सेट का नाम सूचियाँ है और इसमें कई TodoItem हैं जिनमें से प्रत्येक के लिए एक आवश्यक TodoList है।

public class TodoItemContext : DbContext 
{
    public DbSet<TodoItem> TodoItems { get; set; }
    public DbSet<TodoList> TodoLists { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder) 
    {
        base.OnModelCreating(modelBuilder);
        modelBuilder.Entity<TodoList>()
                    .HasKey(e => e.TodoListId)
                    .HasEntitySetName("Lists")
                    .HasMany(e => e.Todos)
                    .WithRequired(e => e.TodoList);
    }
}


उत्पादकता

उदाहरण के लिए विचार करें IEnumerable और इसकी सादगी पर ध्यान दें - केवल एक विधि है, फिर भी यह LINQ का कम या ज्यादा आधार है . Microsoft .NET में इस अंतरापृष्ठ के कई कार्यान्वयन हैं। फिर भी, जाहिर है, सिस्टम में परिभाषित तरीकों की पूरी श्रृंखला को लागू करने के लिए इनमें से प्रत्येक कार्यान्वयन की आवश्यकता बोझिल होगी। .Linq नामस्थान IEnumerables पर काम करने के लिए, भले ही Microsoft के पास सभी स्रोत कूट हों। इससे भी बदतर, इसके लिए Microsoft के अलावा सभी को उन सभी तरीकों को लागू करने के लिए IEnumerable का उपयोग करने पर विचार करने की आवश्यकता होगी, जो इस बहुत ही सामान्य अंतरापृष्ठ के व्यापक उपयोग को देखते हुए बहुत ही विरोधी होते। इसके बजाय, इस अंतरापृष्ठ की एक विधि को लागू करके, LINQ को तुरंत कम या ज्यादा इस्तेमाल किया जा सकता है। विशेष रूप से व्यावहारिक रूप से अधिकांश मामलों में देखने पर IEnumerable की GetEnumerator विधि को एक निजी संग्रह, सूची या सरणी के GetEnumerator कार्यान्वयन के लिए प्रत्यायोजित किया जाता है।

public class BankAccount : IEnumerable<decimal> 
{
    private List<Tuple<DateTime, decimal>> credits; // assumed all negative
    private List<Tuple<DateTime, decimal>> debits; // assumed all positive

    public IEnumerator<decimal> GetEnumerator() 
    {
        var query = from dc in debits.Union(credits) 
                    orderby dc.Item1 /* Date */ 
                    select dc.Item2; /* Amount */
    
        foreach (var amount in query)
            yield return amount;
    }
}
// given an instance of BankAccount called ba and a using System.Linq on top of the current file,
// one could now write ba.Sum() to get the account balance, ba.Reverse() to see most recent transactions first,
// ba.Average() to get the average amount per transaction, etcetera - without ever writing down an arithmetic operator


प्रदर्शन

उस ने कहा, प्रदर्शन को बेहतर बनाने के लिए, या अलग-अलग कार्यान्वित अंतरापृष्ठ कार्यान्वयन से निपटने के लिए एक विस्तार विधि द्वारा प्रदान की गई सुविधा के अतिरिक्त कार्यान्वयन को जोड़ा जा सकता है, जैसे कि संकलक को विशेष रूप से सरणियों के लिए IEnumerable का कार्यान्वयन प्रदान करना (System.SZArrayHelper में), जो कि यह स्वचालित रूप से सरणी टाइप किए गए संदर्भों पर विस्तारक विधि कॉल के लिए चयन करेगा, क्योंकि उनका तर्क विस्तारक विधि की तुलना में अधिक विशिष्ट होगा (यह T [] मान) उसी नाम के साथ विस्तारक विधि से जो IEnumerable अंतरापृष्ठ (यह IEnumerable मान) के उदाहरणों पर संचालित होता है।

एक सामान्य आधार वर्ग की आवश्यकता को कम करना

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

रूढ़िवादी उपयोग

पुन: उपयोग और उचित वस्तु-उन्मुख अभिकलन प्राप्त करने के अन्य साधनों पर विस्तार विधियों को प्राथमिकता देने पर ध्यान दिया जाना चाहिए। विस्तारक विधियां कूट संपादकों की स्वत: पूर्ण होने वाली विशेषताओं को 'अव्यवस्था' कर सकती हैं, जैसे कि विज़ुअल स्टूडियो का इंटेलीसेंस, इसलिए उन्हें या तो अपने स्वयं के नामस्थान में होना चाहिए ताकि विकासक उन्हें चुनिंदा रूप से आयात कर सकें या उन्हें एक प्रकार पर परिभाषित किया जाना चाहिए जो कि विशिष्ट के लिए पर्याप्त है इंटेलीसेंस में प्रकट होने की विधि केवल तभी जब वास्तव में प्रासंगिक हो और ऊपर दी गई हो, इस बात पर विचार करें कि यदि विकासक उनसे अपेक्षा करता है तो उन्हें खोजना मुश्किल हो सकता है, लेकिन लापता उपयोग कथन के कारण उन्हें इंटेलीसेंस से याद कर सकते हैं, क्योंकि विकासक ने विधि को संबद्ध नहीं किया हो सकता है उस वर्ग के साथ जो इसे परिभाषित करता है, या यहां तक ​​​​कि नामस्थान जिसमें यह रहता है - बल्कि उस प्रकार के साथ जो इसे विस्तारित करता है और नामस्थान जो टाइप करता है।

समस्या

प्रोग्रामिंग में, ऐसी परिस्थितियाँ उत्पन्न होती हैं जहाँ किसी मौजूदा वर्ग में कार्यक्षमता जोड़ना आवश्यक होता है - उदाहरण के लिए एक नई विधि जोड़कर, आम तौर पर क्रमादेशित्र मौजूदा वर्ग के स्रोत कूट को संशोधित करेगा, लेकिन यह क्रमादेशित्र को इन नए परिवर्तनों के साथ सभी निष्पादन योग्य को संकलित करने के लिए मजबूर करता है और इसके लिए आवश्यक है कि क्रमादेशित्र वर्ग को संशोधित करने में सक्षम हो, जो हमेशा संभव नहीं होता है, उदाहरण के लिए तीसरे से क्लास का उपयोग करते समय -पार्टी कोड़ांतरण (सीएलआई)। यह आम तौर पर तीन तरीकों में से एक में काम किया जाता है, जिनमें से सभी कुछ हद तक सीमित और अनजान हैं[citation needed]:

  1. क्लास को इनहेरिट करें और फिर व्युत्पन्न क्लास में उदाहरण विधि में कार्यक्षमता को लागू करें।
  2. सहायक वर्ग में जोड़े गए स्थिर तरीकों में कार्यक्षमता को लागू करें।
  3. विरासत (अभिकलित्र विज्ञान) के बजाय वस्तु रचना # एकत्रीकरण का उपयोग करें।

वर्तमान C # समाधान

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

उदाहरण के तौर पर, स्ट्रिंग क्लास को एक नई रिवर्स विधि के साथ विस्तारित करने की आवश्यकता पर विचार करें जिसका वापसी मूल्य उल्टे क्रम में वर्णों के साथ एक स्ट्रिंग है। चूंकि स्ट्रिंग क्लास एक मुहरबंद प्रकार है, विधि आमतौर पर एक नई उपयोगिता वर्ग में निम्न के समान तरीके से जोड़ दी जाएगी:

string x = "some string value";
string y = Utility.Reverse(x);

हालाँकि, उपयोगिता विधियों और क्लासओं के लाइब्रेरी के रूप में नेविगेट करना तेजी से कठिन हो सकता है, विशेष रूप से नए लोगों के लिए। स्थान भी कम सहज है, क्योंकि अधिकांश स्ट्रिंग विधियों के विपरीत, यह स्ट्रिंग क्लास का सदस्य नहीं होगा, बल्कि पूरी तरह से अलग वर्ग में होगा। इसलिए एक बेहतर सिंटैक्स निम्नलिखित होगा:

string x = "some string value";
string y = x.Reverse();


वर्तमान VB.NET समाधान

अधिकांश तरीकों से, VB.NET समाधान उपरोक्त C# समाधान के समान है। हालाँकि VB.NET का एक अनूठा लाभ है कि यह सदस्यों को संदर्भ द्वारा विस्तार में पारित करने की अनुमति देता है (C# केवल मूल्य द्वारा अनुमति देता है)। निम्नलिखित के लिए अनुमति देना;

Dim x As String = "some string value"
x.Reverse()

क्योंकि विज़ुअल बेसिक स्रोत वस्तु को संदर्भ द्वारा पारित करने की अनुमति देता है, इसलिए किसी अन्य चर को बनाने की आवश्यकता के बिना सीधे स्रोत वस्तु में परिवर्तन करना संभव है। यह अधिक सहज भी है क्योंकि यह क्लासओं के मौजूदा तरीकों के अनुरूप काम करता है।

विस्तार के तरीके

सी # 3.0 में विस्तार विधियों की नई भाषा सुविधा, हालांकि, बाद वाले कूट को संभव बनाती है। इस दृष्टिकोण के लिए निम्नानुसार एक स्थिर वर्ग और एक स्थिर विधि की आवश्यकता होती है।

public static class Utility
{
    public static string Reverse(this string input)
    {
        char[] chars = input.ToCharArray();
        Array.Reverse(chars);
        return new String(chars);
    }
}

परिभाषा में, पहले तर्क से पहले संशोधक 'यह' निर्दिष्ट करता है कि यह एक विस्तार विधि है (इस मामले में 'स्ट्रिंग' टाइप करने के लिए)। एक कॉल में, पहला तर्क 'पास इन' नहीं होता है क्योंकि इसे पहले से ही 'कॉलिंग' वस्तु (डॉट से पहले की वस्तु) के रूप में जाना जाता है।

कॉलिंग विस्तारक विधियों और स्टेटिक हेल्पर विधियों को कॉल करने के बीच प्रमुख अंतर यह है कि स्थिर विधियों को पोलिश संकेतन में कहा जाता है, जबकि विस्तारक विधियों को इंफिक्स नोटेशन में कहा जाता है। उत्तरार्द्ध अधिक पठनीय कूट की ओर जाता है जब एक ऑपरेशन के परिणाम का उपयोग दूसरे ऑपरेशन के लिए किया जाता है।

स्थिर विधियों के साथ:

HelperClass.Operation2(HelperClass.Operation1(x, arg1), arg2)

विस्तार विधियों के साथ:

x.Operation1(arg1).Operation2(arg2)


विस्तार विधियों और उदाहरण विधियों में नामकरण विरोध

सी # 3.0 में, एक वर्ग के लिए एक ही हस्ताक्षर के साथ एक उदाहरण विधि और एक विस्तार विधि दोनों मौजूद हो सकते हैं। ऐसे परिदृश्य में, उदाहरण विधि को विस्तार विधि से अधिक पसंद किया जाता है। नामकरण विरोध के बारे में न तो संकलक और न ही Microsoft Visual Studio IDE चेतावनी देता है। इस C# वर्ग पर विचार करें, जहाँ GetAlphabet() इस वर्ग के उदाहरण पर विधि लागू की जाती है:

class AlphabetMaker 
{
    public void GetAlphabet()       
    {                               //When this method is implemented,
        Console.WriteLine("abc");   //it will shadow the implementation
    }                               //in the ExtensionMethods class.
}

static class ExtensionMethods
{
    public static void GetAlphabet(this AlphabetMaker am)   
    {                               //This will only be called                       
        Console.WriteLine("ABC");   //if there is no instance
    }                               //method with the same signature.   
}

आवाहन करने का परिणाम GetAlphabet() के उदाहरण पर AlphabetMaker अगर केवल विस्तार विधि मौजूद है:

एबीसी

परिणाम यदि उदाहरण विधि और विस्तार विधि दोनों मौजूद हैं:

एबीसी

यह भी देखें

संदर्भ

  1. "विस्तार के तरीके". Microsoft. Retrieved 2008-11-23.
  2. "Extensions — The Swift Programming Language (Swift 5.7)". docs.swift.org. Retrieved 2022-06-12.


बाहरी संबंध