क्या मुझे उन मूल्यों के लिए C # का उपयोग करना चाहिए जो नकारात्मक नहीं हो सकते?


80

मैंने सिर्फ एक वर्ग को लागू करने की कोशिश की है जहां कई लंबाई / गिनती गुण, आदि के uintबजाय हैं int। हालाँकि, ऐसा करते समय मैंने देखा कि ऐसा करने के लिए वास्तव में दर्दनाक है, जैसे कि कोई भी वास्तव में ऐसा नहीं करना चाहता है।

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

इसलिए मैंने सोचा कि क्या मुझे intयहाँ वापस आना चाहिए । मैं निश्चित रूप से वैसे भी पूरी रेंज का उपयोग नहीं कर रहा हूं। मैंने अभी सोचा था कि मैं वहां जो काम कर रहा हूं वह केवल नकारात्मक नहीं हो सकता है (यदि यह था, तो यह एक त्रुटि होगी) यह वास्तव में उपयोग करने के लिए एक अच्छा विचार होगा uint

पुनश्च: मैंने इस सवाल को देखा और यह कम से कम बताता है कि फ्रेमवर्क हमेशा ही क्यों उपयोग करता है, intलेकिन यहां तक ​​कि खुद के कोड में भी यह वास्तव में बोझिल है uintजिससे मुझे लगता है कि यह स्पष्ट रूप से वास्तव में नहीं चाहता है।


जवाबों:


42

जबकि कड़ाई से आपको उन uintवेरिएबल्स का उपयोग करना चाहिए जो गैर-नकारात्मक पूर्णांक को धारण करते हैं , जो आपको एक कारण है कि यह हमेशा व्यावहारिक नहीं होता है।

इस मामले में मुझे नहीं लगता कि जातियों को करने के साथ आने वाली पठनीयता में कमी इसके लायक है।


2
यह कहना मुश्किल है, मुझे नहीं लगता कि जातियां केवल अनुक्रमित करने वालों के लिए सुस्ती को कम करती हैं और आप एक आवरण बना सकते हैं। और जो निगेटिव बन जाते हैं वे दर्दनाक और महंगे कीड़े हैं।
user1496062

6
अगर आपको इंट के लिए रैपर बनाना है तो आपके लिए पठनीयता की समस्या अधिक है :)
S ..

61

मैं अन्य उत्तरों में यह भी जोड़ूंगा कि एक सार्वजनिक क्षेत्र, संपत्ति, विधि, पैरामीटर, और इसी तरह के प्रकार के रूप में uint का उपयोग करना, सामान्य भाषा विनिर्देश नियमों का उल्लंघन है और जब संभव हो तो इसे टाला जाना चाहिए।


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

3
अगर वे प्राकृतिक संख्याओं का समर्थन करते हैं तो मैं यह भी जोड़ूंगा कि इस प्रकार का मान 0 से 6 है वे सभी सरणी सीमा की जाँच को समाप्त कर सकते हैं, बड़े पैमाने पर 5-10% प्रदर्शन को बढ़ावा दे सकते हैं।
user1496062

क्या आप ऊपर दिए गए बयान से सहमत हैं, मिस्टर लिपर्ट?
AgentFire

@AgentFire: कथन यह दावा करता है कि यदि किसी ने कुछ किया, तो इससे प्रदर्शन में सुधार होगा। मेरे पास जवाबी दावों का मूल्यांकन करने की कोई क्षमता नहीं है; यदि आप यह जानना चाहते हैं कि क्या यह दावा सही है, तो उपयोगकर्ता से पूछें कि उपयोगकर्ता 1460962 क्या है, जो मेरे दावे को सही ठहराता है, मुझे नहीं; मैं असमर्थित दावा करने वाला नहीं हूं।
एरिक लिपर्ट

1
@ EricLippert जो आपके सबसे छोटे सबसे लंबे समय से एक है "मुझे नहीं पता", यह नहीं है: पी
AgentFire

4

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

यह भी ध्यान दें कि .NET अक्सर सीधे C पुस्तकालयों का निर्माण करता है, इसलिए इस सम्मेलन को जारी रखना समझदारी है। यदि आपको एक बड़े सूचकांक स्थान की आवश्यकता होती है, तो आप विभिन्न त्रुटि सिग्नलिंग तंत्र के लिए सम्मेलन को तोड़ सकते हैं।


24
त्रुटि कोड को वापस करने के बजाय अपवाद फेंकने के साथ .NET का बहुत संगत है। -1 रिटर्न प्रबंधित कोड में एक सामान्य दृश्य नहीं है।
क्रिस

सहमत हैं, लेकिन हम एक डिज़ाइन सम्मेलन के बारे में बात कर रहे हैं जो विंडोज़ तकनीकों में (जो अपवादों के अलावा जहां वे समर्थित हैं) भर में प्रचलित हैं - .NET लाइब्रेरी के वे हिस्से जो निम्न स्तर के कोड वाले इंटरफ़ेस को CRT त्रुटि कोड और अपवादों के बीच अनुवाद करना है। - यह समझने योग्य है कि वे यूइंट्स के बजाय इंट के सम्मेलन को आगे क्यों लाते हैं।
हसन सैयद

@ हसन तब भी, अगर कुछ वाइनपी नेगेटिव वैल्यू देता है, तो फ्रेमवर्क अभी भी इसका अपवाद होगा, सबकुछ साफ-सुथरे खोल में लपेटकर, ताकि तर्क यहाँ पर लागू न हो।
AgentFire

3

मेरी व्यक्तिगत भावना यह है कि आपको शायद सिर्फ इंट से चिपके रहना चाहिए। यह एक बहुत ही हर एक संपत्ति का उपयोग करने के लिए सिर्फ एक संख्यात्मक सीमा को पुनः प्राप्त करने के लिए एक कास्ट जोड़ने के लायक नहीं है। .NET की संभावना वैसे भी आपको उपयोग करने की संभावना नहीं है।


3

संचालन में पूर्णांक अतिप्रवाह का पता लगाने के लिए इंट का उपयोग करना भी सहायक होता है।


100% सटीक नहीं है, अगर यह इतना बह निकला कि शून्य तक पहुंच गया। फिर, डिफ़ॉल्ट रूप से सक्षम अतिप्रवाह सुरक्षा है।
AgentFire

3

IMO, का उपयोग करने uintका दोष यह है कि यह त्रुटि स्थितियों को अस्पष्ट करता है। निम्न कोड के समकक्ष उतने अच्छे नहीं हैं:

if (len < 0)
    terminate_program("length attained impossible value.");

बेशक आपके कार्यक्रमों को शुरू करने के लिए कुछ भी गलत नहीं होना चाहिए, लेकिन मुझे लगता है कि उन्हें प्रसार के बिना संख्यात्मक क्षरण का तेजी से पता लगाने के लिए भी लिखा जाना चाहिए। इस मामले में जहां 2 ^ 31 का एक मैक्सवेल पर्याप्त है, मैं कहता हूं कि ऊपर के उदाहरण के रूप intमें System.Diagnostics.Debug.Assert()और उचित त्रुटि-जांच के साथ उपयोग करें ।

यदि आप इसका uintउपयोग checkedअंडरफ्लो को रोकने के लिए और समान परिणाम प्राप्त करने के लिए करते हैं। हालाँकि मैंने पाया है कि मौजूदा कोड पर लागू करना थोड़ा मुश्किल है जो किसी उद्देश्य के लिए जातियों का उपयोग करता है।


2

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

यदि आप डरते हैं कि आप एक int को ओवरफ्लो कर सकते हैं, तो हर तरह से .. लेकिन समय से पहले अनुकूलन न करें।

मैं कहूँगा कि इंट के उपयोग से बग के थोड़े ऊंचे जोखिम को कम करने वाली जातियों को कम करने की बेहतर पठनीयता है।


2

यदि आप यह जांचना चाहते हैं कि एक मूल्य सकारात्मक है, तो एक बेहतर तरीका यह है कि शायद केवल मुखर का उपयोग करें (ध्यान दें कि यह केवल डिबगिंग तकनीक है - आपको यह सुनिश्चित करना चाहिए कि यह अंतिम कोड में कभी नहीं होता है)।

using System.Diagnostics;
...
Debug.Assert (i > 0);

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