इनुमों को अभिन्न पहचानकर्ताओं को मैप करने में क्या कमियां हैं?


16

मैं इस तरह के पहचानकर्ताओं के लिए कस्टम प्रकार बनाने के बारे में सोच रहा हूं:

public enum CustomerId : int { /* intentionally empty */ }
public enum OrderId : int { }
public enum ProductId : int { }

इसके लिए मेरी प्राथमिक प्रेरणा उस तरह के बग को रोकना है, जहां आप गलती से एक आदेश पारित करते हैं।

ऐसा लगता है कि मैं एक सामान्य .NET वेब एप्लिकेशन में जो कुछ भी उपयोग करना चाहता हूं, उसके साथ काम करते हैं।

  • MVC रूटिंग ठीक काम करता है
  • JSON क्रमांकन ठीक काम करता है
  • हर ORM मैं ठीक काम के बारे में सोच सकता हूं

तो अब मैं सोच रहा हूँ, "मुझे ऐसा क्यों नहीं करना चाहिए?" ये केवल कमियां हैं जो मैं सोच सकता हूं:

  • यह अन्य डेवलपर्स को भ्रमित कर सकता है
  • यदि आपके पास कोई गैर-अभिन्न पहचानकर्ता है, तो यह आपके सिस्टम में असंगतता का परिचय देता है।
  • इसके लिए अतिरिक्त कास्टिंग की आवश्यकता हो सकती है, जैसे (CustomerId)42। लेकिन मुझे नहीं लगता कि यह एक मुद्दा होगा, क्योंकि ओआरएम और एमवीसी मार्ग आमतौर पर आपको सीधे एनम प्रकार के मान सौंपेंगे।

तो मेरा सवाल यह है कि मुझे क्या याद आ रहा है? यह शायद एक बुरा विचार है, लेकिन क्यों?



3
इसे "माइक्रोटाइपिंग" कहा जाता है, आप इसके चारों ओर गूगल कर सकते हैं (जैसे कि यह जावा के लिए है, विवरण अलग हैं, लेकिन प्रेरणा समान हैं)
qbd

मैंने दो आंशिक उत्तर टाइप किए हैं और फिर उन्हें हटा दिया है क्योंकि मुझे एहसास हुआ कि मैं इस गलत के बारे में सोच रहा था। मैं आपसे सहमत हूं कि "यह शायद एक बुरा विचार है, लेकिन क्यों?"
user2023861

जवाबों:


7

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

  • आप अंतर्निहित रूपांतरण को int में जोड़ सकते हैं। जब आप इसके बारे में सोचते हैं, तो यह दूसरी दिशा है, int -> CustomerId, यह एक समस्या है जो उपभोक्ता से स्पष्ट पुष्टि के योग्य है।
  • आप ऐसे व्यावसायिक नियम जोड़ सकते हैं जो निर्दिष्ट करते हैं कि क्या पहचानकर्ता स्वीकार्य हैं और क्या नहीं हैं। यह सिर्फ एक कमजोर जांच के बारे में नहीं है कि क्या इंट सकारात्मक है: कभी-कभी, सभी संभावित आईडी की सूची डेटाबेस में रखी जाती है, लेकिन केवल तैनाती के दौरान ही बदल जाती है। फिर आप आसानी से देख सकते हैं कि दी गई आईडी उचित क्वेरी के कैश्ड परिणाम के खिलाफ मौजूद है। इस तरह, आप गारंटी दे सकते हैं कि आपका एप्लिकेशन अमान्य डेटा की उपस्थिति में तेज़ी से विफल हो जाएगा ।
  • पहचानकर्ता के तरीके महंगे डीबी-अस्तित्व की जाँच करने या संबंधित इकाई / डोमेन ऑब्जेक्ट प्राप्त करने में आपकी सहायता कर सकते हैं।

आप इस लेख को लागू करने के बारे में पढ़ सकते हैं कार्यात्मक C #: आदिम जुनून


1
मैं आपको लगभग निश्चित रूप से कहूंगा कि प्रत्येक इंट को कक्षा में नहीं, बल्कि एक संरचना
jk

अच्छी टिप्पणी, मैंने उत्तर को थोड़ा अद्यतन किया।
लूकैस्क लैन्स्की

3

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

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


1
एक एनुम का मुख्य लाभ यह है कि यह "काम करता है" जिस तरह से आप चाहते हैं कि यह एमवीसी, क्रमबद्धता, ओआरएम, आदि के साथ है। मैंने अतीत में कस्टम प्रकार (संरचनाएं और कक्षाएं) बनाई हैं और आप से अधिक कोड लिखना समाप्त करते हैं। आदेश में उन रूपरेखाओं / पुस्तकालयों को आपके कस्टम प्रकारों के साथ काम करने के लिए होना चाहिए।
default.kramer

सीरियलाइजेशन को पारदर्शी तरीके से काम करना चाहिए, लेकिन उदाहरण के लिए। ORM की आपको किसी प्रकार के स्पष्ट रूपांतरण को कॉन्फ़िगर करने की आवश्यकता है। लेकिन यह एक जोरदार टाइप की गई भाषा की कीमत है।
जैक्सबी

2

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

मुझे नहीं पता है कि यह .NET प्रदर्शन-वार कैसे काम करता है, उदाहरण के लिए आवश्यक रूप से बॉक्स किए गए मान हैं। OTOH कोड जो डेटाबेस के साथ काम करता है, संभावना है कि मैं / O- बाध्य हो सकता हूँ और बॉक्सिंग पहचानकर्ता कोई भी अड़चन नहीं होगी।

एक आदर्श दुनिया में, पहचानकर्ता अपरिवर्तनीय होगा और केवल समानता के लिए तुलनीय होगा; वास्तविक बाइट्स एक कार्यान्वयन विवरण होगा। असंबद्ध पहचानकर्ताओं के पास असंगत प्रकार होंगे ताकि आप गलती से दूसरे के लिए उपयोग न कर सकें। आपका समाधान व्यावहारिक रूप से बिल फिट बैठता है।


-1

आप ऐसा नहीं कर सकते, एनमों को पूर्वनिर्धारित किया जाना चाहिए। इसलिए जब तक आप ग्राहक आईडी के संभावित मूल्यों के पूरे स्पेक्ट्रम को पूर्व-परिभाषित करने के लिए तैयार नहीं हैं, तब तक आपका प्रकार बेकार होगा।

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

यह प्रश्न लाता है, हालांकि अगर यह Int32 (या गाइड) से उतरकर ग्राहक आईडी, ऑर्डर आईडी और उत्पाद आईडी के लिए आपके प्रकार बनाने में सहायक होगा। मैं एक कारण के बारे में सोच सकता हूं कि यह गलत क्यों होगा।

एक आईडी का उद्देश्य पहचान है। अभिन्न प्रकार पहले से ही इस के लिए एकदम सही हैं, उन्हें उतरने से कोई और अधिक पहचान नहीं मिलती है। कोई विशेषज्ञता की आवश्यकता नहीं है और न ही वांछित है, आपकी दुनिया का पहचानकर्ता के लिए विभिन्न प्रकार होने से बेहतर प्रतिनिधित्व नहीं किया जाएगा। इसलिए एक OO के नजरिए से यह बुरा होगा।

आपके सुझाव से आप टाइप सेफ्टी से ज्यादा चाहते हैं, आप वैल्यू सेफ्टी चाहते हैं और यह मॉडलिंग डोमेन से परे है, यह एक ऑपरेशनल इश्यू है।


1
नहीं, enums .NET में पूर्वनिर्धारित होना जरूरी नहीं है। और मुद्दा यह है कि कास्टिंग शायद ही कभी होता है, जैसे कि public ActionResult GetCustomer(CustomerId custId)किसी भी कलाकार की आवश्यकता नहीं है - एमवीसी फ्रेमवर्क मूल्य की आपूर्ति करेगा।
default.kramer

2
मैं सहमत नहीं हूँ। मेरे लिए, यह OO के नजरिए से सही समझ में आता है। Int32 का कोई शब्दार्थ नहीं है, यह विशुद्ध रूप से "तकनीकी" है। लेकिन मुझे सार पहचानकर्ता प्रकार की आवश्यकता है जो वस्तुओं की पहचान करने के उद्देश्य से कार्य करता है और जो कि Int32 के रूप में कार्यान्वित होता है (लेकिन लंबे या जो भी हो सकता है, वास्तव में कोई फर्क नहीं पड़ता)। हमारे पास ProductId जैसी ठोस विशेषज्ञताएँ हैं जो Identifier से उतरती हैं जो ProductId के ठोस उदाहरण की पहचान करती हैं। यह ProductId को OrderItemId के मान को निर्दिष्ट करने के लिए कोई तार्किक अर्थ नहीं रखता है (यह स्पष्ट रूप से एक त्रुटि है) इसलिए यह बहुत अच्छा है कि टाइप सिस्टम हमें इससे बचा सकता है।
21

1
मुझे नहीं पता था कि सी # इस एनम के उपयोग के बारे में लचीला था। यह निश्चित रूप से मेरे लिए इस तथ्य के लिए इस्तेमाल किया गया एक डेवलपर के रूप में भ्रमित है (?) कि enums हैं, ठीक है, संभव मूल्यों की गणना। वे आम तौर पर नामांकित आईडी की एक श्रृंखला निर्दिष्ट करते हैं। तो अब इस प्रकार का "दुरुपयोग" इस अर्थ में किया जाता है कि कोई सीमा नहीं है और कोई नाम नहीं हैं, बस प्रकार शेष है। और जाहिर है, प्रकार या तो सुरक्षित नहीं है। एक और बात: उदाहरण स्पष्ट रूप से एक डेटाबेस अनुप्रयोग है और कुछ बिंदु पर आपके "एनम" को एक अभिन्न प्रकार के क्षेत्र में मैप किया जाएगा, जिस क्षण आप अपने प्रकल्पित प्रकार को सुरक्षित रूप से खो देंगे।
मार्टिन माट
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.