मैं घोषणा-साइट और उपयोग-साइट भिन्नता के बीच मतभेदों का उत्तर देने जा रहा हूं, क्योंकि सी # और जावा जेनरिक कई अन्य तरीकों से भिन्न होते हैं, लेकिन अंतर भिन्नता के लिए अधिकतर ऑर्थोगोनल होते हैं।
सबसे पहले, अगर मुझे सही ढंग से उपयोग-साइट भिन्नता याद है तो घोषणा-साइट भिन्नता (हालांकि संयोजन की लागत पर) से कम शक्तिशाली है, या कम से कम जावा के वाइल्डकार्ड (जो वास्तव में उपयोग-साइट भिन्नता से अधिक शक्तिशाली हैं))। यह बढ़ी हुई शक्ति विशेष रूप से उन भाषाओं के लिए उपयोगी होती है जिनमें राज्यिक संरचनाओं का उपयोग भारी रूप से किया जाता है, जैसे कि सी # और जावा (लेकिन स्कैला बहुत कम है, खासकर जब से इसकी मानक सूचियां अपरिवर्तनीय हैं)। List<E>
पर विचार करें (या IList<E>
)। चूंकि इसमें ई को जोड़ने और ई प्राप्त करने के तरीकों के तरीके हैं, इसलिए यह ई के संबंध में परिवर्तनीय है, और इसलिए घोषणा-साइट भिन्नता का उपयोग नहीं किया जा सकता है। हालांकि, उपयोग-साइट भिन्नता के साथ आप List
के contravariant सबसेट प्राप्त करने के लिए List
और List<-Number>
के कॉन्वर्सट सबसेट प्राप्त करने के लिए केवल List<+Number>
कह सकते हैं। एक घोषणा-साइट भाषा में लाइब्रेरी के डिजाइनर को प्रत्येक सबसेट के लिए अलग-अलग इंटरफेस (या कक्षाएं यदि आप कक्षाओं के एकाधिक विरासत की अनुमति देते हैं) बनाना होगा और List
उन इंटरफेस का विस्तार करें। यदि लाइब्रेरी डिज़ाइनर ऐसा नहीं करता है (ध्यान दें कि सी # IEnumerable
केवल IList
के कॉन्विएन्ट भाग का एक छोटा सबसेट करता है), तो आप भाग्य से बाहर हैं और आपको बिना किसी परेशानी के एक भाषा में करना होगा किसी प्रकार का भिन्नता।
तो घोषणा-साइट विरासत पर उपयोग-साइट विरासत के फायदे हैं। उपयोग-साइट विरासत पर घोषणा-स्थल विरासत का लाभ मूल रूप से उपयोगकर्ता के लिए संक्षिप्त है (बशर्ते डिजाइनर प्रत्येक वर्ग/इंटरफ़ेस को अपने कॉन्वर्सेंट और contravariant भागों में अलग करने के प्रयास के माध्यम से चला गया)। IEnumerable
या Iterator
जैसे कुछ के लिए, इंटरफ़ेस का उपयोग करने पर हर बार कॉन्वर्सिस निर्दिष्ट करना अच्छा नहीं है। जावा ने इसे एक लंबे वाक्यविन्यास का उपयोग करके विशेष रूप से परेशान कर दिया (बिविरिएंस को छोड़कर जिसके लिए जावा का समाधान मूल रूप से आदर्श है)।
बेशक, ये दो भाषा विशेषताएं सह-अस्तित्व में रह सकती हैं। टाइप पैरामीटर के लिए जो स्वाभाविक रूप से कॉन्वर्सेंट या contravariant (जैसे IEnumerable
/Iterator
में) हैं, घोषणा में ऐसा घोषित करें। स्वाभाविक रूप से इनवेरिएंट (जैसे कि (I)List
) के प्रकार पैरामीटर के लिए, यह घोषणा करें कि प्रत्येक बार जब आप इसका उपयोग करते हैं तो आप किस तरह का भिन्नता चाहते हैं। घोषणा-साइट भिन्नता के साथ तर्कों के लिए बस उपयोग-साइट भिन्नता निर्दिष्ट न करें क्योंकि इससे चीजों को भ्रमित कर दिया जाता है।
ऐसे कई और विस्तृत मुद्दे हैं जिनमें मैं नहीं गया हूं (जैसे वाइल्डकार्ड वास्तव में उपयोग-साइट भिन्नता से अधिक शक्तिशाली हैं), लेकिन मुझे उम्मीद है कि यह आपकी सामग्री को आपके प्रश्न का उत्तर देगा। मैं मानता हूं कि मैं उपयोग-साइट भिन्नता की ओर पक्षपातपूर्ण हूं, लेकिन मैंने प्रोग्रामर और भाषा शोधकर्ताओं के साथ मेरी चर्चाओं में दोनों के प्रमुख फायदे चित्रित करने की कोशिश की।
स्रोत
2011-03-29 22:19:39
इस प्रश्न को छूने वाला एक पेपर: http://cgi.di.uoa.gr/~smaragd/varj-ecoop12.pdf – Aivar