c# - ষমত - Enums উপর সবচেয়ে সাধারণ সি#বিটwise অপারেশন




শক্তি ও ক্ষমতার মধ্যে পার্থক্য (7)

আমার জীবনের জন্য, আমি মনে রাখতে পারি না কিভাবে বিটফিল্ডটি সেট, মুছে ফেলতে, টগল করতে বা পরীক্ষা করতে হয়। আমি নিশ্চিত নই বা আমি তাদের মিশ্রিত করি কারণ আমার খুব কমই প্রয়োজন। তাই একটি "বিট ঠকাই শীট" আছে চমৎকার হবে।

উদাহরণ স্বরূপ:

flags = flags | FlagsEnum.Bit4;  // Set bit 4.

অথবা

if ((flags & FlagsEnum.Bit4)) == FlagsEnum.Bit4) // Is there a less verbose way?

আপনি অন্য সব সাধারণ অপারেশন উদাহরণস্বরূপ, একটি [পতাকা] enum ব্যবহার করে সি # সিনট্যাক্স উদাহরণ দিতে পারেন?


.NET 4 এ আপনি এখন লিখতে পারেন:

flags.HasFlag(FlagsEnum.Bit4)

.নেট এর অন্তর্নির্মিত ফ্ল্যাগ এনম অপারেশন দুর্ভাগ্যবশত বেশ সীমিত। অধিকাংশ সময় ব্যবহারকারীদের বিটwise অপারেশন লজিক figuring সঙ্গে বাকি আছে।

.NET 4 এ, HasFlag Enum যুক্ত করা হয়েছে যা ব্যবহারকারীর কোডটি সহজ করতে সহায়তা করে তবে দুর্ভাগ্যবশত এটির সাথে অনেক সমস্যা রয়েছে।

  1. HasFlag টাইপ-নিরাপদ নয় কারণ এটি যেকোনো ধরনের এনম মানের যুক্তি গ্রহণ করে, শুধুমাত্র প্রদত্ত enum টাইপ নয়।
  2. HasFlag মূল্যের যুক্তি দ্বারা প্রদত্ত সমস্ত বা কোনও ফ্ল্যাগ থাকে কিনা তা পরীক্ষা করে কিনা তা সন্দেহজনক। এটা উপায় দ্বারা সব।
  3. বরাদ্দকরণ এবং এইভাবে আরও আবর্জনা সংগ্রহের কারণ যা HasFlag বরং ধীর গতির।

বিশেষ করে ফ্ল্যাগ enums জন্য .NET এর সীমিত সমর্থনে আমি ওএসএস লাইব্রেরী Enums.NET যা এই প্রতিটি Enums.NET সম্বোধন করে এবং ফ্ল্যাগ এনমের সাথে ডিল করে তোলে।

নীচের ক্রিয়াকলাপগুলির মধ্যে এটি কেবলমাত্র .NET কাঠামো ব্যবহার করে তাদের সমতুল্য বাস্তবায়নের সাথে সরবরাহ করে।

পতাকা মিশ্রিত করা

.NET flags | otherFlags flags | otherFlags

Enums.NET flags.CombineFlags(otherFlags) কম্বিন flags.CombineFlags(otherFlags)

পতাকা মুছে ফেলুন

.NET flags & ~otherFlags

Enums.NET পতাকা। flags.RemoveFlags(otherFlags)

সাধারণ পতাকা

.NET flags & otherFlags

Enums.NET flags.CommonFlags(otherFlags) কমন flags.CommonFlags(otherFlags)

পতাকা টগল করুন

.NET flags ^ otherFlags

Enums.NET পতাকা। flags.ToggleFlags(otherFlags)

সব পতাকা আছে

.NET (flags & otherFlags) == otherFlags বা (flags & otherFlags) == otherFlags flags.HasFlag(otherFlags)

Enums.NET পতাকা। flags.HasAllFlags(otherFlags)

কোন পতাকা আছে

.NET (flags & otherFlags) != 0

Enums.NET পতাকা। flags.HasAnyFlags(otherFlags)

পতাকা পান

.NET

Enumerable.Range(0, 64)
  .Where(bit => ((flags.GetTypeCode() == TypeCode.UInt64 ? (long)(ulong)flags : Convert.ToInt64(flags)) & (1L << bit)) != 0)
  .Select(bit => Enum.ToObject(flags.GetType(), 1L << bit))`

Enums.NET পতাকা। flags.GetFlags()

আমি এই উন্নতিগুলি .NET কোর এবং হয়ত শেষ পর্যন্ত সম্পূর্ণ .NET Framework এ অন্তর্ভুক্ত করার চেষ্টা করছি। আপনি here আমার প্রস্তাব চেক আউট করতে পারেন।


C ++ সিনট্যাক্স, বিট 0 অনুমান করা LSB হয়, অনুমান করা পতাকাগুলি স্বাক্ষরহীন নয়:

সেট করুন কিনা তা পরীক্ষা করুন:

flags & (1UL << (bit to test# - 1))

সেট না থাকলে পরীক্ষা করুন:

invert test !(flag & (...))

সেট করুন:

flag |= (1UL << (bit to set# - 1))

পরিষ্কার:

flag &= ~(1UL << (bit to clear# - 1))

টগল করুন:

flag ^= (1UL << (bit to set# - 1))

Idiom বিট সেট করতে bitwise বা-সমান অপারেটর ব্যবহার করা হয়:

flags |= 0x04;

একটি বিট পরিষ্কার করার জন্য, idiom বিটwise এবং অস্বীকার সঙ্গে ব্যবহার করা হয়:

flags &= ~0x04;

কখনও কখনও আপনার একটি বিট যা আপনার বিটকে চিহ্নিত করে এবং তারপরে idiom বাম-শিফ্টের সাহায্যে এইগুলি ব্যবহার করতে হয়:

flags |= 1 << offset;
flags &= ~(1 << offset);

এটি ডেলফিতে সূচকের হিসাবে সেটগুলি ব্যবহার করে অনুপ্রাণিত হয়েছিল, যখন সেটি আবার:

/// Example of using a Boolean indexed property
/// to manipulate a [Flags] enum:

public class BindingFlagsIndexer
{
  BindingFlags flags = BindingFlags.Default;

  public BindingFlagsIndexer()
  {
  }

  public BindingFlagsIndexer( BindingFlags value )
  {
     this.flags = value;
  }

  public bool this[BindingFlags index]
  {
    get
    {
      return (this.flags & index) == index;
    }
    set( bool value )
    {
      if( value )
        this.flags |= index;
      else
        this.flags &= ~index;
    }
  }

  public BindingFlags Value 
  {
    get
    { 
      return flags;
    } 
    set( BindingFlags value ) 
    {
      this.flags = value;
    }
  }

  public static implicit operator BindingFlags( BindingFlagsIndexer src )
  {
     return src != null ? src.Value : BindingFlags.Default;
  }

  public static implicit operator BindingFlagsIndexer( BindingFlags src )
  {
     return new BindingFlagsIndexer( src );
  }

}

public static class Class1
{
  public static void Example()
  {
    BindingFlagsIndexer myFlags = new BindingFlagsIndexer();

    // Sets the flag(s) passed as the indexer:

    myFlags[BindingFlags.ExactBinding] = true;

    // Indexer can specify multiple flags at once:

    myFlags[BindingFlags.Instance | BindingFlags.Static] = true;

    // Get boolean indicating if specified flag(s) are set:

    bool flatten = myFlags[BindingFlags.FlattenHierarchy];

    // use | to test if multiple flags are set:

    bool isProtected = ! myFlags[BindingFlags.Public | BindingFlags.NonPublic];

  }
}

সি ++ অপারেশনগুলি: & | ^ ~ ((এবং, বা, xor এবং বিটwise ক্রিয়াকলাপ নয়)। এছাড়াও আগ্রহের >> এবং <<, যা bitshift অপারেশন।

সুতরাং, একটি পতাকাতে কিছুটা সেট করার জন্য পরীক্ষা করার জন্য, আপনি ব্যবহার করবেন: যদি (ফ্ল্যাগ এবং 8) // পরীক্ষা বিট 4 সেট করা হয়েছে


আমি এই এক্সটেনশানগুলির উপর আরো কিছু কাজ করেছি - আপনি এখানে কোডটি খুঁজে পেতে পারেন

আমি কিছু এক্সটেনশন পদ্ধতি লিখেছি যা সিস্টেম প্রসারিত করে। আমি যে প্রায়ই ব্যবহার করি ... আমি বলছি না যে তারা বুলেটপ্রুফ, কিন্তু তারা সাহায্য করেছে ... মন্তব্যগুলি সরানো হয়েছে ...

namespace Enum.Extensions {

    public static class EnumerationExtensions {

        public static bool Has<T>(this System.Enum type, T value) {
            try {
                return (((int)(object)type & (int)(object)value) == (int)(object)value);
            } 
            catch {
                return false;
            }
        }

        public static bool Is<T>(this System.Enum type, T value) {
            try {
                return (int)(object)type == (int)(object)value;
            }
            catch {
                return false;
            }    
        }


        public static T Add<T>(this System.Enum type, T value) {
            try {
                return (T)(object)(((int)(object)type | (int)(object)value));
            }
            catch(Exception ex) {
                throw new ArgumentException(
                    string.Format(
                        "Could not append value from enumerated type '{0}'.",
                        typeof(T).Name
                        ), ex);
            }    
        }


        public static T Remove<T>(this System.Enum type, T value) {
            try {
                return (T)(object)(((int)(object)type & ~(int)(object)value));
            }
            catch (Exception ex) {
                throw new ArgumentException(
                    string.Format(
                        "Could not remove value from enumerated type '{0}'.",
                        typeof(T).Name
                        ), ex);
            }  
        }

    }
}

তারপর তারা নিম্নলিখিত মত ব্যবহার করা হয়

SomeType value = SomeType.Grapes;
bool isGrapes = value.Is(SomeType.Grapes); //true
bool hasGrapes = value.Has(SomeType.Grapes); //true

value = value.Add(SomeType.Oranges);
value = value.Add(SomeType.Apples);
value = value.Remove(SomeType.Grapes);

bool hasOranges = value.Has(SomeType.Oranges); //true
bool isApples = value.Is(SomeType.Apples); //false
bool hasGrapes = value.Has(SomeType.Grapes); //false




flags