2012-05-24 3 views
13

सी # में enum के लिए डिफ़ॉल्ट मान के रूप में '0' होने का क्या मतलब है? अगर मैं गणन की घोषणा एक अलग संख्या के साथ शुरू होता है कि:क्यों डिफ़ॉल्ट enum मान 0 है और न्यूनतम नहीं है?

enum Color 
{ 
    Blue = 1, 
    Green, 
    Red, 
} 

तो var color = default(Color) - मुझे वापस आ जाएगी '0'। मुझे इसके बजाय न्यूनतम मूल्य देखने की उम्मीद है। यह व्यवहार समस्याएं पैदा कर सकता है यदि गणना का प्रत्येक सदस्य कुछ विशिष्ट संख्या से मेल खाता है और '0' मान्य मान नहीं है।

+2

क्यों "न्यूनतम मूल्य"? क्यों गिनती नहीं है कि गिनती? – BoltClock

+2

आप 0 के अलावा किसी भी चीज़ पर मूल्य क्यों शुरू करेंगे? अधिकांश प्रोग्रामर गिनती करते समय शुरुआती बिंदु के रूप में 0 का उपयोग करने के आदी हैं, उदा। जैसे कि सरणी के साथ काम करते हैं। मैं सुझाव दूंगा कि आपके एम्स मूल्यों को तब तक न दें जब तक कि आपके पास ऐसा करने का वास्तव में अच्छा कारण न हो। –

+0

@ जेसेवेब यह एक उदाहरण है। लेकिन मैं गणना घोषित कर सकता हूं, जहां प्रत्येक सदस्य के पास कुछ विशिष्ट मूल्य होता है। हाल ही में मैंने एक निश्चित प्रारूप की फाइलों के साथ काम किया, जहां प्रत्येक प्रविष्टि को 1, 2 या 3 टैग मानों द्वारा परिभाषित किया गया था। – username

उत्तर

8

हम केवल अनुमान कर सकते हैं के बारे में क्यों नेट ढांचे का एक पहलू एक निश्चित तरीके से डिजाइन किया गया था। सबसे सरल स्पष्टीकरण के लिए, मैं the MSDN documentation से इस टिप्पणी को उजागर करना चाहते हैं:

एक गणन नामित स्थिरांक जिसका अंतर्निहित प्रकार चार को छोड़कर किसी भी अभिन्न प्रकार है का एक सेट है। यदि कोई अंतर्निहित प्रकार स्पष्ट रूप से घोषित नहीं किया गया है, तो Int32 का उपयोग किया जाता है।

ध्यान दें कि एक .NET गणना अनिवार्य रूप से एक अभिन्न प्रकार का विस्तार है। अभिन्न प्रकारों के लिए डिफ़ॉल्ट मान 0 है, इसलिए यह व्यवहार योग्य होने के लिए गणना के लिए उचित है (यदि आपने जो मामलों को सचित्र किया है) में कुछ असुविधाजनक है।

+0

लेकिन जब मैं enums के लिए 0 मानों का उपयोग नहीं करता हूं, तो मुझे "अपवाद का एक अपवाद" System.NullReferenceException 'MyProjectName.dll में हुआ था लेकिन उपयोगकर्ता कोड में प्रबंधित नहीं किया गया था। अतिरिक्त जानकारी: ऑब्जेक्ट संदर्भ किसी ऑब्जेक्ट के उदाहरण पर सेट नहीं है। " त्रुटि। इसे कैसे जोड़ेंगे? नोट: मैं enum के विवरण प्रदर्शित करने के लिए एक एक्सटेंशन विधि का उपयोग करता हूं, लेकिन यह सुनिश्चित नहीं करता कि [इस पृष्ठ] पर परिभाषित सहायक विधि (GetDescription) में त्रुटि से कैसे बचें (http://stackoverflow.com/questions/34293468/cannot- डिस्प्ले-एनम-वैल्यू-ऑन-केंडो-ग्रिड/34294589? noredirect = 1 # comment56355782_34294589) –

+1

@ क्रिस्टोफ़ मैं आपके कोड को देखे बिना उस प्रश्न का उत्तर नहीं दे सकता, लेकिन अपवाद जो आप वर्णन कर रहे हैं, एक वैरिएबल को 'शून्य' पर सेट किया गया है अप्रत्याशित रूप से। डिबगिंग के दौरान यह देखना है। –

+0

ठीक है, धन्यवाद। मैंने गेटडिस्क्रिप्शन() विधि का उपयोग करके समस्या को हल किया [उपयोगकर्ता अनुकूल तारों के साथ Enum ToString] (http://stackoverflow.com/questions/479410/enum-tostring-with-user-friendly-strings)। –

0

बिंदु probabbly कम सकारात्मक पूर्णांक संभव मूल्य होने में है।

क्यों कम सकारात्मक?

बिट-शिफ्ट ऑपरेशन के साथ एनम का इलाज करने में सक्षम होने के लिए।

मैं स्वाभाविक रूप से डिफ़ॉल्ट मान के बारे में बात कर रहा हूं, जिसे डेवलपर द्वारा बदला जा सकता है।

12

सभी मूल्य प्रकारों (enum सहित) के लिए डिफ़ॉल्ट मान bitwise 0. है। परिणामस्वरूप इसका मतलब है कि 0 हमेशा enum के लिए संभव मूल्य है, भले ही इसे स्पष्ट रूप से परिभाषित नहीं किया गया हो। Default values table

संपादित करें:

यहाँ विनिर्देश है अधिक जानकारी के लिए गणन प्रकार के लिए MSDN जाँच - enum

enum टाइप जो एक तरह से विशेष है यह अन्य मान प्रकार से व्युत्पन्न तरह-की (जो आमतौर पर संभव नहीं है), लेकिन इसके बैकिंग प्रकार के मूल्य प्रकार के रूप में व्यवहार करता है। एक enum बैकिंग प्रकार के रूप में केवल कुछ अभिन्न मूल्यों का उपयोग कर सकते हैं।

नोट: जैसा कि @archil इंगित करता है, enum मान में बैकिंग प्रकार का कोई भी मूल्य हो सकता है, भले ही enum में उल्लिखित स्थिरांक की सूची के बावजूद। "FlagsAttribute" के साथ चिह्नित enums के लिए इस व्यवहार की सामान्य रूप से अपेक्षा की जाती है, लेकिन सामान्य enums के लिए यह सहज नहीं हो सकता है।

+1

मैंने दस्तावेज़ धन्यवाद पढ़ा है, लेकिन सवाल ऐसा क्यों है। गणना नहीं है कि कोड में घोषित केवल मूल्यों को पकड़ना चाहिए? अब मुझे डिफ़ॉल्ट 0 तत्व बनाना है और हमेशा जांचें कि यह तत्व नहीं है। और मैं सुरक्षित रूप से उम्मीद नहीं कर सकता कि enum सदस्य हमेशा प्रदान किया गया है। मुझे लगता है कि इसे सी # में इस तरह कार्यान्वित करना आसान था। – username

+1

नहीं। एनम में इसके बैकिंग प्रकार (डिफ़ॉल्ट रूप से int) के रूप में कोई मान हो सकता है। इसी कारण से इसका बैकिंग प्रकार के रूप में डिफ़ॉल्ट मान होता है जब तक अन्यथा निर्दिष्ट नहीं किया जाता है। इनपुट एनम पैरामीटर को प्रमाणित करने के लिए Enum.IsDefined (मान) फ़ंक्शन का उपयोग करें। –

+1

हम्म, मुझे अपना खुद का पोस्ट करने से पहले यह जवाब पढ़ना चाहिए था। हालांकि, यह एक बहुत ही सामान्यीकृत है: enums मूल्य प्रकार नहीं हैं, लेकिन उनके समर्थन प्रकार हैं। एक enum * किसी भी * मान का उपयोग अपने बैकिंग प्रकार, केवल अभिन्न मूल्यों के रूप में नहीं कर सकता है। इन बिंदुओं को स्पष्ट करने के लायक है। :) –

7

हमेशा एनम के अस्तित्व के लिए संभावना है। यही कारण है कि Enum.IsDefined Method मौजूद है।

एक enum ई का डिफ़ॉल्ट मान अभिव्यक्ति (ई) 0 द्वारा उत्पादित मूल्य है।

+0

@ बोल्टक्लॉक लेकिन जैसा कि मैंने चेक किया है, मैंने अपना उत्तर अधिक सही परिभाषा – archil

+0

के लिए संपादित किया है क्या आप कह रहे हैं कि अगर कोड में घोषित नहीं किया गया है तो enum को 0 को छोड़कर कुछ और हो सकता है? – username

0

मुझे यकीन नहीं है क्यों लेकिन ...http://msdn.microsoft.com/en-us/library/sbbt4032.aspx

ूगणकों जैसा कि निम्न उदाहरण में दिखाया गया है, मूलभूत मूल्यों ओवरराइड करने के लिए initializers उपयोग कर सकते हैं:

यहाँ सी # enum के बारे में दस्तावेज़ है।

enum दिन {शनि = 1, सूर्य, सोम, मंगल, बुध, गुरु, शुक्र};

इस गणना में, तत्वों के अनुक्रम को 0 के बजाय 1 से शुरू करने के लिए मजबूर होना पड़ता है। हालांकि, स्थिरता सहित 0 का मान अनुशंसित है। अधिक जानकारी के लिए, see Enumeration Types (C# Programming Guide)

वे अनुशंसा करते हैं कि आप हमेशा प्लेसहोल्डर एनम मान शामिल करें जो मूल्य 0 के अनुरूप है अन्यथा आप समस्याओं में भाग ले सकते हैं। आप इस enum मान को Undefined या Default या उस तरह कुछ ऐसा नाम दे सकते हैं।

जैसा कि मैंने आपके प्रश्न पर मेरी टिप्पणी में उल्लेख किया है, लेकिन मेरी सिफारिश आपके पर सभी पर मूल्यों का उपयोग नहीं करना चाहिए जब तक कि आपके पास ऐसा करने का बहुत अच्छा कारण न हो। यदि आपको MSDN Programming Guide for Enumeration Types

1

का पालन करें, तो डिफ़ॉल्ट enum मान क्यों है? रनटाइम कार्यान्वयन की आसानी। किसी भी मान प्रकार का डिफ़ॉल्ट bitwise 0 है, और संभवतः एक शून्य संदर्भ को bitwise 0 द्वारा दर्शाया गया है। इस प्रकार प्रारंभ में किसी ऑब्जेक्ट को इसके डिफ़ॉल्ट मानों के साथ बनाने के लिए, हमें केवल इसके आकार को जानने की आवश्यकता है; रनटाइम को ऑब्जेक्ट की संरचना के बारे में कुछ भी जानने या संसाधित करने की आवश्यकता नहीं है। इसी तरह, पूर्व परिभाषित मान-प्रकार का कन्स्ट्रक्टर केवल शून्य के साथ मेमोरी रेंज भर सकता है।

यह पसंद है या नहीं, ऐसा ही है। प्रतिक्रिया में हमें क्या करने की ज़रूरत है जब एक enum को डिजाइन करते हैं, जो भी नाम उपयुक्त डिफ़ॉल्ट है, उसे मान 0 दें। यदि कोई उपयुक्त डिफ़ॉल्ट नहीं है, तो पैरामीटर के रूप में इस तरह के enum को स्वीकार करने के आपके तरीके यह जांच सकते हैं कि यह ठीक से सेट है, जैसे

void ProcessColor(Color c) { 
    if (c == 0) 
     throw new ArgumentException("Color is not set", "c"); 
    //... 
} 
+0

हाँ, यह मुझे यह देखने के लिए है कि यह 0 नहीं है या नहीं, लेकिन किसी भी अंतर्निहित असंगतताओं से बचने के लिए एनम में 0 का डिफ़ॉल्ट मान शामिल करना बेहतर है। धन्यवाद। – username

0

enum (डिफ़ॉल्ट रूप से) int है। Enums हमारे स्रोत कोड के लिए मानव पठनीय इंक हैं, लेकिन जब आपका प्रोग्राम संकलित हो जाता है, तो enum नहीं है, केवल int एस है। (

IL_0001: ldc.i4.0 
IL_0002: stloc.0  
IL_0003: ldc.i4.0  
IL_0004: stloc.1 

तो, कैसे एक int 1 का डिफ़ॉल्ट मान हो सकता था के रूप में आप से पूछना:

public enum test { One, Two, Three } 

var x = test.One; 
var y = 0; 

आईएल में यह हो जाता है: पूर्णांक के लिए डिफ़ॉल्ट मान 0.

इस कोड है) कुछ मामलों में, लेकिन दूसरों को नहीं?

3

जैसा कि कई उत्तरों में कहा गया है, किसी भी निश्चित आकार की डेटा संरचना के लिए "डिफ़ॉल्ट" मान 0 है। संरचनाओं का आकार स्मृति को शून्य पर सेट किया गया है और इसे "डिफ़ॉल्ट" माना जाता है। अब, यदि आप एनम के लिए अपना "डिफ़ॉल्ट" मान परिभाषित करना चाहते हैं, तो आपके पास कई विकल्प हैं।सबसे आसान अपने खुद के समारोह लिखने के लिए आप एक "कम से कम मान्य enum" देने के लिए किया जाएगा

private E GetDefaultEnum<E>() 
{ 
    return (E)(Enum.GetValues(typeof(E)).Cast<E>().Min<E>()); 
} 

उपयोग:

enum Color 
{ 
    Blue = 1, 
    Green, 
    Red, 
} 

Color defaultColor = GetDefaultEnum<Color>(); 
MessageBox.Show(defaultColor.ToString()); // "Blue" 

आप स्पष्ट रूप से बदल सकते हैं कि कैसे आप एक "डिफ़ॉल्ट" मूल्य निर्धारित है, लेकिन इस तरह से आपकी आवश्यकताओं के लिए सबसे उपयुक्त लगता है।