2010-06-30 11 views
23

मैंने अभी एक सूक्ष्म बग की खोज की जहां मेरे पास दो नामों के साथ एक enum था जो अनिश्चित रूप से समान संख्यात्मक मूल्य साझा कर रहा था (इस मामले में लाल = 10 और crimson = 10)। मुझे आश्चर्य है कि यह वाक्यविन्यास त्रुटि नहीं है।एक एनम के लिए समान संख्यात्मक मूल्य के साथ दो अलग-अलग नाम होने के लिए यह ठीक क्यों है?

public enum Colour 
{ 
    Red=10, 
    Blue=11, 
    Green=12, 
    Crimson=10 
} 
// Debug.Write(Colour.Red==Colour.Crimson) outputs True 

क्या कोई वास्तविक दुनिया कारण है कि यह व्यवहार उपयोगी हो सकता है या ऐसा लगता है कि यह एक वाक्यविन्यास त्रुटि होनी चाहिए?

+2

मैंने सोचा कि मैं मूल रूप से पूछे जाने के तीन साल बाद यह पूछने के लिए इतना चालाक था। – MrBoJangles

+0

एनम डिज़ाइन के लिए एमएसडीएन दिशानिर्देश देखें: http://msdn.microsoft.com/en-us/library/ms229058.aspx इनकी भावना में, मैं कहूंगा कि यह तकनीकी रूप से संभव है, शायद यह है सलाह नहीं दी। – Technobabble

+2

@MrBoJangles, तो मैं आपके बाद 16 महीने बाद एक ही बात पूछने जा रहा था। –

उत्तर

36
public enum Colour 
{ 
    Red=10, 
    Rouge=10, 
    Blue=11, 
    Bleu=11, 
    Green=12, 
    Vert=12, 
    Black=13, 
    Noir=13 
} 
+0

बहुत संक्षिप्त और प्रभावी उत्तर। –

+0

सहमत हुए। सीधे बिंदु पर कोई स्पष्टीकरण की आवश्यकता नहीं है। – Gage

+10

और आप इसका उपयोग कैसे करेंगे? एक बहुभाषी प्रोग्रामिंग टीम में, प्रत्येक सदस्य अपने स्वयं के स्थिरांक चुनते हैं? –

4

Enum लगातार चर का गणन है, और आप एक ही मूल्य के साथ दो आइटम हो सकते हैं, वहाँ एक सिंटैक्स त्रुटि मुझे लगता है कि होना करने के लिए कोई कारण नहीं है, हालांकि, इस लिए इस कोड

switch(c) 
{ 
    Colour.Red: 
    break; 
    Colour.Crimson: 
    break; 
    ... 
} 
+0

यह जानने के लायक है। जानबूझकर शेयर नामों का उपयोग न करने का एक कारण है। – AndyM

+0

सहमत; एक ही मूल्य के साथ दो नाम एक त्रुटि नहीं है। यदि आप इससे बचना चाहते हैं, तो संख्यात्मक मान निर्दिष्ट न करें। –

0
में त्रुटि संकलन का कारण होगा

मैंने एक ही चीज़ को .NET TWAIN wrapper में देखा है - यह सभी TWAIN संदेश कोड को एक बड़े enum में संग्रहीत करने की अनुमति देता है, लेकिन इससे पहले चीजें थोड़ा उलझन में आती हैं।

9

एनम्स का उपयोग कॉन्सन्स की तरह किया जाता है और आप निश्चित रूप से उसी मूल्य के साथ दो स्थिरांक रख सकते हैं जिनका उपयोग उसी स्थान पर किया जाता है। व्यापार नियमों के कारण पिछड़े संगतता की वजह से यह तृतीय पक्ष एपीआई की वजह से हो सकता है।

1

यह ठीक है। आपके पास दो मान हो सकते हैं जो एपीआई के उपयोगकर्ता के दृष्टिकोण से भिन्न होते हैं, लेकिन कार्यात्मक रूप से समान मान के रूप में माना जा सकता है।

3

यह एक वाक्यविन्यास त्रुटि नहीं है। सभी enum दृढ़ता से टाइप किए गए फैशन में स्थिरांक की श्रृंखला का आकलन करते हैं।

इस प्रकार, यदि कोई डेवलपर गलत टाइप (जैसा कि आपके उदाहरण में है), जहां तक ​​सीएलआर का संबंध है, यह एक बिल्कुल वैध मामला है। सीएलआर मानता है कि डेवलपर जानता है कि वह क्या कर रहा है, और वह ऐसा करने के लिए क्यों चुने गए।

वास्तविक दुनिया के मामलों के लिए, मैं किसी भी समय के साथ किसी के साथ नहीं आ सकता, लेकिन मुझे अभी भी निश्चित है कि शायद ऐसे मौके हैं जहां यह सहायक होगा।

2

निश्चित रूप से ऐसा है, हालांकि यह शायद बहुत आम नहीं है। यदि कोई इकाई/मान है जो आमतौर पर दो अलग-अलग नामों के तहत जाना जाता है, तो यह एक अच्छा कारण है।

आपके द्वारा प्रस्तुत परिदृश्य शायद एक ऐसा मामला है। बीसीएल से सीधे एक बेहतर, System.Windows.Forms.MessageBoxIcon enum है; Stop, Error, और Hand सदस्यों के पास एक ही विवरण है और वास्तव में एक ही मूल्य है। Asterisk और Information भी समान, के रूप में टिप्पणी ने सुझाव दिया है:

Asterisk The message box contains a symbol consisting of a lowercase letter i in a circle. 
Information The message box contains a symbol consisting of a lowercase letter i in a circle. 

उम्मीद है कि यह आप (अपनी खुद की शायद एक होने) उचित परिदृश्यों की एक अच्छा विचार देना चाहिए।

19

मैंने देखा है कि इस सुविधा कभी कभी एक "डिफ़ॉल्ट" मूल्य के लिए प्रयोग किया जाता है:

public enum Scope 
{ 
    Transient, 
    Singleton, 
    Default=Transient 
} 

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

1

वास्तविक मूल्य के विपरीत नामित मूल्य का उपयोग रूट है। मान लीजिए कि आपके पास एक ही मूल्य के साथ फ्रेंच, अंग्रेजी आदि है। यह मेरे लिए enum की जड़ है।

6

From the c# language spec:

एकाधिक enum सदस्यों को एक ही जुड़े मूल्य साझा कर सकते हैं। उदाहरण

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

एक enum दिखाता है जिसमें दो enum सदस्य-ब्लू और मैक्स के समान मूल्य हैं।

इस मामले में आप MyColor == Color.Max की जांच कर सकते हैं जो कुछ परिस्थितियों में उपयोगी होगा।

+2

मैक्स एक मूल मूल्य का एक उदाहरण है। गणना के लिए एमएसडीएन डिजाइन दिशानिर्देशों के अनुसार यह अनुशंसित नहीं है क्योंकि यह कच्चे मूल्य और उसके राज्य के बीच चिंताओं को अलग करने का उल्लंघन करता है। यदि अधिकतम को मैक्स के रूप में बदलने की आवश्यकता उत्पन्न होती है, तो मैक्स को हमेशा ब्लू के बराबर होने की अपेक्षा करने वाले किसी भी संदर्भ को ठीक करने की आवश्यकता होगी। – Technobabble

0

यह कभी कभी सिफारिश की है (हालांकि नहीं सी # के लिए एमएस द्वारा सिफारिश - Salaros की टिप्पणी देखें) अपने enum में एक कम और ऊपरी बाध्य शामिल करने के लिए इस तरह के रूप

public enum Colour 
{ 
    LowBound=10, 
    Red=10, 
    Rouge=10, 
    Blue=11, 
    Bleu=11, 
    Green=12, 
    Vert=12, 
    Black=13, 
    Noir=13, 
    UpperBound=13 
} 

सत्यापन/बार-बार दोहराना के प्रयोजनों के लिए प्रत्येक संभव सेटिंग के माध्यम से। हालांकि मुझे एहसास है कि .Net इस के लिए एक सुविधा प्रदान कर सकता है :)

+1

गणना का अंत एक बाध्य है और आप घोषणा के क्रम में इसे पुन: सक्रिय कर सकते हैं: foreach (Enum.GetValues ​​(टाइपोफ (Foos) में Foos foo) असल में सेंटीनल गणना मूल्यों (लोबाउंड, अपरबाउंड) से बचने की अनुशंसा की जाती है। http://msdn.microsoft.com/en-us/library/vstudio/ms229058%28v=vs.100%29.aspx – Salaros

+0

मैं एक उदाहरण दे रहा था कि एकाधिक आइटम एक मूल्य साझा कर सकते हैं। कुछ भाषाओं में आप foreach के साथ एक enum फिर से नहीं कर सकते हैं। शायद -1 के लिए योग्य है लेकिन कभी दिमाग नहीं! –

+1

हम सी # के बारे में बात कर रहे हैं, न कि "अन्य" भाषाओं, इसलिए यदि आप आधिकारिक विनिर्देशों के खिलाफ कोड करने के लिए किसी को सिखाते हैं तो आप -1 के लायक हैं। मैं इस तरह सी # newbies सी # पर गलत thins नहीं सीखेंगे। वैसे भी ध्यान रखें कि -1 दोनों खातों पर लागू होता है, इसलिए यह ट्रोलिंग नहीं कर रहा है: मैं स्टैक ओवरफ्लो को बेहतर बनाने के लिए बस अपने अंक बलिदान कर रहा हूं .. यही वह है जो हम सभी को करना है। – Salaros

0

मुझे लगता है कि उसी नंबर का पुनः उपयोग करने के लिए कई उपयोग हैं। एक नया उदाहरण देने के लिए, कहें कि आपके पास एक रैंकिंग प्रणाली है जो यह सुनिश्चित करेगी कि किसी विशेष वर्ग (माता-पिता) की वस्तुओं को अन्य वर्गों (बच्चों) पर निर्भर करने से पहले बनाया गया हो, तो आपके पास कुछ बच्चे हो सकते हैं जो एक ही स्तर पर हैं 'और इससे कोई फर्क नहीं पड़ता कि पहले कौन सा बनाया गया है। नीचे दिए गए उदाहरण में, माता-पिता को पहले बनाया जाएगा, चाइल्ड 1, 2, या 3 अगला, फिर आखिरी बच्चा 4 होगा। यदि इसे पेड़ आरेख के रूप में देखा गया था, तो उसी संख्या वाले किसी भी आइटम 'भाई बहन' होंगे।

public enum ObjectRanks 
{ 
    Parent = 0, 
    Child1 = 1, 
    Child2 = 1, 
    Child3 = 1, 
    Child4 = 2 
} 

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

21

सावधान रहें! यदि आपके enum में एक ही मान वाले कई तत्व हैं, तो आप Enum.Parse() का उपयोग करते समय अप्रत्याशित परिणाम प्राप्त कर सकते हैं। ऐसा करने से मनमाने ढंग से पहला तत्व लौटाया जाएगा जिसमें अनुरोधित मान है। उदाहरण के लिए, यदि आपके पास enum Car { Ford = 1, Chevy = 1, Mazda = 1} है, तो (Car)Enum.Parse(typeof(Car), "1")Car.Ford वापस आ जाएगा। हालांकि यह उपयोगी हो सकता है (मुझे यकीन नहीं है कि यह क्यों होगा), ज्यादातर स्थितियों में यह संभवतः भ्रमित होने जा रहा है (विशेष रूप से कोड बनाए रखने वाले इंजीनियरों के लिए) या समस्याओं के उत्पन्न होने पर आसानी से अनदेखा किया जा सकता है।

+0

SO पर आपके पहले उत्तर के लिए धन्यवाद, और यह एक अच्छा है। क्या मैं कुछ अतिरिक्त सफेद स्थान जोड़ने के लिए पाठ को संपादित करने का सुझाव दे सकता हूं और विशेष रूप से, कोड टुकड़ों को हाइलाइट करने के लिए मार्कडाउन का उपयोग करने के लिए? उत्तरार्द्ध करने का सबसे आसान तरीका या तो बैकटिक (') के साथ 'टेक्स्ट को घेरना' या फ़ॉर्मेटिंग बार में कोड कोट बटन का उपयोग करना है। मुझे संदेह है कि अगर आपकी पढ़ाई थोड़ा आसान हो तो आपकी अपवित्र गणना भी बढ़ सकती है। सौभाग्य। – Simon

1

यह मान्य है और एक को अलग-अलग नामों के साथ समान मान देखने की अनुमति देता है। इस काम को अच्छी तरह से सावधान रहें। यदि आप int/string से enum या स्ट्रैटिंग स्ट्रिंग्स के दौरान कनवर्ट कर रहे हैं तो आपको असंगत परिणाम मिल सकते हैं।

उदाहरण के लिए:

public enum Colour 
{ 
    Red=10, 
    Blue=11, 
    Green=12, 
    Crimson=10 
} 
Colour myColor = Colour.Crimson; 
Console.WriteLine("Crimson is {0}", myColor.ToString()); 

आउटपुट:

Crimson is Red 
0

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

public enum GestureType 
{ 
Touch = 1, 
Tap = 1, 
DoubleTouch = 2, 
DoubleTap = 2, 
Swipe = 3, 
Slide = 3, 
... 
} 

जब कुछ स्थितियों में अलग-अलग शब्दों का अर्थ समान होता है, तो उन्हें नाम देने का अर्थ होता है। पार्सिंग करते समय, यह हमेशा इस स्थिति में अच्छा मूल्य लौटाता है।पार्स से

void Main() 
{ 
    ((FieldName)Enum.Parse(typeof(FieldName), "Name", true)).ToString().Dump(); 
    ((FieldName)Enum.Parse(typeof(FieldName), "TaskName", true)).ToString().Dump(); 
    ((FieldName)Enum.Parse(typeof(FieldName), "IsActive", true)).ToString().Dump(); 
    ((FieldName)Enum.Parse(typeof(FieldName), "TaskIsActive", true)).ToString().Dump(); 
} 

public enum FieldName 
{ 
    Name, 
    TaskName = Name, 
    IsActive, 
    TaskIsActive = IsActive 
} 

उद्देश्य नामों में से कम का उपयोग कर रहा है, फिर भी परिणाम या TryParse संगत नहीं हैं और इस:

0

मैंने सोचा कि यह क्षेत्र मानचित्रण के लिए उपयोगी होगा, उदाहरण (LINQPad में) के लिए कोड आउटपुट:

TaskName 
TaskName 
IsActive 
IsActive 
संबंधित मुद्दे

 संबंधित मुद्दे