2011-11-08 14 views
7

क्या दो अद्वितीय जेनेरिक पैरामीटर को बाधित कक्षा को कार्यान्वित करना संभव है?दो गैर-बराबर (अद्वितीय) प्रकारों वाला एक सामान्य वर्ग

यदि ऐसा नहीं है, तो क्या यह अनुपूरक है या क्योंकि भाषा संरचना (विरासत) को असंभव होगा?

class BidirectionalMap<T1,T2> where T1 != T2 
{ 
    ... 
} 

मैं एक Bidirectional dictionary को लागू कर रहा हूँ:

मैं फार्म की कुछ करना चाहते हैं। यह ज्यादातर जिज्ञासा का सवाल है, जरूरत नहीं है।


भावानूदित टिप्पणियों से:

  1. दान: "अगर इस बाधा को पूरा नहीं कर रहा है नकारात्मक परिणाम क्या हैं"

  2. मी: "फिर उपयोगकर्ता मानचित्र [टी 1] और मानचित्र [टी 2] के साथ अनुक्रमित कर सकता है। यदि वे एक ही प्रकार के थे, तो कोई भेद नहीं होगा और इससे कोई अर्थ नहीं होगा।"

  3. दान: संकलक वास्तव में [दो सामान्य प्रकार पैरामीटर को अलग विधि ओवरलोड को परिभाषित करने की अनुमति देता है], इसलिए मैं उत्सुक हूं; क्या यह मनमाने ढंग से कॉल करने के तरीकों में से एक चुनता है?

+1

आप हमेशा निर्माता को 'नया चाहिएबीकंपाइलटाइम एरर()' फेंक सकते हैं । :-) – foson

+1

शायद क्योंकि यह समझ में नहीं आता है, वे जेनेरिक हैं, कुछ ऐसा जो कि प्रकारों द्वारा "बाधित" नहीं होना चाहिए। – GriffinHeart

+0

जिज्ञासा से, यदि इस बाधा को पूरा नहीं किया जाता है तो नकारात्मक परिणाम क्या हैं? एक ही सेट से वस्तुओं के बीच एक मैपिंग एक बहुत ही आम आवश्यकता है। –

उत्तर

4

समस्या को उजागर करने के उदाहरण पर विस्तार:

public class BidirectionalMap<T1,T2> 
{ 
    public void Remove(T1 item) {} 
    public void Remove(T2 item) {} 

    public static void Test() 
    { 
     //This line compiles 
     var possiblyBad = new BidirectionalMap<string, string>(); 

     //This causes the compiler to fail with an ambiguous invocation 
     possiblyBad.Remove("Something"); 
    } 
} 

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


एक तरफ नोट यह है कि अगर आप सावधान नहीं हैं तो इस तरह के ओवरलोडिंग से कुछ अजीब व्यवहार हो सकते हैं। यदि आप एक BidirectionalMap<Animal, Cat> और बिल्ली है, तो: पशु, पर विचार क्या इस कोड के साथ क्या होगा:

Animal animal = new Cat(); 
map.Remove(animal); 

यह, अधिभार कि पशु लेता फोन तो यह एक महत्वपूर्ण दूर करने की कोशिश करेंगे, भले ही आप करने का इरादा हो सकता है मूल्य बिल्ली हटा दें। यह कुछ हद तक कृत्रिम मामला है, लेकिन विधि ओवरलोडिंग के परिणामस्वरूप बहुत अलग व्यवहार होने पर सावधानी बरतने के लिए पर्याप्त है। ऐसे मामलों में, यदि आप अपने अलग-अलग व्यवहारों को प्रतिबिंबित करते हैं, तो अलग-अलग तरीकों को प्रतिबिंबित करना संभव है (निकालें और निकालें वैल्यू, मान लें।)

+0

उत्कृष्ट रूट उत्तर! त्रुटि पाठ: 'कॉल निम्न विधियों या गुणों के बीच संदिग्ध है: बिडरेक्शनल मैप । यह [टी]' और 'बिडरेक्शनल मैप । यह [के]'" – user664939

0

टाइप बाधाएं एक गलत नामक की तरह लगती हैं। जबकि वे टाइप पैरामीटर का विरोध करते हैं, इसका उद्देश्य संकलक को यह जानने के लिए है कि इस प्रकार के ऑपरेशन किस प्रकार उपलब्ध हैं।
यदि आप चाहते थे, तो आप एक बाधा हो सकती है जहां टी 1 और टी 2 दोनों अलग कंक्रीट बेस कक्षाओं से प्राप्त होते हैं, लेकिन मुझे नहीं लगता कि यह वही है जो आप चाहते हैं।

-1

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

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

0

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

प्रकार पैरामीटर की असमानता यह सत्यापित करने की तरह होगी कि विधि तर्क शून्य नहीं हैं। यह कार्यक्रम के तर्क का हिस्सा है, न कि इसकी प्रकार की सुरक्षा।

0

मुझे पूरी तरह से यकीन नहीं है कि यह एक वांछनीय संकलन समय जांच क्यों होगी। अनिवार्य रूप से बॉक्सिंग या तो मूल्य या मूल्य द्वारा शर्त को पारित करना संभव होगा, जिससे संकलन-समय की जांच बेकार हो।

कुछ विचार करने के लिए कुछ विचार करने की आवश्यकता है ... मैं किस त्रुटि को रोकने की कोशिश कर रहा हूं?

यदि आप दस्तावेज़ीकरण को पढ़ने से आलसी सह-कार्यकर्ता को रोक रहे हैं, तो केवल एक डीबग जोड़ें और अपवाद फेंक दें। इस तरह रिलीज कोड के लिए चेक हटाया जा सकता है उदा।

#if Debug 

if (T1 is T2 || T2 is T1) 
{ 
    throw new ArguementException(...); 
} 

#endif 

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

+0

आप इस चेक को जेनेरिक प्रकार के स्थिर कन्स्ट्रक्टर में भी डाल सकते हैं , इसलिए यह केवल एक बार चलाएगा। (आपकी जांच संकलित नहीं होगी, वैसे, क्योंकि 'is' ऑपरेटर का बायां तरफ एक ऑब्जेक्ट संदर्भ लेता है, एक प्रकार का नाम नहीं। आप चाहते हैं कि' if (typeof (T1) = = typeof (t2) ') – phoog

0

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

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