एक ORUM एनम के लिए एक आइटम कैसे निकालें?


181

मेरे पास एक एनम है:

public enum Blah
{
    RED = 2,
    BLUE = 4,
    GREEN = 8,
    YELLOW = 16
}

Blah colors = Blah.RED | Blah.BLUE | Blah.YELLOW;

मैं चर रंगों से रंग को कैसे हटा सकता हूं?


2
छोटे नोट: C # में एक बिटवाइन एनम को इसके ऊपर [फ्लैग्स] विशेषता मिलनी चाहिए।
Nyerguds

@ नीयरग्स, क्या आप बता सकते हैं कि इसे विशेषता क्यों मिलनी चाहिए?
इथेन

यह डीबगिंग के दौरान बेहतर इंटेलीसेनस समर्थन देता है, क्योंकि यह अज्ञात एनम मूल्यों को मौजूदा मूल्यों के संयोजन के रूप में पहचानता है।
Nyerguds

1
यह अधिक सार्थक .ToString()मूल्य भी प्रदान करता है । के RED, BLUE, YELLOWबजाय उदाहरण के लिए 22
सिंजई

जवाबों:


331

आपको 'BLUE' &के ~(पूरक) साथ इसकी आवश्यकता है ।

पूरक ऑपरेटर आवश्यक रूप से दिए गए डेटा प्रकार के लिए सभी बिट्स को उलट या 'फ़्लिप' करता है। जैसे, यदि आप उपयोग करते हैंAND& कुछ मान के साथ ऑपरेटर ( ) का (चलो उस मान को 'X' कहते हैं) और एक या अधिक सेट बिट्स के पूरक (चलो उन बिट्स Qऔर उनके पूरक को कॉल करें ~Q), स्टेटमेंट X & ~Qकिसी भी बिट्स को साफ़ करता है जो इसमें सेट किए गए थे Qसे Xऔर परिणाम देता है।

तो BLUEबिट्स को हटाने या साफ़ करने के लिए , आप निम्न कथन का उपयोग करते हैं:

colorsWithoutBlue = colors & ~Blah.BLUE
colors &= ~Blah.BLUE // This one removes the bit from 'colors' itself

आप कई बिट्स को स्पष्ट करने के लिए निर्दिष्ट कर सकते हैं, निम्नानुसार हैं:

colorsWithoutBlueOrRed = colors & ~(Blah.BLUE | Blah.RED)
colors &= ~(Blah.BLUE | Blah.RED) // This one removes both bits from 'colors' itself

या वैकल्पिक रूप से ...

colorsWithoutBlueOrRed = colors & ~Blah.BLUE & ~Blah.RED
colors &= ~Blah.BLUE & ~Blah.RED // This one removes both bits from 'colors' itself

इसलिए संक्षेप में:

  • X | Q बिट्स सेट करता है Q
  • X & ~Q क्लीयर बिट्स Q
  • ~X flips / सभी बिट्स को इन्वर्ट करता है X

1
इसलिए यदि मैं अधिक निकालना चाहता था तो मैं बस करूंगा: & = ~ Blah.BLUE & ~ Blah.Green
ब्लैंकमैन

11
बेहतर हैcolors &= ~( Blah.BLUE | Blah.GREEN );
बराबर

2
कितना असामान्य है, मैं सोच रहा था कि यह कैसे करना है फिर भी लगभग 5 दिन पहले :) यह सवाल मेरे इनबॉक्स और वॉइला में अपडेट किया गया!
ब्लैंकमैन

बहुत बढ़िया जवाब। मुझे लगता है कि आप "और =" नहीं "= और" हालांकि, अपने कोड के नमूनों में मतलब;)
डेव Jellison

48

अन्य उत्तर सही हैं, लेकिन विशेष रूप से ऊपर से नीले रंग को हटाने के लिए आप लिखेंगे:

colors &= ~Blah.BLUE;


7

सोचा कि यह मेरे जैसे अन्य लोगों के लिए उपयोगी हो सकता है।

सावधान रहें कि आप किसी भी एनम मूल्यों को कैसे संभालते हैं जो आप मान == 0 के लिए निर्धारित कर सकते हैं (कभी-कभी यह एनम के लिए एक अज्ञात या निष्क्रिय स्थिति के लिए सहायक हो सकता है)। जब इन बिट हेरफेर ऑपरेशन पर भरोसा करते हैं तो यह समस्या पैदा करता है।

इसके अलावा जब आपके पास एनम मान है जो 2 मानों की अन्य शक्ति के संयोजन हैं, जैसे

public enum Colour
{
    None = 0,  // default value
    RED = 2,
    BLUE = 4,
    GREEN = 8,
    YELLOW = 16,
    Orange = 18  // Combined value of RED and YELLOW
}

इन मामलों में एक विस्तार विधि जैसे कि यह काम आ सकती है:

public static Colour UnSet(this Colour states, Colour state)
{
    if ((int)states == 0)
        return states;

    if (states == state)
        return Colour.None;

    return states & ~state;
}

और समतुल्य आइससेट विधि भी है जो संयुक्त मूल्यों को संभालती है (यद्यपि हैकी तरीके से थोड़ा सा)

public static bool IsSet(this Colour states, Colour state)
{
    // By default if not OR'd
    if (states == state)
        return true;

    // Combined: One or more bits need to be set
    if( state == Colour.Orange )
        return 0 != (int)(states & state);

    // Non-combined: all bits need to be set
    return (states & state) == state;
}

यह मुझे लगता है कि सरल उपाय 0 को ध्वज के रूप में उपयोग करने से बचना है। मैं आमतौर पर इस तरह से झंडा लगाता हूं । मैं यह नहीं देखता कि आप 0. के मान के साथ किसी राज्य को निर्दिष्ट करने से कैसे लाभान्वित होते हैं। आखिर, पूरे बिंदु यह है कि आप Red, Blue, Greenअंतर्निहित मूल्यों के बजाय प्रोग्रामर-फ्रेंडली नामों ( ) के साथ खुद को चिंतित कर सकते हैं, हाँ?
सिंजई

बीत रहा है एक noneया unknownया unsetमूल्य == 0 के साथ प्रवेश कई मामलों में है एक अच्छी बात है के रूप में आप हमेशा कल्पना नहीं कर सकते कि एक विशेष मूल्य डिफ़ॉल्ट सेट, जैसे है अगर आप केवल है लाल, नीला और हरा आप लाल के रूप में करने के लिए जा रहे हैं डिफ़ॉल्ट मान (उदाहरण के लिए यह मान कि
एनुम

क्या आपके पास सिर्फ Unset = 1 नहीं है और 1, 2, 4, 8आपके मूल्यों के रूप में उपयोग करें? यदि आपको एक डिफ़ॉल्ट मान की आवश्यकता है, तो यह है कि क्या डिफ़ॉल्ट निर्माणकर्ता सही हैं? मैं पठनीयता के लिए यथासंभव चीजों को स्पष्ट रखना पसंद करता हूं, और किसी भी डेवलपर द्वारा ज्ञात जानकारी होने के बावजूद, जब कोई मूल्य नहीं दिया जाता है, तो डिफ़ॉल्ट रूप से default(int)( 0) के लिए डिफ़ॉल्ट रूप से भरोसा करना पसंद है, वैसे भी मेरे स्वाद के लिए बहुत डरपोक है। संपादित करें: ओह रुको, परेशान कर देगा = 0 कुछ होने से रोकें Unset | Blue?
सिंजई

आप अपने संपादित Sinjai में सही रास्ते पर हैं, और परेशान मूल्य == 0 रखते हुए वास्तव में कुछ समस्याओं को हल करता है। एक जो आपने उल्लेख किया है और एक और अगर आप सभी एनम मूल्यों को परेशान करते हैं तो आपको "अनसेट" के लिए एक विशेष मामले की आवश्यकता नहीं है यदि यह शून्य पर सेट है। (उदाहरण यदि आप Red & ~Redतब शून्य के साथ समाप्त होते हैं तो आपके पास इस मामले की जाँच करने के लिए कोड होना चाहिए और Unsetमूल्य को स्पष्ट रूप से निर्दिष्ट करना होगा )
Sverrir Sigmundarson

पकड़ लिया। क्या आप अक्सर खुद को परेशान झंडे से निपटने में पाते हैं?
सिंजई

2

Xor (^) के बारे में क्या?

यह देखते हुए कि आप जिस FLAG को निकालने की कोशिश कर रहे हैं, वह वहां है। यह काम करेगा .. यदि नहीं, तो आपको a & का उपयोग करना होगा।

public enum Colour
{
    None = 0,  // default value
    RED = 2,
    BLUE = 4,
    GREEN = 8,
    YELLOW = 16,
    Orange = 18  // Combined value of RED and YELLOW
}

colors = (colors ^ Colour.RED) & colors;

1

फ्लैग एनम को सरल बनाने के लिए और इसे मल्टीप्ले से बचकर पढ़ना बेहतर हो सकता है, हम बिट शिफ्टिंग का उपयोग कर सकते हैं। (एक अच्छे लेख से एनुम झंडे पर महान बहस समाप्त )

[FLAG]
Enum Blah
{
   RED = 1,
   BLUE = 1 << 1,
   GREEN = 1 << 2,
   YELLOW = 1 << 3
}

और सभी बिट्स को साफ़ करने के लिए भी

private static void ClearAllBits()
{
    colors = colors & ~colors;
}

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