2009-05-30 8 views
6

Similar question but not quite the same thingसी # में इंटरफेस पर एक्सटेंशन विधियों के साथ छद्म-बहु-विरासत?

मैं सोच रहा था इंटरफेस के रूप में एक ही नाम स्थान में विस्तार के तरीकों के साथ आपको लगता है कि में एकाधिक वंशानुक्रम के लिए एक समान प्रभाव आप डुप्लिकेट कोड एक ही इंटरफ़ेस को लागू करने में 10 में एक ही तरीका है की जरूरत नहीं है हो सकता है कि विभिन्न वर्ग

ऐसा करने के कुछ डाउनसाइड्स क्या हैं? मुझे लगता है कि पेशेवर बहुत स्पष्ट हैं, यह वह विपक्ष है जो आम तौर पर बाद में आपको काटने के लिए वापस आती है।

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

उत्तर

4

विस्तार विधियों के माध्यम से इंटरफ़ेस क्षमता निर्माण के साथ जो समस्या मैं देखता हूं वह यह है कि अब आप वास्तव में इंटरफ़ेस को कार्यान्वित नहीं कर रहे हैं और इसलिए ऑब्जेक्ट को इंटरफ़ेस प्रकार के रूप में उपयोग नहीं कर सकते हैं।

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

यदि मुझे कई विरासत की आवश्यकता है (और अब तक मैं इसके बिना रहता हूं) बुरी तरह से, मुझे लगता है कि मैं कोड डुप्लिकेशन की मात्रा को कम करने के लिए संरचना का उपयोग करूंगा।

+0

क्या आप समझा सकते हैं "तो फू आईबार से नहीं निकलता है और इसका उपयोग एक दूसरे के साथ नहीं किया जा सकता"? यदि मेरे पास सार्वजनिक कक्षा है Foo: IBar, क्या कोई भी आईबीआर की अपेक्षा कहीं भी किसी फू में पास नहीं कर पाएगा? या आप कुछ अलग मतलब था? मुझे एहसास है कि यह एक इंटरफ़ेस के रूप में कार्य करना बंद कर देता है। कार्यात्मक रूप से मैं इसे एक ठोस बेस क्लास की तरह अभिनय करता हूं जिसमें इंटरफ़ेस की तुलना में वर्चुअल विधियां नहीं हैं।(चाहे यह एक अच्छा विचार है या नहीं, संभवतः एक अलग सवाल है, लेकिन यह DRY रखने के लिए उपयोगी लगता है) – Davy8

+0

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

+0

यदि फू आईबीर से निकला है तो उसे इबार को लागू करने वाले विस्तार विधियों के उदाहरण के तरीकों की आवश्यकता नहीं है। क्या आप विस्तार विधियों में इन विधियों को प्रतिनिधि करने की उम्मीद कर रहे हैं? मैं मान रहा था कि कार्यान्वयन केवल एक्सटेंशन द्वारा प्रदान किया गया था। यदि आप प्रतिनिधिमंडल कर रहे हैं, तो मुझे लगता है कि इच्छित इंटरफ़ेस कार्यक्षमता को लागू करने वाले बेस क्लास की संरचना विस्तार विधियों से अधिक बेहतर है। शायद आप सजावटी पैटर्न का उपयोग कर कार्यक्षमता प्रदान कर सकते हैं। – tvanfosson

1

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

एक इंटरफ़ेस घोषित करता है "मुझे इस कार्यक्षमता का उपयोग करने की परवाह है, लेकिन यह कैसे पूरा नहीं किया जाता है।" इससे कार्यान्वयनकर्ताओं को यह चुनने की आजादी मिलती है कि कैसे। यह तंत्र से, एक सार्वजनिक एपीआई, तंत्र से, कंक्रीट कोड के साथ एक वर्ग decouples।

चूंकि यह इंटरफेस का मुख्य लाभ है, उन्हें पूरी तरह कार्यान्वित करना क्योंकि विस्तार विधियां उनके उद्देश्य को हराने के लिए प्रतीत होती हैं। यहां तक ​​कि IEnumerable<T> में एक उदाहरण विधि है।

संपादित करें: इसके अलावा, ऑब्जेक्ट्स उनके डेटा में कार्य करने के लिए हैं। एक्सटेंशन विधियां केवल एक ऑब्जेक्ट की सार्वजनिक API देख सकती हैं (क्योंकि वे केवल स्थिर विधियां हैं); आपको इसे कार्य करने के लिए किसी ऑब्जेक्ट की स्थिति का खुलासा करना होगा (ओओ नो-नो)।

+0

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

+0

ठीक है, मैं देख रहा हूं कि आप क्या पूछ रहे हैं। अंततः आप उन वर्गों के व्यवहार को जोड़ना चाहते हैं जो एक इंटरफ़ेस को लागू करके "ऑप्ट इन" करते हैं। एकाधिक इंटरफेस = एकाधिक व्यवहार = एकाधिक विरासत। अच्छा तर्क, लेकिन इसका क्या मतलब है? आपको अभी भी किसी ऑब्जेक्ट की स्थिति का खुलासा करना है ताकि एक्सटेंशन विधियां इसके साथ काम कर सकें। लेकिन अब कोई भी उस राज्य को देख सकता है, इसलिए कोई encapsulation नहीं। फिर भी, विधि केवल एक आईबीर प्राप्त करेगी, जिसमें कोई सदस्य नहीं है, और इस प्रकार यह बहुत उपयोगी नहीं है। विस्तार विधियां क्या कर सकती हैं? @tvanfosson के रूप में, रचना आपकी सबसे अच्छी शर्त है। –

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