2011-08-03 16 views
19

इस प्रतिरूप के लिए एक नाम है?क्या इस पैटर्न के लिए कोई नाम है? ("पैरामीटर" विभिन्न प्रकार के आर्ग के साथ सी # संकलन समय प्रकार- सुरक्षा)

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

void MyMethod (params object[] args) 
{ 
    foreach (object arg in args) 
    { 
     if (arg is SomeType) 
      DoSomethingWith((SomeType) arg); 
     else if (arg is SomeOtherType) 
      DoSomethingElseWith((SomeOtherType) arg); 
     // ... etc. 
     else throw new Exception("bogus arg"); 
    } 
} 

हालांकि की है कि, मेरे जैसे, आप संकलन समय प्रकार सुरक्षा से ग्रस्त रहे हैं का कहना है, और संकलन समय पर अपनी विधि के तर्क प्रकार को सत्यापित करने में सक्षम होना चाहते हैं।

void MyMethod (params MyArg[] args) 
{ 
    // ... etc. 
} 

struct MyArg 
{ 
    public readonly object TheRealArg; 

    private MyArg (object obj) { this.TheRealArg = obj; } 

    // For each type (represented below by "GoodType") that you want your 
    // method to accept, define an implicit cast operator as follows: 

    static public implicit operator MyArg (GoodType x) 
    { return new MyArg(x); } 

} 

निहित डाले स्पष्ट रूप से डाली या उन्हें रैप करने के लिए बिना, आप सीधे अपने दिनचर्या के लिए मान्य प्रकार के तर्कों से गुजरने की अनुमति: यहाँ एक दृष्टिकोण मैं के साथ आया है। यदि आप अस्वीकार्य प्रकार के मान को पारित करने का प्रयास करते हैं, तो त्रुटि संकलन समय पर पकड़ा जाएगा।

मुझे यकीन है कि दूसरों के इस दृष्टिकोण का इस्तेमाल किया है हूँ, इसलिए इस पद्धति के लिए एक नाम हो, तो मैं सोच रहा हूँ।

+6

मुझे कुछ याद आ रहा है, लेकिन मुझे कोई पैटर्न नहीं दिख रहा है। –

+4

अच्छी चाल! +1। –

+8

आप जानते हैं, आपके पास "आवश्यक प्रकार" एक सामान्य इंटरफ़ेस को लागू कर सकता है, और उसके बाद 'पैरा IWhatever [] args' ले सकता है। –

उत्तर

0

यह Composite Pattern की तरह दिखता है। विकिपीडिया से उद्धरण:

समग्र पैटर्न वर्णन करता है कि ऑब्जेक्ट्स का एक समूह उसी तरह एक ऑब्जेक्ट के एक उदाहरण के रूप में व्यवहार किया जाना चाहिए।

+0

इंगित करता है, शायद यह निकटतम गोफ पैटर्न है जो मुझे पता है कि मामले को फिट करता है। –

3

वहाँ interwebs पर एक नामित पैटर्न होना प्रतीत नहीं होता है, लेकिन Ryan के अपने प्रश्न का टिप्पणी के आधार पर, मैं वोट पैटर्न के नाम Variadic Typesafety होना चाहिए।

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

प्रसंग

भिन्न वस्तुओं का चर सेट संसाधित किया जाना चाहिए है।

उपयोग जब

  1. आपका विधि भिन्न प्रकार के तर्क है कि एक आम आधार प्रकार नहीं है के परिवर्तनशील स्वीकार कर सकते हैं।
  2. आपकी विधि व्यापक रूप से उपयोग की जाती है (यानी कोड में और/या आपके ढांचे के उपयोगकर्ताओं की एक बड़ी संख्या में। बिंदु यह है कि टाइप-सुरक्षा इसके उपयोग को वारंट करने के लिए पर्याप्त लाभ प्रदान करती है।
  3. तर्क किसी भी क्रम में पारित किए जा सकते हैं, फिर भी अलग-अलग प्रकारों का सेट सीमित है और विधि के लिए स्वीकार्य एकमात्र सेट है।
  4. अभिव्यक्ति आपका डिज़ाइन लक्ष्य है और आप उपयोगकर्ता को रैपर बनाने के लिए ऑनस नहीं रखना चाहते हैं या एडेप्टर (देखें विकल्प)।

कार्यान्वयन

आप पहले से ही प्रदान की है।

उदाहरण

  • एक्सएमएल के लिए LINQ (जैसे new XElement(...))
  • जैसे कि वे एसक्यूएल मानकों का निर्माण के रूप में अन्य बिल्डरों।
  • स्पष्ट कमांड एडाप्टर बनाने की आवश्यकता के बिना कमांड निष्पादित करने के लिए प्रोसेसर facades (उदाहरण के लिए जो विभिन्न प्रकार के प्रतिनिधियों को स्वीकार कर सकते हैं या विभिन्न ढांचे से कमांड ऑब्जेक्ट्स स्वीकार कर सकते हैं)।

वैकल्पिक

  • एडाप्टर। कुछ एडाप्टर प्रकार (जैसे Adapter<T> या गैर-जेनेरिक Adapter के उप-वर्ग) के तर्कों की एक चर संख्या को स्वीकार करें कि विधि वांछित परिणाम उत्पन्न करने के लिए काम कर सकती है। यह उस सेट को बढ़ाता है जिसकी विधि आपकी विधि का उपयोग कर सकती है (प्रकार अब सीमित नहीं हैं), लेकिन अगर एडाप्टर अभी भी काम करने के लिए प्रसंस्करण को सक्षम करने के लिए सही काम करता है तो कुछ भी नहीं खो जाता है। नुकसान यह है कि उपयोगकर्ता के पास मौजूदा और/या नए एडेप्टर बनाने का अतिरिक्त बोझ है, जो शायद इरादे से हटता है (यानी "समारोह" जोड़ता है, और "सार" कमजोर करता है)।
  • प्रकार सुरक्षा हटाएं। इसमें एक बहुत ही मूल प्रकार (उदा। Object) स्वीकार करना और रनटाइम चेक रखना शामिल है। पास करने के बारे में जानना कि उपयोगकर्ता को पास किया गया है, लेकिन कोड अभी भी अभिव्यक्तिपूर्ण है। त्रुटियां रनटाइम तक खुद को प्रकट नहीं करती हैं।
  • समग्र। एक वस्तु को पास करें जो दूसरों के समग्र है। इसके लिए प्री-विधि-कॉल बिल्ड अप की आवश्यकता होती है, लेकिन समग्र संग्रह में आइटम्स के लिए उपरोक्त पैटर्न में से किसी एक का उपयोग करने के लिए वापस ले जाती है।
  • फ्लुएंट एपीआई। एकल कॉल को विशिष्ट कॉल की एक श्रृंखला के साथ बदलें, प्रत्येक स्वीकार्य तर्क के लिए एक। एक कैनोलिक उदाहरण StringBuilder है।
+0

स्ट्रिंगबिल्डर ... अच्छा उदाहरण। मैं अधिभारित तरीकों के पक्ष में होगा। आपने * अभिव्यक्ति * का उल्लेख किया - मुझे 'अभिव्यक्ति' के कस्टम व्युत्पन्न की संभावना के बारे में आश्चर्य हुआ। हो सकता है कि एक पैरामीटर ट्री ... एक 'ऑफ द कफ' विचार। – IAbstract

1

इसे एंटी-पैटर्न कहा जाता है जिसे आमतौर पर Poltergeist के नाम से जाना जाता है।

अद्यतन:

आर्ग के प्रकार हमेशा स्थिर रहे हैं और आदेश कोई फर्क नहीं पड़ता है, तो भार के कि प्रत्येक संग्रह (IEnumerable < टी >) प्रकार आप संचालित करने के लिए की जरूरत के लिए प्रत्येक विधि में बदल रहा है टी ले बनाने पर।

  1. MyArg वर्ग
  2. निकाला जा रहा है
  3. कि में एक अतिरिक्त संकलन समय प्रकार सुरक्षा जोड़ देगा अपने MyMethod में टाइप कास्टिंग की आवश्यकता को समाप्त करता है, तो आप विधि कॉल करने की कोशिश: इस करके अपने कोड जटिलता कम हो जाएगा उन तर्कों की एक सूची के साथ जिन्हें आप संभाल नहीं सकते हैं, आपको एक कंपाइलर अपवाद मिलेगा।
+0

मैं असहमत हूं, यह संभावित रूप से पुस्तकालय में उपयोगी हो सकता है। टाइप-सुरक्षा एफटीडब्ल्यू। – Gleno

+0

यह कन्स्ट्रक्टर "निजी MyArg (ऑब्जेक्ट obj) {this.RealArg = obj;}" संकलित समय प्रकार सुरक्षा की किसी भी संभावना को हटा देता है। MyMethod में भी संकलित संकलन समय प्रकार की सुरक्षा को खत्म करते हैं जो विधियों को कुछ और करने के साथ करते हैं और कुछ भी मुफ्त में प्राप्त करते हैं। –

+1

एह, और क्या होगा यदि वे स्थिर नहीं हैं? मैं अपने फ़ंक्शन को इस प्रकार कॉल करना चाहता हूं: 'f (10," हैलो ", नया अपवाद (" इसे बगजर ")), और मैं केवल उन प्रकारों को स्वीकार करना चाहता हूं। इसके खिलाफ केवल वैध तर्क यह कह रहा है कि आपको ऐसा करने की आवश्यकता नहीं है। मेरा सुझाव है कि लाइब्रेरी कॉल विधियों को प्रदान करते समय यह उपयोगी हो सकता है, और अब मैं इसके साथ खेल रहा हूं, और मुझे लगता है कि यह बहुत साफ है। – Gleno