जब मुझे KeyValuePair जैसी पूर्व-निर्मित संरचना पर 2-संपत्ति वर्ग का उपयोग करना चाहिए?


31

आपको पूर्व-निर्मित जेनेरिक संरचना का उपयोग करने के बजाय अपनी कक्षा में डेटा / कुंजी प्रकार का डेटा कब डालना चाहिए, जैसे कि a KeyValuePairया a Tuple?

उदाहरण के लिए, मेरे द्वारा बनाए गए अधिकांश कॉम्बो बॉक्स में एक DisplayName और एक मान होता है। यह उस तरह का डेटा है जो मैं यह तय करने की कोशिश कर रहा हूं कि नई कक्षा में कब रखा जाए, और कब KeyValuePair का उपयोग किया जाए।

मैं वर्तमान में उपयोग होने वाली किसी चीज़ पर काम कर रहा हूं iCalendar, और चयनित उपयोगकर्ता का डेटा अंततः एक key1=value1;key2=value2;प्रकार के स्ट्रिंग में संयुक्त हो जाता है । मैंने डेटा को एक में डालकर शुरू किया था KeyValuePair<string,string>, लेकिन अब मैं सोच रहा हूं कि क्या इसकी जगह खुद की क्लास होनी चाहिए।

कुल मिलाकर, मुझे यह पता लगाने में दिलचस्पी है कि मौजूदा संरचना / वर्ग को KeyValuePair2-प्रॉपर्टी ऑब्जेक्ट की तरह उपयोग करने का निर्णय लेने के दौरान कौन से दिशानिर्देशों का उपयोग किया जाता है , और आप किस तरह की स्थितियों में एक दूसरे का उपयोग करेंगे।


3
क्या भाषा? पायथन में, हमारे पास यह दुविधा नहीं है, क्योंकि हमारे पास tupleटाइप है।
एस.लूट।

3
@ S.Lott - .NET BCL में v 4.0 से ट्यूपल हैं।
ओडेड

1
.NET 4 में टुपल टाइप भी है। msdn.microsoft.com/en-us/library/system.tuple.aspx
डेव नाय

1
इस मामले में @Oded, मैं के साथ कुछ निर्माण कर रहा हूँ iCalendarऔर मैं के लिए वस्तुओं चाहता था BYDAYऔर BYSETPOS। वे कॉम्बो बॉक्स में दिखाई देते हैं, लेकिन वास्तविक डेटा को आवर्ती नियम स्ट्रिंग में जोड़ा जाता है, जो एक key=value;प्रकार का स्ट्रिंग है
राहेल

4
@ राशेल: कृपया प्रश्न को और अधिक विशिष्ट होने के लिए अपडेट करें । टिप्पणियों का एक गुच्छा चीजों को स्पष्ट करने का सबसे अच्छा तरीका नहीं है।
S.Lott

जवाबों:


26

मैं आमतौर पर ज्यादातर मामलों में KeyValuePair या Tuple के बजाय किसी ऑब्जेक्ट का उपयोग करता हूं। सबसे पहले, जब आप बदलाव करने के लिए 6 महीने बाद आते हैं, तो यह पता लगाना बहुत आसान है कि आपके इरादे क्या थे Tuple tऔर क्यों यह उन मज़ेदार मूल्यों के बजाय पहले था । दूसरा, जैसे-जैसे चीजें बढ़ती हैं और बदलती हैं आप आसानी से आवश्यकतानुसार अपने सरल डेटा ट्रांसफर ऑब्जेक्ट्स व्यवहार दे सकते हैं। दो नाम प्रारूप की आवश्यकता है? आसान, बस उचित ToString () अधिभार जोड़ें। इसे कुछ इंटरफ़ेस लागू करने की आवश्यकता है? कोई बात नहीं। अंत में, एक साधारण वस्तु बनाने के लिए वास्तव में लगभग शून्य ओवरहेड है, विशेष रूप से स्वचालित गुणों और कोड पूरा होने के साथ।

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


1
डीटीओ = डेटा ट्रांसफर ऑब्जेक्ट ? - मुझे नफरत है TLAs ;-)
बेन

3
@Ben - TFTFY। । ।
व्याट बार्नेट

7

एक नए वर्ग को परिभाषित करने का नियम सरल है: इसे "ओसम के रेजर" द्वारा संक्षेपित किया गया है।

http://c2.com/cgi/wiki?OccamsRazor

अच्छे कारण के बिना नई कक्षाओं का परिचय न दें। या जितना संभव हो पूर्व निर्मित कक्षाओं का उपयोग करें। या जितना संभव हो उतना कम आविष्कार करें। हालाँकि आप कम कोड लिखने में सहज हैं।

आप किसी पूर्व-निर्मित वर्ग का उपयोग नहीं कर सकते हैं यदि आपको ऑब्जेक्ट के लिए कुछ अद्वितीय जिम्मेदारी सौंपनी है और उस जिम्मेदारी को पूर्व-निर्मित वर्ग में परिभाषित नहीं किया गया है। अक्सर यह एक अनूठी विधि है।

tupleया KeyValuePairपसंद किया जाता है।

तक।

आपको कुछ कार्यक्षमता की आवश्यकता है जो ए tupleया का हिस्सा नहीं है KeyValuePair। फिर आपको अपनी कक्षा को परिभाषित करना होगा।


3
" कभी भी डिज़ाइन न करें कि आप क्या चोरी कर सकते हैं " क्या यह मेरे पसंदीदा तरीके के बारे में है।
सिंगलनेशन इलिमिनेशन

1
आप पर विचार करेंगे अर्थ विज्ञान "कार्यक्षमता है कि एक का हिस्सा नहीं होने के लिए tupleया KeyValuePair"? KeyValuePair में कम से कम कुछ शब्दार्थ के सीमित रूप हैं, लेकिन ट्यूपल्स शायद ही कभी (संभव हो सकता है, संदर्भ के आधार पर) imho। एक नए वर्ग का परिचय आपको स्पष्ट शब्दार्थ के रूप में देना चाहिए।
माल रॉस

+1 डक्ट टेप के साथ एक नाव में एक पूरे पैच न करें अगर यह एक प्लग को फिट कर सकता है।
इवान प्लाइस

4
मुझे लगता है कि यह ओकाम के रेजर का गलत इस्तेमाल है। दूसरी बात यह जानना महत्वपूर्ण है कि एक चर में क्या जानकारी निहित है। -1।
बेंट

4

यदि आप अपनी कक्षा लिखते हैं, तो आपके पास दस्तावेज रखने के लिए एक स्पष्ट स्थान है कि दोनों मूल्य क्या हैं। खासकर जब से दो तार एक बहुत स्पष्ट परिभाषा नहीं है। हालाँकि आप कुछ लिख सकते हैं

 public class MyPair : Tuple<string, string>

मुझे यह पसंद है क्योंकि यह MyPairपरिभाषित करता है कि टपल के मूल्य क्या हैं और उनका उपयोग किस लिए किया जाता है।
आइब्रीस्ट

2
लेकिन तब आपके गुणों को बुलाया जाएगा Item1और Item2! क्या पूरे वर्ग को परिभाषित करना इतना आसान नहीं है? public class SideStrings { public string Left { get; set; } public string Right { get; set; } }
विन्यासकर्ता

@configurator मैं उस पर प्रतिक्रिया लिख ​​रहा था और देखा कि ट्यूपल केवल इसलिए पढ़ा जाता है कि मैं सहमत हूं जो मुझे लगता है कि पूरी बात को लूट लेता है। यद्यपि आप मूल्यों को नाम देने के लिए टपल को लपेट सकते हैं।
हस्ताक्षर करें

2
@ साइन: लेकिन क्या बात है? अपनी खुद की कक्षा बनाना एक ट्यूल लपेटने की तुलना में कम काम है।
विन्यासकर्ता

2
@configurator आपको कुछ समानता और तुलना का सामान मिलता है जो कस्टम ऑब्जेक्ट से बेहतर काम करता है, लेकिन अगर सेटिंग की आवश्यकता है तो ट्यूपल निश्चित रूप से जाने का गलत तरीका है।
हस्ताक्षर करें

4

एस.लॉट ने लिखा

अच्छे कारण के बिना नई कक्षाओं का परिचय न दें। या जितना संभव हो पूर्व निर्मित कक्षाओं का उपयोग करें। जितना संभव हो उतना कम आविष्कार करें।

आप पूर्व निर्मित वर्ग का उपयोग नहीं कर सकते हैं यदि आपको उस ऑब्जेक्ट के लिए कुछ अनूठी जिम्मेदारी सौंपनी है जो पूर्व-निर्मित वर्ग में परिभाषित नहीं है।

मुझे कहना चाहिए कि क्यों मैं इस के साथ एक गंभीर मुद्दा है। जबसे

KeyValuePair [स्ट्रिंग, स्ट्रिंग]

लगता है ठीक है .... KeyValue [string, KeyValue [string, KeyValuePair [string, string]]] भी ठीक है? मैं S.Lott यह करने के लिए क्या कहेंगे पता नहीं है, लेकिन मेरे मालिक सोचता है कि यह है ठीक है।

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

PS मैं एक Ultra_Noob हूं इसलिए कृपया मुझे बताएं कि क्या मैं गलत हूं।


2
मुझे लगता है कि KeyValuePair<string,string>ठीक है, यह मानते हुए कि वास्तव में चाबियाँ और मूल्य हैं। यहां, एक मौजूदा वर्ग का पुन: उपयोग करना एक जीत है, क्योंकि आप लेखन कोड को बचाते हैं और अंतर -लाभ प्राप्त करते हैं OTOH, के रूप में जटिल के रूप KeyValuePair<string,KeyValuePair<string,string>>में कुछ का उपयोग कर समय के सबसे अधिक व्यावहारिक रूप से जटिल भी है। कभी-कभी यह सही हो सकता है - जब आपको अतिरिक्त कार्यक्षमता की आवश्यकता नहीं होती है, जब अर्थ स्पष्ट होता है, और जब यह अन्य वर्गों के साथ अच्छी तरह से काम करता है। YMMV, यह केवल पेशेवरों और विरोधाभासों का भार है।
मआर्टिनस सिप

यदि आप C # का उपयोग कर रहे हैं, तो यहां Tuple vs KeyValuePair का प्रदर्शन है । कुछ आप अपने मालिक के साथ साझा करना चाहते हैं?
बेन

3

जब हम कुंजी / मान युग्म कहते हैं , तो मैं आमतौर पर हैश टेबल , या साहचर्य सरणियों या बस एक KeyValuePair ऑब्जेक्ट के बारे में सोचता हूं । मैं उन सभी का उपयोग करता हूं और जब मैं उपयोग करता हूं तो इसमें कोई अंतर नहीं है।

मुझे लगता है कि कुंजी / मूल्य जोड़े की सूची के बारे में सबसे महत्वपूर्ण बात यह है कि, चाबियाँ अद्वितीय होनी चाहिए (क्योंकि यह सब के बाद एक कुंजी है), और उपरोक्त सभी संरचनाएं वास्तव में मुझे उस कार्यक्षमता के साथ प्रदान करती हैं।

इसके अलावा, मैं कुंजी द्वारा खोज करना चाहता हूं, या पुश (पॉप) जैसी सूची (सरणी) शैली क्रियाएं करना चाहता हूं।

तो, मेरा जवाब है, नहीं , और मैं कुंजी / मूल्य जोड़े के लिए स्पष्ट रूप से ऑब्जेक्ट नहीं बनाते हैं, क्योंकि बहुत सारी अंतर्निहित संरचनाएं मेरे लिए पहले से ही ऐसा करती हैं।


3

क्लीन कोड के अध्याय छह में एक डेटा संरचना का उपयोग करने का एक अच्छा विवरण दिया गया है। संक्षेप में, आप एक डेटा संरचना का उपयोग करते हैं जब आप उस डेटा पर काम करने के लिए नए कार्यों को जोड़ने का अनुमान लगाते हैं। जब आप मौजूदा कार्यों द्वारा संचालित किए जाने वाले नए डेटा प्रकारों को जोड़ने का अनुमान लगाते हैं तो आप एक वर्ग का उपयोग करते हैं। आपका ComboBox उत्तरार्द्ध का एक उदाहरण है। आपके पास कई अलग-अलग डेटा प्रकारों (विभिन्न विजेट्स के लिए विभिन्न प्रकार के डेटा) पर काम करने वाले कार्यों (कॉम्बोबॉक्स कार्यान्वयन) का एक सेट है।


2

मैं शायद यहां विल्डिंग के साथ सहमत होऊंगा , लेकिन तब मैं इस तरह की बात पर भी थोड़ा शोर करता हूं ।

मेरा सुझाव है कि अंतर्निहित प्रकार अक्सर तंत्र ऑब्जेक्ट होते हैं । KeyValuePair उदाहरण के लिए, एक शब्दकोश और हैश तालिकाओं के तंत्र का हिस्सा है, जो अद्वितीय कुंजियों को सुनिश्चित करने में मदद करता है और उनके पास ऐसे गुण होते हैं जिनके पास तंत्र के संदर्भ में सार्थक नाम होते हैं।

दूसरी ओर, कस्टम मेड डेटा ऑब्जेक्ट का उपयोग आपके डेटा का बेहतर प्रतिनिधित्व प्रदान करता है और पठनीयता और विस्तार सहित कई लाभ प्रदान करता है। कस्टम निर्मित वस्तुओं में मौजूदा कोड का पुन: उपयोग करने से रोकने के लिए कुछ भी नहीं है जैसा कि साइन ने सुझाव दिया है , लेकिन मैं लिपटे हुए वर्ग को छिपाने और छिपाने की कोशिश करूंगा, और अमूर्त रिसाव से बचूंगा , ताकि आप बाद में अपने बाकी कोड को प्रभावित किए बिना अंतर्निहित कार्यान्वयन को बदल सकें। ।

तो असली सवाल: क्या आप डेटा का प्रतिनिधित्व कर रहे हैं या आप एक तंत्र में डेटा का उपयोग कर रहे हैं? (और मैं इन अवधारणाओं को एक साथ मिलाने की सलाह नहीं दूंगा)।

मेरे अनुभव में ऐसा कुछ भी बुरा नहीं है कि ट्यूपल [स्ट्रिंग, स्ट्रिंग] को एक विधि में देखा जा रहा है और यह जानने के लिए कोई तत्काल तरीका नहीं है कि आइटम 1 और आइटम 2 क्या माना जाता है। तरीकों के भीतर या केवल एक वर्ग के निजी सदस्यों के रूप में ट्यूपल्स का उपयोग करने के लिए सबसे अच्छा है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.