এনামের পতাকা থাকাতে কীভাবে মানগুলি পুনরুক্ত করা যায়?


131

যদি আমার কাছে একটি এনগম ফ্ল্যাগ এনাম থাকে তবে আমি কি সেই নির্দিষ্ট ভেরিয়েবলের বিট মানগুলি নিয়ে পুনরাবৃত্তি করতে পারি? অথবা পুরো এনামের উপরে পুনরাবৃত্তি করতে এবং কোনটি সেট করা আছে তা পরীক্ষা করতে আমাকে এনাম.গেটভ্যালু ব্যবহার করতে হবে?


আপনার এপিআই-তে যদি নিয়ন্ত্রণ থাকে তবে বিট ফ্ল্যাগ ব্যবহার এড়িয়ে চলুন। তারা খুব কমই একটি দরকারী অপ্টিমাইজেশন। বেশ কয়েকটি পাবলিক 'বুল' ক্ষেত্রের সাথে কাঠামো ব্যবহার করা শব্দার্থগত সমতুল্য তবে আপনার কোডটি নাটকীয়ভাবে সহজ। এবং যদি আপনার পরে প্রয়োজন হয়, আপনি ক্ষেত্রগুলি এমন বৈশিষ্ট্যগুলিতে পরিবর্তন করতে পারেন যা বিট ক্ষেত্রগুলিকে অভ্যন্তরীণভাবে ম্যানিপুলেট করে, অপ্টিমাইজেশন encapsulating।
জে বাজুজি

2
আপনি যা বলছেন তা আমি দেখতে পাচ্ছি, এবং অনেক ক্ষেত্রে এটি বোঝা যায় তবে এই ক্ষেত্রে আমার যদি ইফ পরামর্শ হিসাবে একই সমস্যা হত ... তবে আমি লিখতে হত যদি তার পরিবর্তে কয়েক ডজন বুলের জন্য বিবৃতি লিখতে হত একটি অ্যারের উপরে একটি সরল ফোরচ লুপ ব্যবহার করে। (এবং যেহেতু এটি একটি পাবলিক ডিএলএল এর অংশ, তাই আমি কেবল বুলির অ্যারে থাকা বা আপনার কাছে যা আছে তার মতো আরকেন কাজ করতে পারি না))

10
"আপনার কোডটি নাটকীয়ভাবে সহজ" - যদি আপনি স্বতন্ত্র বিট পরীক্ষা না করে অন্য কিছু করেন তবে সম্পূর্ণ বিপরীতটি সত্য ... লুপ এবং সেট ক্রিয়াকলাপ কার্যত অসম্ভব হয়ে যায় কারণ ক্ষেত্র এবং সম্পত্তি প্রথম শ্রেণীর সত্তা নয়।
জিম বাল্টার

উত্তর:


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

7
নোট HasFlag4 .NET 4 এর পরে উপলব্ধ।
Andreas গ্রেচ

3
এটা অসাধারণ! তবে আপনি এটিকে আরও সহজ এবং সহজ ব্যবহার করতে পারেন। এটি কেবল একটি এক্সটেনশান পদ্ধতি হিসাবে আটকে দিন: Enum.GetValues(input.GetType()).Cast<Enum>().Where(input.HasFlag); তারপরে ঠিক: myEnum.GetFLags():)
জোশকমলে

3
দুর্দান্ত ওয়ান-লাইনার, জোশ, তবে এটি উপরে জেফের উত্তর হিসাবে কেবলমাত্র একক পতাকা-মূল্য (বার, বাজ) এর পরিবর্তে একাধিক-পতাকা-মান (বুও) বাছাইয়ের সমস্যায় ভুগছে।

10
ভাল - কারও জন্য নজর রাখবেন না - যেমন আইটেমস Je জেফের উত্তর থেকে কোনওটি সর্বদা অন্তর্ভুক্ত থাকবে
Ilan

1
পদ্ধতির স্বাক্ষর হওয়া উচিতstatic IEnumerable<Enum> GetFlags(this Enum input)
এরউইন রুইজাকার্স

48

সমস্যাটির একটি লিনক সমাধান এখানে।

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
23:37

সুপার ক্লিন আমার মতে সেরা সমাধান।
রায়ান ফিয়েরিনি

@ জর্জিওড আমি অনুমান করি যে পারফরম্যান্সটি দুর্দান্ত নয় not (তবে বেশিরভাগ কাজের জন্য যথেষ্ট ভাল হওয়া উচিত)
এন্টিহ্যাডশট

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অভ্যন্তরীণভাবে স্ট্রিং তৈরি করতে ফ্ল্যাগগুলি ফিরিয়ে আনার জন্য যা রূপান্তরিত করেছি does আপনি কোডটি প্রতিফলকের দিকে দেখতে পারেন এবং কম বা বেশি সমতুল্য হওয়া উচিত। সাধারণ ব্যবহারের ক্ষেত্রে খুব ভাল কাজ করে যেখানে একাধিক বিট রয়েছে এমন মান রয়েছে।

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
জেফ মার্কাডো

মজার বিষয় হচ্ছে যে আমি কী করছি তার জন্য আপনি সেই অংশটিকে অপ্রয়োজনীয় (এবং বাস্তবে একটি সত্যই খারাপ ধারণা :)) বানাতে সক্ষম হন।

এটি আকর্ষণীয় দেখায়, তবে আমি যদি ভুল বোঝাবুঝি না করি তবে এটি উপরের এনামের জন্য বুকে ফিরে আসবে, যেখানে আমি কেবল এমন সংস্করণগুলিই গণনা করতে চাই যা অন্যান্য মানের সংমিশ্রণ নয় (উদাহরণস্বরূপ, দুটি হিসাবে দুটি) । তা কি সহজেই করা যায়? আমি চেষ্টা করে যাচ্ছি এবং এফপি গণিতে অবলম্বন না করে সনাক্ত করার সহজ উপায় সম্পর্কে আমি ভাবতে পারি না।

@ রবিন: আপনি ঠিক বলেছেন, আসলটি ফিরে আসবে 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;
        }
    }
}

এটি কাজ করছে বলে মনে হচ্ছে এবং কয়েক বছর আগে আমার আপত্তি সত্ত্বেও আমি এখানে হ্যাসফ্ল্যাগ ব্যবহার করেছি, যেহেতু এটি বিটওয়াইজ তুলনা ব্যবহার করার চেয়ে অনেক বেশি সুশাস্ত্র এবং গতির তফাত আমি যে কিছু করব তার পক্ষে তাত্পর্যপূর্ণ। (এটি সম্পূর্ণরূপে সম্ভব যেহেতু তারা যাইহোক হ্যাশফ্লাগগুলির গতি উন্নত করেছে, আমি জানি সকলের জন্য ... আমি পরীক্ষা করিনি))


কেবলমাত্র একটি নোট পতাকা একটি প্রান্তে আরম্ভ করা হয় যেমন বিটগুলির
ফোর্স উইল

ধন্যবাদ, আমি এটি ঠিক করব! (আমি মাত্র গিয়েছিলাম এবং আমার আসল কোডটি পরীক্ষা করে দেখেছি এবং এটি ইতিমধ্যে উলং হিসাবে ঘোষণা করে ইতিমধ্যে অন্যভাবে ঠিক করেছি))

2
এটিই আমি একমাত্র সমাধান পেয়েছি যা দেখে মনে হয় না যে আপনার যদি শূন্য মানের একটি পতাকা থাকে যা "কিছুই নয়" উপস্থাপন করে তবে অন্যান্য উত্তর গেটফ্ল্যাগ () পদ্ধতিগুলি আপনার পতাকাটি এক হিসাবে প্রত্যাবর্তন করবে। এমনকি এটি এনামে না থাকলেও আপনি পদ্ধতিটি চালাচ্ছেন! আমি অদ্ভুত সদৃশ লগ এন্ট্রিগুলি পেয়েছিলাম কারণ পদ্ধতিগুলি আমার প্রত্যাশার চেয়ে বেশি সময় চলছিল যখন তাদের কাছে কেবল একটি শূন্য-এনাম পতাকা সেট ছিল। এই দুর্দান্ত সমাধানটিতে আপডেট এবং যোগ করার জন্য সময় দেওয়ার জন্য ধন্যবাদ!
ব্রায়ানএইচ

yield return bits;?
জায়েদার

1
আমি একটি "অল" এনাম ভেরিয়েবল চাইছিলাম, যার জন্য আমি উলংকে অর্পণ করেছি ax ম্যাক্সভ্যালু, সুতরাং সমস্ত বিট '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 এছাড়াও ডেলাগেট এবং এর জন্য প্রতিবন্ধকতা যুক্ত করেছে unmanaged


4
আপনি সম্ভবত flagsপ্যারামিটারটি জেনেরিক প্রকারের হতে চেয়েছিলেন T, অন্যথায় আপনি যতবারই কল করবেন প্রত্যেকবার আপনাকে অবশ্যই এনাম টাইপটি স্পষ্টভাবে উল্লেখ করতে হবে।
রায়

11

@ রবিনহুড 70 দ্বারা সরবরাহিত উত্তরের জন্য +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;
        }
    }
}

সমাধানের জায়গায় সি # 7.3 আনার জন্য @ অস্টিন ডাব্লু ব্রায়ানের জন্য সম্পাদনা করুন এবং +1 করুন।

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...
}

বা (যেমন পিএসটিজেডস মন্তব্যে বলেছে) আপনি এটির মতো ব্যবহারের জন্য এটি পরীক্ষা করতে পারেন:

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

5
আপনি নেট নেট 4.0.০ ব্যবহার করে থাকেন তবে এখানে একটি এক্সটেনশন পদ্ধতি হ্যাসফ্ল্যাগ রয়েছে যা আপনি একই জিনিসটি করতে ব্যবহার করতে পারেন: myVar.HasFlag (ফ্ল্যাগসনাম। ফ্ল্যাগ 1)
পিএসটিজেডস

1
যদি কোনও প্রোগ্রামার কিছুটা দিকনির্দেশ এবং অপারেশন বুঝতে না পারে তবে তাদের উচিত এটি প্যাক করে নতুন ক্যারিয়ার সন্ধান করা।
এড এস

2
@ এড: সত্য, তবে আপনি যখন আবার কোড পড়ছেন তখন হাসফ্লেগ আরও ভাল ... (সম্ভবত কিছু মন্থেস বা বছর পরে)
ডঃ টিজে

4
@ এড সোয়াংগ্রেন: কোডটি আরও পঠনযোগ্য এবং কম ভার্বোস তৈরি করার বিষয়ে এটি সত্যই, কারণ বিটওয়াইজ অপারেশনগুলি "শক্ত"।
জেফ মার্কাডো

2
হ্যাশফ্লাগ অত্যন্ত ধীর। হাসফ্লেগ বনাম বিট-মাস্কিং ব্যবহার করে একটি বৃহত লুপ ব্যবহার করে দেখুন এবং আপনি একটি বিশাল পার্থক্য লক্ষ্য করবেন।

3

আমি যা করেছি তা ছিল আমার পদ্ধতির পরিবর্তন, পদ্ধতির ইনপুট প্যারামিটারটি টাইপ হিসাবে টাইপ করার পরিবর্তে enum, আমি এটিকে enumটাইপ ( MyEnum[] myEnums) এর অ্যারে হিসাবে টাইপ করেছি , এইভাবে আমি কেবল লুপের অভ্যন্তরে একটি সুইচ বিবৃতি দিয়ে অ্যারের মাধ্যমে পুনরাবৃত্তি করি।


2

উপরের উত্তরগুলির সাথে সন্তুষ্ট ছিল না, যদিও তারা শুরু ছিল।

এখানে কিছু ভিন্ন উত্স একসাথে
পাইক করার পরে: এই থ্রেডের এসও কিউএনএ
কোড প্রকল্পের পূর্ববর্তী পোস্টার এনুম ফ্ল্যাগগুলি চেক পোস্ট
গ্রেট এনাম <টি> ইউটিলিটি

আমি এটি তৈরি করেছি যাতে আপনি কী ভাবছেন তা আমাকে জানান।
পরামিতি::
bool checkZeroএটি 0একটি পতাকা মান হিসাবে অনুমতি দিতে বলে । ডিফল্টরূপে input = 0খালি ফিরে আসে।
bool checkFlags: এটি Enumডাব্লু / [Flags]বৈশিষ্ট্যটি সজ্জিত কিনা তা পরীক্ষা করতে বলে।
পুনশ্চ. checkCombinators = falseআলগ বের করার জন্য আমার কাছে এখনই সময় নেই যা এটি বিটের সংমিশ্রণে থাকা কোনও এনাম মানগুলিকে উপেক্ষা করতে বাধ্য করবে।

    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;
            }
        }

    }

এটি হেল্পার ক্লাস এনাম <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
কেবল একটি মাথা উপরে আছে যে কোডে একটি বাগ আছে। যদি (চেককোম্বিনেটর) বিবৃতি উভয় শাখায় কোড অভিন্ন হয়। এছাড়াও, সম্ভবত কোনও বাগ নয়, তবে অপ্রত্যাশিত, এটি হল যে আপনার যদি 0 এর জন্য এনাম মান ঘোষিত হয় তবে এটি সর্বদা সংগ্রহে ফিরে আসবে। দেখে মনে হয় যে কেবলমাত্র চেক জিরোটি সত্য হলে এবং অন্য কোনও পতাকা সেট না থাকলেই ফিরে আসা উচিত।
ধোচে

@dhochee। আমি রাজী. বা কোডটি বেশ সুন্দর, তবে যুক্তিগুলি বিভ্রান্তিকর।
এফ্রেক্ট

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;
}

যে কেউ আরও কীভাবে এটির উন্নতি করতে জানতে পারে যাতে এনামের সমস্ত পতাকা একটি দুর্দান্ত স্মার্ট উপায়ে সেট করা থাকে যা সমস্ত অন্তর্নিহিত এনাম প্রকার এবং সমস্ত = ~ 0 এবং সমস্ত = এনামভ্যালু 1 | কে পরিচালনা করতে পারে handle এনামভ্যালু 2 | এনামভ্যালু 3 | ...


1

আপনি এনাম থেকে একজন আইট্রেটর ব্যবহার করতে পারেন। এমএসডিএন কোড থেকে শুরু:

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

Enালাই রোধ করতে নতুন এনুম সীমাবদ্ধতা এবং জেনেরিকগুলি ব্যবহার করে এক্সটেনশন পদ্ধতি:

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

আপনি সরাসরি ইন-তে রূপান্তর করে এটি করতে পারেন তবে আপনি টাইপ চেক করতে পারেন। আমি মনে করি সবচেয়ে ভাল উপায় হ'ল আমার প্রস্তাবের অনুরূপ কিছু ব্যবহার করা। এটি পুরোপুরি সঠিক টাইপ রাখে। কোনও রূপান্তর প্রয়োজন। বক্সিংয়ের কারণে এটি নিখুঁত নয় যা পারফরম্যান্সে কিছুটা হিট যোগ করবে।

নিখুঁত (বক্সিং) নয়, তবে এটি কোনও সতর্কতা ছাড়াই কাজ করে ...

/// <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())
    {
        ...
    }
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.