2009-10-29 12 views
6

में विस्तार विधियों का उपयोग करने की लागत/लाभ का मूल्यांकन करना क्या परिस्थितियों (उपयोग परिदृश्य) आप किसी ऑब्जेक्ट को उप-वर्गीकृत करने के बजाय एक्सटेंशन लिखना चुनेंगे?सी # => 3.0

< पूर्ण प्रकटीकरण: मैं एक एमएस कर्मचारी नहीं हूं; मैं व्यक्तिगत रूप से मित्सु फुरोटा नहीं जानता; मैं यहां उल्लिखित ओपन-सोर्स कंपोनैक्स लाइब्रेरी के लेखक को जानता हूं, लेकिन मेरे पास उनके साथ कोई व्यापारिक व्यवहार नहीं है; मैं विस्तार नहीं कर रहा हूं, या एक्सटेंशन का उपयोग करके कोई वाणिज्यिक उत्पाद बनाने की योजना नहीं बना रहा हूं: योग में: यह पोस्ट शुद्ध बौद्धिक जिज्ञासा से है (लगातार) "सर्वोत्तम प्रथाओं" के बारे में जागरूक हो जाती है>

मुझे यह विचार मिलता है विस्तार विधियां "शांत", और स्पष्ट रूप से आप उनके साथ "दूर-दूर" चीजें कर सकते हैं जैसे कि मित्सु फूरोटा (एमएस) ब्लॉग पोस्ट link text में आप कई उदाहरणों में कर सकते हैं।

एक निजी मित्र ने ओपन-सोर्स कंपोनैक्स लाइब्रेरी link text लिखा, और वहां कुछ उल्लेखनीय सुविधाएं हैं; लेकिन वह कोड छोटी दिशाओं पर कुल नियंत्रण के साथ अपनी छोटी कंपनी के पूर्ण आदेश में है, और कोड की हर पंक्ति "अपने हाथों से गुज़रती है।"

हालांकि यह मेरे हिस्से पर अटकलें है: मुझे लगता है कि अनुमान लगाया जा सकता है कि अन्य मुद्दों को मध्यम-से-बड़ी सॉफ़्टवेयर टीम की स्थिति में विस्तार का उपयोग किया जा सकता है।

link text में एमएस के दिशा निर्देशों को देखते हुए, आप पाते हैं:

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

और एमएस के link text पर:

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

कारक है कि मेरे लिए स्पष्ट प्रतीत शामिल होंगे:

  1. मुझे लगता है जब तक आप उम्मीद यह बहुत आम तौर पर और बहुत बार इस्तेमाल किया जा अगर आप एक्सटेंशन नहीं लिखेंगे।दूसरी ओर: क्या आप उप-वर्गीकरण के बारे में एक ही बात नहीं कह सकते?

  2. जानना हम उन्हें एक अलग डीएल में संकलित कर सकते हैं, और संकलित डीएलएल जोड़ सकते हैं, और इसका संदर्भ ले सकते हैं, और फिर एक्सटेंशन का उपयोग करें: "ठंडा" है, लेकिन क्या यह पहले संकलक में निहित लागत को "शेष" करता है यह देखने के लिए जांच करनी है कि उपरोक्त वर्णित उदाहरण विधियों को परिभाषित किया गया है या नहीं। या लागत, "नाम संघर्ष" के मामले में, स्टेटिक आमंत्रण विधियों का उपयोग करने के लिए यह सुनिश्चित करने के लिए कि आपका एक्सटेंशन आवृत्ति परिभाषा के बजाय बुलाया गया हो?

एक्सटेंशन का कितनी बार उपयोग रन-टाइम प्रदर्शन या स्मृति उपयोग को प्रभावित करेगा: मुझे कोई जानकारी नहीं है।

तो, मैं आपके विचारों की सराहना करता हूं, या आप कैसे/कब करते हैं, या नहीं करते हैं, उप-वर्गीकरण की तुलना में एक्सटेंशन का उपयोग करते हैं।

धन्यवाद, बिल

+1

बहुत सारे और अन्य एक ही विषय को कवर कई प्रश्न: http://stackoverflow.com/questions/487904/what-advantages-of-extension-methods-have-you-found – snicker

+1

"कैसे लगातार एक्सटेंशन का प्रयोग करेंगे रन-टाइम प्रदर्शन या स्मृति उपयोग को प्रभावित करें: मुझे कोई जानकारी नहीं है। " - यह किसी भी तरह से किसी को प्रभावित नहीं करता है। एक स्थैतिक विधि आविष्कार बिल्कुल गैर-आभासी, गैर-इंटरफ़ेस उदाहरण विधि के आविष्कार के समान ही तर्क के समान होता है (बाद के मामले में अंतर्निहित 'यह' गिनती)। –

उत्तर

10

उनके लिए मेरे सबसे बड़ी उपयोग बंद बंद 3 पार्टी एपीआई का विस्तार करने के लिए है।

अधिकांश समय, जब एक सॉफ्टवेयर डेवलपर इन दिनों विंडोज पर एक एपीआई पेश कर रहा है, तो वे उस विस्तार के लिए .NET की ओर अधिक से अधिक झुका रहे हैं। मुझे ऐसा करना पसंद है क्योंकि मैं अपने स्वयं के तरीकों पर निर्भर होना पसंद करता हूं जिसे मैं भविष्य में संशोधित कर सकता हूं और उनके एपीआई को वैश्विक प्रविष्टि बिंदु के रूप में कार्य करता हूं, अगर वे इसे बदल देते हैं।

पहले, जब यह करने के लिए हो रही है, और मैं एपीआई वस्तु के वारिस नहीं कर सकता है, क्योंकि यह सील किया गया था या कुछ और, मैं Adapter pattern पर भरोसा करते हैं मेरे अपने वर्गों है कि उनके वस्तुओं की समाप्ति के बनाने के लिए होगा। यह एक कार्यात्मक, बल्कि बल्कि सुरुचिपूर्ण समाधान है। विस्तार विधियां आपको उस चीज़ पर अधिक कार्यक्षमता जोड़ने का एक सुंदर तरीका देती हैं जिसे आप नियंत्रित नहीं करते हैं।

उनके लिए कई अन्य लोगों का सबसे बड़ा उपयोग LINQ है!

LINQ IENumerable को प्रदान किए गए एक्सटेंशन विधियों के बिना संभव नहीं होगा।

लोग उन्हें प्यार क्यों करते हैं क्योंकि वे कोड को और अधिक पठनीय बनाते हैं।

मैं विस्तार तरीकों का एक अन्य प्रमुख उपयोग पर ध्यान दिया है (अपने आप को शामिल) कोड अधिक पठनीय बनाने के लिए, और यह जाहिर होता है जैसे कि कोड कुछ अंतर्गत आता है जहां यह माना जाता है ऐसा करने के लिए बनाने के लिए है। यह डरावनी "यूटिल" स्थैतिक-देवता-वर्ग से भी छुटकारा पाता है जिसे मैंने कई बार देखा है। क्या बेहतर दिखता है ... Util.DecimalToFraction(decimal value); या value.ToFraction();? यदि आप मेरे जैसे हैं, उत्तरार्द्ध।

अंत में, ऐसे लोग हैं जो "स्थिर विधि" को EVIL मानते हैं!

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

प्रदर्शन के बारे में ..

विस्तार के तरीकों के लिए एक स्थिर विधि बुला, गुजर वस्तु एक पैरामीटर के रूप बढ़ाया जा रहा ... क्योंकि है कि क्या संकलक यह में बदल जाता है से अलग नहीं कर रहे हैं। इसके बारे में बड़ी बात यह है कि आपका कोड साफ दिखता है, यह वही करता है जो आप चाहते हैं, और संकलक आपके लिए गंदे काम को संभालता है।

+0

धन्यवाद, स्निकर, इस विचारशील उत्तर के लिए, और आपकी टिप्पणी में SO पर अन्य संदेशों का लिंक। मैंने उन कई अन्य पोस्ट पढ़ीं, लेकिन फिर भी मुझे अपने "स्वाद" प्रश्न पूछने की आवश्यकता महसूस हुई। मैं पहले से ही स्टेटिक विधियों, फ़ील्ड इत्यादि का उपयोग करने का एक "प्रशंसक" हूं, और, मेरे लिए, आपके द्वारा उठाए गए पठनीयता की समस्या विस्तार विधियों का उपयोग करने के लिए एक निश्चित प्रेरणा है। यदि हम कभी एक्सटेंशन गुण प्राप्त करते हैं, तो मैं भी इसके लिए तैयार हूं :) सर्वश्रेष्ठ, बिल - बिलडब्ल्यू 0 सेकंड पहले – BillW

1

कुछ मामलों में आप उप-वर्ग का उपयोग नहीं कर सकते हैं: उदाहरण के लिए स्ट्रिंग सील कर दी गई है। हालांकि आप अभी भी विस्तार विधियां जोड़ सकते हैं।

2

बनाम विस्तार तरीकों उप classing दृष्टिकोण लेते चीजों के एक जोड़े सच

  1. प्रकार बढ़ाई (नहीं-सील)
  2. सभी स्थानों प्रकार एक का समर्थन करना चाहिए बनाई गई है होना चाहिए होने की आवश्यकता है प्रकार या अन्य कोड का कारखाना पैटर्न सिर्फ आधार प्रकार बनायेगा।

एक विस्तार विधि जोड़ने के लिए वास्तव में सी # 3.0+ कंपाइलर का उपयोग करने के अलावा कुछ भी नहीं चाहिए।

लेकिन सबसे महत्वपूर्ण बात यह है कि विरासत पदानुक्रम को एक रिश्ते का प्रतिनिधित्व करना चाहिए। मुझे नहीं लगता कि इस प्रकार के रिश्ते को वास्तव में व्यक्त करने वाले वर्ग में 1 या 2 नई विधियों/व्यवहार जोड़ना। यह मौजूदा व्यवहार को बढ़ाने के बजाय है। एक रैपर वर्ग या विस्तार विधि परिदृश्य फिट बैठता है।

4

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

Min() और Max() विस्तार विधियां इस के महान उदाहरण हैं। आप आसानी से एक निजी विधि घोषित कर सकते हैं जो इनकी गणना करेगा, लेकिन एक विस्तार विधि बेहतर पठनीयता प्रदान करती है, जिससे कार्यक्षमता आपके पूरे प्रोजेक्ट में उपलब्ध हो जाती है, और किसी ऑब्जेक्ट को किसी सरणी को बनाने की आवश्यकता नहीं होती है।