झंडे वाले Enum के मूल्यों पर पुनरावृति कैसे करें?


131

अगर मेरे पास एक फ़्लैग एनम पकड़े हुए वैरिएबल है, तो क्या मैं किसी तरह उस विशिष्ट वैरिएबल में बिट वैल्यू पर पुनरावृति कर सकता हूं? या क्या मुझे Enum.GetValues ​​का उपयोग पूरे एनम पर पुनरावृति करने के लिए करना है और यह देखना है कि कौन से सेट हैं?


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

2
मैं देख रहा हूं कि आप क्या कह रहे हैं, और कई मामलों में यह समझ में आता है, लेकिन इस मामले में, मुझे अगर सुझाव के रूप में एक ही समस्या होगी ... मुझे लिखना होगा यदि इसके बजाय एक दर्जन अलग-अलग बूल के लिए बयान। एक सरणी पर एक साधारण फोरच लूप का उपयोग करना। (और चूंकि यह एक सार्वजनिक DLL का हिस्सा है, मैं

10
"आपका कोड नाटकीय रूप से सरल है" - यदि आप व्यक्तिगत बिट्स का परीक्षण करने के अलावा कुछ भी कर रहे हैं तो पूरी तरह से विपरीत सच है ... लूप और सेट ऑपरेशन लगभग असंभव हो जाते हैं क्योंकि फ़ील्ड और गुण प्रथम श्रेणी के नहीं हैं।
जिम बाल्टर

2
@nawfal "थोड़ा सा" मैं देखता हूं कि आपने वहां क्या किया था
stannius

जवाबों:


179
static IEnumerable<Enum> GetFlags(Enum input)
{
    foreach (Enum value in Enum.GetValues(input.GetType()))
        if (input.HasFlag(value))
            yield return value;
}

7
ध्यान दें कि HasFlag.NET 4 से उपलब्ध है।
एंड्रियास ग्रीन

3
यह भी खूब रही! लेकिन आप इसे और भी सरल और उपयोग में आसान बना सकते हैं। इसे एक विस्तार विधि के रूप में Enum.GetValues(input.GetType()).Cast<Enum>().Where(input.HasFlag);myEnum.GetFLags()
चिपकाएँ

3
ग्रेट वन-लाइनर, जोश, लेकिन यह अभी भी जेफ के जवाब के रूप में, केवल एकल-ध्वज मूल्यों (बार, बाज) के बजाय बहु-ध्वज मूल्यों (बू) को चुनने की समस्या से ग्रस्त है।

10
नीस - हालांकि किसी के लिए बाहर देखो - जैसे आइटम। जेफ के जवाब से कोई भी हमेशा शामिल नहीं होगा
इलान

1
विधि हस्ताक्षर होना चाहिएstatic IEnumerable<Enum> GetFlags(this Enum input)
एरविन रूइजाक्कर्स

48

यहाँ समस्या का एक Linq समाधान है।

public static IEnumerable<Enum> GetFlags(this Enum e)
{
      return Enum.GetValues(e.GetType()).Cast<Enum>().Where(e.HasFlag);
}

7
यह सबसे ऊपर क्यों नहीं है ?? :) .Where(v => !Equals((int)(object)v, 0) && e.HasFlag(v));यदि आपके पास प्रतिनिधित्व करने के लिए शून्य मान है तो उपयोग करेंNone
georgiosd

बहुत साफ। मेरी राय में सबसे अच्छा समाधान।
रयान फियोरिनी

@georgiosd मुझे लगता है कि प्रदर्शन इतना बढ़िया नहीं है। (लेकिन अधिकांश कार्यों के लिए पर्याप्त होना चाहिए)
एंटीहेडशॉट

41

जहाँ तक मुझे पता है प्रत्येक घटक को प्राप्त करने के लिए कोई बिल्टइन विधियां नहीं हैं। लेकिन यहाँ एक तरह से आप उन्हें प्राप्त कर सकते हैं:

[Flags]
enum Items
{
    None = 0x0,
    Foo  = 0x1,
    Bar  = 0x2,
    Baz  = 0x4,
    Boo  = 0x6,
}

var value = Items.Foo | Items.Bar;
var values = value.ToString()
                  .Split(new[] { ", " }, StringSplitOptions.None)
                  .Select(v => (Items)Enum.Parse(typeof(Items), v));

// This method will always end up with the most applicable values
value = Items.Bar | Items.Baz;
values = value.ToString()
              .Split(new[] { ", " }, StringSplitOptions.None)
              .Select(v => (Items)Enum.Parse(typeof(Items), v)); // Boo

मैंने अनुकूलित किया कि Enumझंडे को वापस करने के लिए स्ट्रिंग उत्पन्न करने के लिए आंतरिक रूप से क्या करता है। आप परावर्तक में कोड को देख सकते हैं और कम या ज्यादा समतुल्य होना चाहिए। सामान्य उपयोग के मामलों के लिए अच्छी तरह से काम करता है जहां ऐसे मान होते हैं जिनमें कई बिट्स होते हैं।

static class EnumExtensions
{
    public static IEnumerable<Enum> GetFlags(this Enum value)
    {
        return GetFlags(value, Enum.GetValues(value.GetType()).Cast<Enum>().ToArray());
    }

    public static IEnumerable<Enum> GetIndividualFlags(this Enum value)
    {
        return GetFlags(value, GetFlagValues(value.GetType()).ToArray());
    }

    private static IEnumerable<Enum> GetFlags(Enum value, Enum[] values)
    {
        ulong bits = Convert.ToUInt64(value);
        List<Enum> results = new List<Enum>();
        for (int i = values.Length - 1; i >= 0; i--)
        {
            ulong mask = Convert.ToUInt64(values[i]);
            if (i == 0 && mask == 0L)
                break;
            if ((bits & mask) == mask)
            {
                results.Add(values[i]);
                bits -= mask;
            }
        }
        if (bits != 0L)
            return Enumerable.Empty<Enum>();
        if (Convert.ToUInt64(value) != 0L)
            return results.Reverse<Enum>();
        if (bits == Convert.ToUInt64(value) && values.Length > 0 && Convert.ToUInt64(values[0]) == 0L)
            return values.Take(1);
        return Enumerable.Empty<Enum>();
    }

    private static IEnumerable<Enum> GetFlagValues(Type enumType)
    {
        ulong flag = 0x1;
        foreach (var value in Enum.GetValues(enumType).Cast<Enum>())
        {
            ulong bits = Convert.ToUInt64(value);
            if (bits == 0L)
                //yield return value;
                continue; // skip the zero value
            while (flag < bits) flag <<= 1;
            if (flag == bits)
                yield return value;
        }
    }
}

विस्तार विधि में GetIndividualFlags()एक प्रकार के सभी व्यक्तिगत झंडे मिलते हैं। इसलिए कई बिट्स वाले मानों को छोड़ दिया जाता है।

var value = Items.Bar | Items.Baz;
value.GetFlags();           // Boo
value.GetIndividualFlags(); // Bar, Baz

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

दुर्भाग्य से ऐसा करने पर, आपको अनावश्यक मानों के लिए परीक्षण करना होगा (यदि उन्हें नहीं करना है)। मेरी दूसरी उदाहरण देखें, यह प्राप्त होते हैं Bar, Bazऔर Booबजाय सिर्फ की Boo
जेफ मर्काडो 5

दिलचस्प है कि आप बू से बाहर निकलने में सक्षम हैं, हालांकि वह हिस्सा अनावश्यक है (और वास्तव में, एक बहुत बुरा विचार :)) जो मैं कर रहा हूं।

यह दिलचस्प लग रहा है, लेकिन अगर मुझे गलतफहमी नहीं है, तो यह उपरोक्त एनम के लिए Boo लौटाएगा, जहां मैं केवल उन संस्करणों की गणना करना चाहता हूं जो अन्य मूल्यों के संयोजन नहीं हैं (यानी, जो दो की शक्तियां हैं) । क्या यह आसानी से हो सकता है? मैं कोशिश कर रहा हूं और मैं एफपी गणित का सहारा लिए बिना इसे पहचानने का आसान तरीका नहीं सोच सकता।

@ रॉबिन: आप सही कह रहे हैं, मूल वापस आ जाएगा Boo(मान का उपयोग करके लौटा ToString())। मैंने इसे केवल व्यक्तिगत झंडे की अनुमति देने के लिए ट्विक किया है। तो मेरे उदाहरण में, आप प्राप्त कर सकते हैं Barऔर Bazइसके बजाय Boo
जेफ मर्काडो

26

कुछ साल बाद इस पर वापस आते हुए, थोड़ा और अधिक अनुभव के साथ, एकल-बिट मूल्यों के लिए मेरा अंतिम उत्तर, सबसे कम बिट से उच्चतम बिट तक जा रहा है, जेफ मर्कडो की आंतरिक दिनचर्या का एक मामूली रूप है:

public static IEnumerable<Enum> GetUniqueFlags(this Enum flags)
{
    ulong flag = 1;
    foreach (var value in Enum.GetValues(flags.GetType()).Cast<Enum>())
    {
        ulong bits = Convert.ToUInt64(value);
        while (flag < bits)
        {
            flag <<= 1;
        }

        if (flag == bits && flags.HasFlag(value))
        {
            yield return value;
        }
    }
}

यह काम करने लगता है, और कुछ साल पहले मेरी आपत्तियों के बावजूद, मैं यहाँ हैसफलग का उपयोग करता हूं, क्योंकि यह बिटवाइज तुलनाओं की तुलना में कहीं अधिक सुपाठ्य है और गति अंतर मैं किसी भी चीज के लिए महत्वहीन हूं। (यह पूरी तरह से संभव है कि उन्होंने तब से HasFlags की गति में सुधार किया है, सभी के लिए मुझे पता है ... मैंने परीक्षण नहीं किया है।)


बस एक टिप्पणी झंडा किसी पूर्णांक पर आरंभ नहीं हो जाता करने के लिए किया जाना चाहिए एक ऐसी बिट्स के रूप में Ulong, के रूप में प्रारंभ किया जाना चाहिए 1UL
forcewill

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

2
यह एकमात्र समाधान है जो मैंने पाया है कि इस तथ्य से भी ग्रस्त नहीं है कि यदि आपके पास एक ध्वज है जिसका मूल्य शून्य है, जिसे "कोई नहीं" का प्रतिनिधित्व करना चाहिए, तो अन्य जवाब GetFlag () विधियाँ YourEnum को लौटा देंगी। किसी एक झंडे के रूप में। यहां तक ​​कि अगर यह वास्तव में Enum में आप पर विधि चला रहे हैं नहीं है! मुझे अजीब डुप्लिकेट लॉग प्रविष्टियाँ मिल रही थीं क्योंकि विधियाँ मेरी अपेक्षा से अधिक बार चल रही थीं जब उनके पास केवल एक गैर-शून्य एनुम ध्वज सेट था। इस महान समाधान में अद्यतन करने और जोड़ने के लिए समय निकालने के लिए धन्यवाद!
ब्रायन एचएच

yield return bits;?
जैदर

1
मुझे "ऑल" एनम वैरिएबल चाहिए था, जिसके लिए मैंने ulong.MaxValue असाइन किया था, इसलिए सभी बिट्स '1' पर सेट हैं। लेकिन आपका कोड एक अनंत लूप से टकराता है, क्योंकि झंडा <बिट्स कभी भी सच का मूल्यांकन नहीं करता है (ध्वज लूप नकारात्मक तक पहुंच जाता है और फिर 0 पर अटक जाता है)।
हाईगेस्ट्रॉम

15

@ ग्रेग की विधि से दूर जा रहा है, लेकिन सी # 7.3 से एक नई सुविधा जोड़ रहा है, Enumबाधा:

public static IEnumerable<T> GetUniqueFlags<T>(this Enum flags)
    where T : Enum    // New constraint for C# 7.3
{
    foreach (Enum value in Enum.GetValues(flags.GetType()))
        if (flags.HasFlag(value))
            yield return (T)value;
}

नई बाधा के माध्यम से कास्ट करने के लिए बिना, इस एक विस्तार विधि होने की अनुमति देता (int)(object)eहै, और मैं उपयोग कर सकते हैं HasFlagकरने के लिए सीधे विधि और कलाकारों Tसे value

सी # 7.3 भी delagates के लिए और बाधाओं को जोड़ा unmanaged


4
आप शायद flagsपैरामीटर को सामान्य प्रकार का होना चाहते थे T, अन्यथा हर बार जब आप इसे कहते हैं, तो आपको स्पष्ट रूप से एनम प्रकार को निर्दिष्ट करना होगा।
रे

11

@ RobinHood70 द्वारा दिए गए उत्तर के लिए +1। मैंने पाया कि विधि का एक सामान्य संस्करण मेरे लिए सुविधाजनक था।

public static IEnumerable<T> GetUniqueFlags<T>(this Enum flags)
{
    if (!typeof(T).IsEnum)
        throw new ArgumentException("The generic type parameter must be an Enum.");

    if (flags.GetType() != typeof(T))
        throw new ArgumentException("The generic type parameter does not match the target type.");

    ulong flag = 1;
    foreach (var value in Enum.GetValues(flags.GetType()).Cast<T>())
    {
        ulong bits = Convert.ToUInt64(value);
        while (flag < bits)
        {
            flag <<= 1;
        }

        if (flag == bits && flags.HasFlag(value as Enum))
        {
            yield return value;
        }
    }
}

EDIT और +1 समाधान स्थान में C # 7.3 लाने के लिए @AustinWBryan के लिए।

public static IEnumerable<T> GetUniqueFlags<T>(this T flags) where T : Enum
{
    ulong flag = 1;
    foreach (var value in Enum.GetValues(flags.GetType()).Cast<T>())
    {
        ulong bits = Convert.ToUInt64(value);
        while (flag < bits)
        {
            flag <<= 1;
        }

        if (flag == bits && flags.HasFlag(value as Enum))
        {
            yield return value;
        }
    }
}

3

आपको सभी मूल्यों को पुनरावृत्त करने की आवश्यकता नहीं है। बस अपने विशिष्ट झंडे की जाँच करें जैसे:

if((myVar & FlagsEnum.Flag1) == FlagsEnum.Flag1) 
{
   //do something...
}

या (जैसा कि pstrjds ने टिप्पणियों में कहा था) आप इसका उपयोग करने के लिए जाँच कर सकते हैं:

if(myVar.HasFlag(FlagsEnum.Flag1))
{
   //do something...
}

5
यदि आप .Net 4.0 का उपयोग कर रहे हैं, तो एक विस्तार विधि HasFlag है जिसे आप एक ही काम करने के लिए उपयोग कर सकते हैं: myVar.HasFlag (FlagsEnum.Flag1)
pstrjds

1
यदि एक प्रोग्रामर एक बिटवाइज़ और ऑपरेशन को नहीं समझ सकता है तो उन्हें इसे पैक करना चाहिए और एक नया करियर ढूंढना चाहिए।
एड एस।

2
@ ईडी: सच है, लेकिन जब आप फिर से कोड पढ़ रहे हैं तो हस्फलाग बेहतर है ... (शायद कुछ महीनों या वर्षों के बाद)
डॉ। टीजे

4
@ एड स्वांगरेन: यह वास्तव में कोड को अधिक पठनीय और कम क्रियात्मक बनाने के बारे में है, जरूरी नहीं कि क्योंकि बिटवाइन का उपयोग करना बहुत कठिन है। "
जेफ मर्काडो

2
HasFlag काफी धीमा है। HasFlag बनाम बिट-मास्किंग का उपयोग करके एक बड़े लूप का प्रयास करें और आपको एक बड़ा अंतर दिखाई देगा।

3

मैंने जो किया वह मेरे दृष्टिकोण को बदलने का था, टाइप के तरीके के इनपुट पैरामीटर को टाइप करने के बजाय enum, मैंने इसे टाइप की एक सरणी के रूप में enumटाइप किया ( MyEnum[] myEnums), इस तरह से मैं लूप के अंदर एक स्विच स्टेटमेंट के साथ एरे के माध्यम से पुनरावृति करता हूं।


2

ऊपर दिए गए जवाबों से संतुष्ट नहीं थे, हालांकि वे शुरुआत थे।

यहाँ कुछ अलग स्रोतों को एक साथ रखने के बाद:
इस धागे के SO QnA
कोड प्रोजेक्ट Enum फ्लैग में पिछला पोस्टर चेक पोस्ट
महान Enum <T> उपयोगिता

मैंने इसे बनाया है इसलिए मुझे बताएं कि आप क्या सोचते हैं।
पैरामीटर::
bool checkZeroइसे 0ध्वज मूल्य के रूप में अनुमति देने के लिए कहता है । डिफ़ॉल्ट रूप से input = 0खाली है।
bool checkFlags: यह जाँचने के लिए बताता है कि क्या Enumसजाया w / [Flags]विशेषता है।
पुनश्च। मेरे पास अभी समय नहीं है कि हम इस checkCombinators = falsealg का पता लगा सकें जो इसे किसी भी एनुम मान को अनदेखा करने के लिए मजबूर करेगा जो बिट्स के संयोजन हैं।

    public static IEnumerable<TEnum> GetFlags<TEnum>(this TEnum input, bool checkZero = false, bool checkFlags = true, bool checkCombinators = true)
    {
        Type enumType = typeof(TEnum);
        if (!enumType.IsEnum)
            yield break;

        ulong setBits = Convert.ToUInt64(input);
        // if no flags are set, return empty
        if (!checkZero && (0 == setBits))
            yield break;

        // if it's not a flag enum, return empty
        if (checkFlags && !input.GetType().IsDefined(typeof(FlagsAttribute), false))
            yield break;

        if (checkCombinators)
        {
            // check each enum value mask if it is in input bits
            foreach (TEnum value in Enum<TEnum>.GetValues())
            {
                ulong valMask = Convert.ToUInt64(value);

                if ((setBits & valMask) == valMask)
                    yield return value;
            }
        }
        else
        {
            // check each enum value mask if it is in input bits
            foreach (TEnum value in Enum <TEnum>.GetValues())
            {
                ulong valMask = Convert.ToUInt64(value);

                if ((setBits & valMask) == valMask)
                    yield return value;
            }
        }

    }

यह हेल्पर क्लास Enum <T> का उपयोग यहां करता है जिसे मैंने यहां उपयोग के yield returnलिए अद्यतन किया है GetValues:

public static class Enum<TEnum>
{
    public static TEnum Parse(string value)
    {
        return (TEnum)Enum.Parse(typeof(TEnum), value);
    }

    public static IEnumerable<TEnum> GetValues()   
    {
        foreach (object value in Enum.GetValues(typeof(TEnum)))
            yield return ((TEnum)value);
    }
}  

अंत में, यहाँ इसका उपयोग करने का एक उदाहरण है:

    private List<CountType> GetCountTypes(CountType countTypes)
    {
        List<CountType> cts = new List<CountType>();

        foreach (var ct in countTypes.GetFlags())
            cts.Add(ct);

        return cts;
    }

क्षमा करें, इस परियोजना को कई दिनों में देखने का समय नहीं मिला है। एक बार आपके कोड पर बेहतर नज़र डालने के बाद मैं आपसे वापस मिलूंगा।

4
बस एक सिर है कि उस कोड में एक बग है। If (checkCombinators) स्टेटमेंट की दोनों शाखाओं में कोड समान है। इसके अलावा, शायद एक बग नहीं, लेकिन अप्रत्याशित, यह है कि यदि आपके पास 0 के लिए घोषित एनम मूल्य है, तो यह हमेशा संग्रह में वापस आ जाएगा। ऐसा लगता है कि केवल तभी लौटा जाना चाहिए जब चेकजेरो सच है और कोई अन्य झंडे सेट नहीं हैं।
धोखे से

@dhochee। मैं सहमत हूँ। या कोड बहुत अच्छा है, लेकिन तर्क भ्रमित हैं।
AF'१27 को

2

ऊपर दिए गए ग्रेग के उत्तर के आधार पर, यह उस मामले का भी ध्यान रखता है, जहाँ आपके पास आपकी एनुम में मान 0 है, जैसे कोई नहीं = 0. किस स्थिति में, उस मान पर पुनरावृति नहीं होनी चाहिए।

public static IEnumerable<Enum> ToEnumerable(this Enum input)
{
    foreach (Enum value in Enum.GetValues(input.GetType()))
        if (input.HasFlag(value) && Convert.ToInt64(value) != 0)
            yield return value;
}

क्या किसी को पता होगा कि इस पर आगे भी कैसे सुधार किया जाए, ताकि यह उस मामले को संभाल सके जहां Enum में सभी झंडे एक सुपर स्मार्ट तरीके से सेट किए गए हैं जो सभी अंतर्निहित Enum प्रकार और All = ~ 0 और All = EnumValue1 के मामले को संभाल सकते हैं। EnumValue2 | EnumValue3 | ...


1

आप Enum से एक Iterator का उपयोग कर सकते हैं। MSDN कोड से शुरू:

public class DaysOfTheWeek : System.Collections.IEnumerable
{
    int[] dayflag = { 1, 2, 4, 8, 16, 32, 64 };
    string[] days = { "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun" };
    public string value { get; set; }

    public System.Collections.IEnumerator GetEnumerator()
    {
        for (int i = 0; i < days.Length; i++)
        {
            if value >> i & 1 == dayflag[i] {
                yield return days[i];
            }
        }
    }
}

यह परीक्षण नहीं किया गया है, इसलिए यदि मुझे कोई गलती हुई तो मुझे बाहर बुलाने के लिए स्वतंत्र महसूस करें। (स्पष्ट रूप से यह फिर से प्रवेश नहीं है।) आपको पहले से मान असाइन करना होगा, या इसे किसी अन्य फ़ंक्शन में तोड़ना होगा जो enum.dayflag और enum.days का उपयोग करता है। आप रूपरेखा के साथ कहीं जाने में सक्षम हो सकते हैं।


0

यह निम्नलिखित कोड के रूप में अस्वस्थ हो सकता है:

public static string GetEnumString(MyEnum inEnumValue)
{
    StringBuilder sb = new StringBuilder();

    foreach (MyEnum e in Enum.GetValues(typeof(MyEnum )))
    {
        if ((e & inEnumValue) != 0)
        {
           sb.Append(e.ToString());
           sb.Append(", ");
        }
    }

   return sb.ToString().Trim().TrimEnd(',');
}

यह तभी अंदर जाता है जब एनुम वैल्यू वैल्यू पर निहित हो


0

सभी उत्तर सरल झंडे के साथ अच्छी तरह से काम करते हैं, आप संभवतः झंडे के संयुक्त होने पर मुद्दों में शामिल होने जा रहे हैं।

[Flags]
enum Food
{
  None=0
  Bread=1,
  Pasta=2,
  Apples=4,
  Banana=8,
  WithGluten=Bread|Pasta,
  Fruits = Apples | Banana,
}

शायद यह जांचने के लिए एक जांच को जोड़ने की जरूरत है कि अगर एनम का मूल्य स्वयं का संयोजन है। आपको अपनी आवश्यकता को पूरा करने के लिए हेनक वैन बोइजेन द्वारा यहां पोस्ट की गई चीज़ की आवश्यकता होगी (आपको थोड़ा नीचे स्क्रॉल करने की आवश्यकता है)


0

कास्टिंग को रोकने के लिए नई Enum बाधा और जेनरिक का उपयोग कर विस्तार विधि:

public static class EnumExtensions
{
    public static T[] GetFlags<T>(this T flagsEnumValue) where T : Enum
    {
        return Enum
            .GetValues(typeof(T))
            .Cast<T>()
            .Where(e => flagsEnumValue.HasFlag(e))
            .ToArray();
    }
}

-1

आप इसे सीधे int में कनवर्ट करके कर सकते हैं लेकिन आप टाइपिंग की जाँच ढीली कर देंगे। मुझे लगता है कि सबसे अच्छा तरीका मेरे प्रस्ताव के समान कुछ का उपयोग करना है। यह सभी प्रकार से उचित प्रकार रखता है। कोई रूपांतरण आवश्यक नहीं है। यह बॉक्सिंग के कारण बिल्कुल सही नहीं है जो प्रदर्शन में थोड़ा हिट जोड़ देगा।

बिल्कुल सही (मुक्केबाजी) नहीं, लेकिन यह बिना किसी चेतावनी के काम करता है ...

/// <summary>
/// Return an enumerators of input flag(s)
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
public static IEnumerable<T> GetFlags<T>(this T input)
{
    foreach (Enum value in Enum.GetValues(input.GetType()))
    {
        if ((int) (object) value != 0) // Just in case somebody has defined an enum with 0.
        {
            if (((Enum) (object) input).HasFlag(value))
                yield return (T) (object) value;
        }
    }
}

उपयोग:

    FileAttributes att = FileAttributes.Normal | FileAttributes.Compressed;
    foreach (FileAttributes fa in att.GetFlags())
    {
        ...
    }
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.