কীভাবে একটি OR'd এনামের জন্য কোনও আইটেম সরানো যায়?


180

আমার মতো এনাম রয়েছে:

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

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

আমি পরিবর্তনশীল রঙগুলি থেকে নীল রঙটি কীভাবে সরিয়ে ফেলতে পারি?


2
ছোট দ্রষ্টব্য: সি # এর কিছুটা দিকের এনামের উপরে [পতাকাগুলি] বৈশিষ্ট্যটি পাওয়া উচিত।
নাইয়ারগডস

@ নাইয়ারগডস, আপনি ব্যাখ্যা করতে পারেন কেন এটির বৈশিষ্ট্যটি পাওয়া উচিত?
ইথেন

এটি ডিবাগ করার সময় আরও ভাল ইন্টেলিজেন্স সহায়তা দেয় কারণ এটি অজানা এনাম মানগুলিকে বিদ্যমান মানগুলির সংমিশ্রণ হিসাবে স্বীকৃতি দেয়।
নাইয়ারগডস

1
এটি আরও অর্থবহ .ToString()মান দেয়। যেমন RED, BLUE, YELLOWতুলনায় 22
সিনজাই

উত্তর:


328

আপনার &এটি ~'ব্লু' এর (পরিপূরক) সাথে দরকার ।

পরিপূরক অপারেটরটি প্রদত্ত ডেটা ধরণের জন্য প্রয়োজনীয়ভাবে বিপরীত বা 'ফ্লিপ' করে দেয়। যেমন, আপনি যদি কিছু মান সহ ANDঅপারেটর ( &) ব্যবহার করেন (আসুন সেই মানটিকে 'এক্স' বলুন) এবং এক বা একাধিক সেট বিটের পরিপূরক (আসুন সেই বিটগুলি 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 সমস্ত বিটগুলি উল্টে / উল্টে দেয় X

1
সুতরাং আমি যদি আরও বেশি সরিয়ে নিতে চাই তবে আমি কেবল এটিই করতাম: & = lah ব্লাহ.ব্লু & ~ ব্লাহ.গ্রাইন?
খালি

11
আরও ভালcolors &= ~( Blah.BLUE | Blah.GREEN );
সমান

2
কিভাবে অস্বাভাবিক, আমি ঠিক কীভাবে এটি আরও 5 দিন আগে আবার করব তা ভাবছিলাম :) এই প্রশ্নটি আমার ইনবক্সে আপডেট হয়েছে এবং ভয়েলা!
খালি

দুর্দান্ত উত্তর। আমার মনে হয় তবে আপনার কোডের নমুনায় "& =" নয় "= &" বলতে চাইছেন;)
ডেভ জেলিসন

47

অন্যান্য উত্তরগুলি সঠিক, তবে উপরের থেকে নীল মুছে ফেলার জন্য আপনি লিখবেন:

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 হিসাবে একটি পতাকা হিসাবে এড়ানো to আমি সাধারণত মত পতাকা enums সেট আপ এই । আমি দেখতে পাচ্ছি না যে 0 Red, Blue, Greenটির মান সহ একটি রাষ্ট্র উল্লেখ করে আপনি কীভাবে উপকৃত হন? সর্বোপরি পুরো বিষয়টি হ'ল আপনি অন্তর্নিহিত মানগুলির চেয়ে প্রোগ্রামার-বান্ধব নামগুলি ( ) দিয়ে নিজেকে চিন্তিত করতে পারেন , হ্যাঁ?
সিনজাই

রয়ে একটি noneবা unknownবা unsetমান == 0 এন্ট্রি অনেক ক্ষেত্রে একটি ভাল জিনিস যেমন আপনি সবসময় অনুমান করতে পারে না যে একটি নির্দিষ্ট মান ডিফল্ট সেট, যেমন হলে আপনি শুধুমাত্র আছে লাল, নীল ও সবুজ আপনি লাল হিসাবে আছে যাচ্ছে ডিফল্ট মান (যেমন
এনাম তৈরি করার সময় এনামের

আপনার কি কেবল আনসেট = 1 থাকতে পারে না এবং 1, 2, 4, 8আপনার মান হিসাবে ব্যবহার করতে পারেন ? আপনার যদি কোনও ডিফল্ট মান প্রয়োজন হয় তবে এটিই কি ডিফল্ট কনস্ট্রাক্টরগুলির জন্য, তাই না? আমি পঠনযোগ্যতার স্বার্থে জিনিসগুলি যথাসম্ভব স্পষ্ট করে রাখতে চাই এবং কোনও বিকাশকারী দ্বারা সম্ভবত তথ্য হিসাবে পরিচিত হওয়া সত্ত্বেও কোনও মূল্য দেওয়া না হলে default(int)( 0) এর জন্য ডিফল্ট হওয়ার জন্য একটি এনামের উপর নির্ভর করা যাই হোক না কেন আমার স্বাদগুলির জন্য খুব স্পর্শকাতর। সম্পাদনা: ওহ অপেক্ষা করুন, আনসেট = 0 তৈরি করা কি কোনও কিছু হতে বাধা দেবে Unset | Blue?
সিনজাই

আপনি আপনার সম্পাদনা সিনজাইয়ের সঠিক পথে রয়েছেন, আনসেট মান == 0 রেখে আসলে কয়েকটি সমস্যা সমাধান করে। একটি যা আপনি উল্লেখ করেছেন তা হ'ল এবং অন্যটি হ'ল যদি আপনি সমস্ত এনাম মানগুলি সেট না করে থাকেন তবে "আনসেট" এর জন্য যদি এটি শূন্যতে সেট করা থাকে তবে আপনার বিশেষ কেসের প্রয়োজন হবে না। (যেমন আপনি যদি Red & ~Redশূন্যের সাথে শেষ করেন তবে আপনাকে অবশ্যই এই ক্ষেত্রে পরীক্ষা করার জন্য কোড থাকতে হবে এবং স্পষ্টভাবে Unsetমান নির্ধারণ করতে হবে )
সোভেরির সিগমুন্দরসন

Gotcha। আপনি প্রায়শই নিজেকে আনসেট করা পতাকা ব্যবহার করছেন বলে মনে করেন?
সিনজাই

2

Xor (^) সম্পর্কে কী?

আপনি যে এফএলএজি অপসারণের চেষ্টা করছেন তা সেখানে রয়েছে, এটি কার্যকর হবে .. যদি তা না হয় তবে আপনাকে একটি & ব্যবহার করতে হবে।

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

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.