2009-12-12 19 views
5

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

मैं दो इंटरफेस है - उन्हें IOnline और IOffline फोन करते हैं।

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

तब मेरे पास कुछ विधियां हैं जो इन इंटरफेस के ठोस कार्यान्वयनकर्ताओं के खिलाफ काम करती हैं। कभी-कभी ये विधियां केवल एक प्रकार से निपटना चाहती हैं, न कि दूसरे।

काफी सरल:

public void DoStuff<T>(string foo) where T : IOnline {} 

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

public void DoStuff<T>(string foo) where T : IOnline, IOffline {} 

ही नाम के साथ दो अलग-अलग तरीकों को लागू करने की कोशिश कर रहा है, लेकिन विभिन्न बाधाओं में विफल रहता है के रूप में है वहाँ स्पष्ट अस्पष्टता मुद्दों - अधिक भार नहीं हम के बाद से पैरामीटर सूची में एक ही है (के बाद से वांछित व्यवहार के समान है)।

मैं प्रत्येक दो अलग अलग तरीकों के लिए दो अलग-अलग नाम, इस्तेमाल कर सकते हैं उचित बाधा के साथ है, लेकिन वह kludgy लगता है और अन्य बातों गधा ... साध्य में दर्द होने के लिए नीचे की ओर है, लेकिन आदर्श नहीं।

मुझे लगता है कि यहां कुछ ऐसा होना चाहिए जो मुझे याद आ रहा है ... मुझे सामान्य भूमि में पूरी तरह से सहज महसूस होता है लेकिन यह पहली बार है जब मुझे कभी भी पूरा करना पड़ता है और मुझे लगता है कि मैं ' मैं बस अपने पहियों एटीएम कताई।

उत्तर

8

आपके दूसरे उदाहरण के रूप में कई बाधाओं की आपूर्ति वास्तव में योजक है। MSDN page on generic constraints इस बारे में थोड़ा सा है।

क्या आप अपने दो इंटरफेस बेस इंटरफेस से प्राप्त कर सकते हैं, और आधार प्रकार के तरीकों को बाधित कर सकते हैं?

+0

पूरी तरह से ईमानदार होने के लिए, मैंने हाल ही में सीखा है कि सी # समर्थित इंटरफेस विरासत। देव काम के दस वर्षों में, जरूरत कभी खत्म नहीं हुई थी। इसे एक भंवर देना होगा और देखें कि आखिरकार मुझे वह जगह मिलती है जहां मुझे होना चाहिए। – bakasan

0

मुझे लगता है कि ऐसा करने के लिए .NET में मानक तरीका एक इंटरफेस है जिसमें आपके IOnline और IOffline फ़ंक्शंस दोनों शामिल हैं, और फिर कुछ गुण जो कहते हैं कि कौन से फ़ंक्शंस वास्तव में किसी विशिष्ट वर्ग में लागू होते हैं। आप इस पैटर्न को .NET में विभिन्न स्थानों पर देखते हैं जैसे एक सेक() विधि जो लागू हो सकती है या नहीं भी हो सकती है और एक कैनसीक प्रॉपर्टी जिसे आप परीक्षण कर सकते हैं।

शायद यह सबसे साफ ओओ डिज़ाइन नहीं है, लेकिन यह काम करता है।

+0

एक और तरीका अलग IOnline और IOffline इंटरफेस को परिभाषित करना है, और एक IOnlineAndOffline इंटरफ़ेस जो दोनों को विरासत में मिला है। यह दृष्टिकोण अच्छी तरह से काम करता है, बशर्ते कि कक्षाएं जो IOnline और IOffline दोनों को लागू करती हैं IOnlineAndOffline भी लागू करती हैं। यदि इंटरफेस के कई संयोजनों का उपयोग किया जा सकता है तो यह दृष्टिकोण थोड़ी गड़बड़ी हो जाती है। एक और दृष्टिकोण है जो बिना किसी संयोजन के विस्फोट के किसी भी इंटरफेस के लिए एक्स्टेंसिबल है, लेकिन यह सॉर्टा icky है। – supercat

+0

@supercat: मैं भूल गया था कि मैंने इसे पोस्ट किया था ... वाह एक साल बाद शून्य वोट! महोदय, मुझे लगता है कि मैं इसे ठीक करने के बजाय इसे हटा दूंगा लेकिन आपकी टिप्पणी के लिए धन्यवाद! –

+0

मुझे गैर-पदानुक्रमित इंटरफेस के साथ समझदारी से निपटने की कोशिश करने में कुछ रूचि है। Http://stackoverflow.com/questions/4373259/storing-an-object-that-implements-multiple-interfaces-and-derives-from-a- सुनिश्चित करें जो शायद मेरे कामकाज पर बहुत अधिक समय बिताता है, और पर्याप्त नहीं सवाल पर, और अगर मुझे कोई समझ हो तो मुझे बताएं। – supercat

0

कुछ संकलन-समय की जांच को खो देता है, लेकिन मैं इसके आसपास किसी भी तरह से नहीं देख सकता ...आप जो आप नहीं बल्कि प्रयोग करेंगे चुनने के लिए करते हैं, (मैं अपनी पसंद संभालने कर रहा हूँ ऑनलाइन होगा):

public void DoStuff<T>(string foo) 
{ 
    Type type = typeof(T); 
    if(type.GetInterfaces().Contains(typeof(IOnline))) 
     doStuffOnline<T>(foo); 
    else if(type.GetInterfaces().Contains(typeof(IOffline))) 
     doStuffOffline<T>(foo); 
    else 
     throw new Exception("T must implement either IOnline or IOffline"); 
} 

private void doStuffOnline<T>(string foo){ // can assume T : IOnline } 
private void doStuffOffline<T>(string foo){ // can assume T : IOffline } 
+0

कहना है कि मैं अन्य लोगों के साथ सहमत हूं हालांकि ... ऐसा करने के लिए बेहतर ओओपी तरीके, जैसे एक आधार इंटरफ़ेस ... – LorenVS

2

यह शायद अपने प्रश्न का उत्तर नहीं है, लेकिन मैं अनायास लग रहा है कि आप चाहते हो सकता है मिल अपने इंटरफेस को दोबारा करने के लिए। अपने प्रश्न से:

वे बारीकी से संबंधित रहे है कि वे लगभग समान अनुबंध, लेकिन के बीच मुख्य अंतर उन्हें संदर्भ में ठोस कार्यान्वयन इस्तेमाल किया जाएगा में से एक का वर्णन।

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

+0

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

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