كيفية تخزين العديد من الولايات في متغير واحد؟

StackOverflow https://stackoverflow.com/questions/1855211

  •  13-09-2019
  •  | 
  •  

سؤال

كائن بلدي Item لديه العديد من الدول الثنائية التي يمكن دمجها

bool CanBeSold;
bool CanBeBought;
bool CanBeExchanged;

أحتاج إلى تخزين الجمع بين القيم الحالية في متغير واحد. والسبب هو أنني بحاجة إلى تخزين هذه القيمة في DB. في C ++، أود إنشاء قناع بت حيث تحتل دولة واحدة بعض الشيء. هل هي ممارسة جيدة في .NET؟

هل كانت مفيدة؟

المحلول

يمكنك استخدام التعداد مع Flags ينسب:

[Flags]
enum MyStates {
  CanBeSold = 1,
  CanBeBought = 2,
  CanBeExchanged = 4
}

نظرا لأن التعدادات هي أنواع بيانات متكاملة أسفلها، يمكنك دمجها في الأزياء المعتادة:

state = MyStates.CanBeSold | MyStates.CanBeExchanged

لاحظ أن هذا يعمل فقط عندما تكون قيم المعندوق صلاحيات اثنين (كما دوغ فيرجسون أشار في تعليق)، لذلك يمكن دمجها بسهولة ولا تتداخل عند تعيين العديد منها.

يمكنك أيضا تحديد القيم كملقيات من القيم الأخرى المتعددة:

 CanBeSoldOrBought = CanBeSold | CanBeBought

أو

 CanBeSoldOrBought = 3

الذي يعمل أيضا كما هو متوقع. يمكن رؤية ذلك على سبيل المثال أذونات الملف حيث عادة ما يكون ReadWrite مزيج من بت القراءة والكتابة.

ونعم، هذه ممارسة شائعة. يستخدم الإطار نفسه أيضا في العديد من الأماكن.

الطريقة المعتادة ل التحقق من للحصول على عدد معين يجري تعيين ثم

if ((state & MyStates.CanBeSold) != 0) { ... }

نصائح أخرى

قم بإنشاء عطاء حيث تتوافق القيم مع البتات في عدد صحيح. قم بإضافة سمة الأعلام مكنتكم للقيام ببعض عمليات بعض الشيء على قيم Enum.

[Flags]
public enum CanBe {
  Sold = 1,
  Bought = 2,
  Exchanged = 4
}

الآن يمكنك فقط استخدام أو المشغل بين القيم:

CanBe can = CabBe.Sold | CanBe.Exchanged.

يمكنك إضافة حالة مع | = المشغل:

can |= CanBe.Sold;

أو عدة دول:

can |= CanBe.Sold | CanBe.Bought;

يمكنك الاحتفاظ بالحالة مع A & = المشغل:

can &= CanBe.Sold;

أو عدة دول:

can &= CanBe.Sold | CanBe.Bought;

يمكنك إزالة الحالات باستخدام المشغل ~ لإنشاء مكمل إلى قيمة:

can &= ~CabBe.Bough;

أو حالات سيفيل:

can &= ~(CabBe.Bough | CanBe.Exchanged);

يمكنك التحقق من حالة باستخدام ومشغل:

if ((can & CanBe.Sold) != 0) ...

أو العديد من الدول في وقت واحد:

if ((can & (CanBe.Sold | CanBe.Bought)) != 0) ...

أو التحقق من أن العديد من الولايات يتم تعيين جميع الولايات:

if ((can & (CanBe.Sold | CanBe.Bought)) == (CanBe.Sold | CanBe.Bought)) ...

يمكنك القيام بذلك مع أقنعة البت في .NET أيضا.

داخل برنامجك، يمكنك تحديد حالاتك كقيم

public enum ItemState { CanBeSold = 1; CanBeBought = 2; CanBeExchanged = 4 }

ثم داخل كائنك، يمكنك القيام به

if (item.State ^ ItemState.CanBeSold) ....

يمكنك استخدام الأعلام Enum مع كل بت المحدد

[Flags]
enum MyStates {
    CanBeSold = 0x1,
    CanBeBought = 0x2,
    CanBeExchanged = 0x4,
}

MyStates m_Flags;

// to set a flag:
m_Flags |= MyStates.CanBeSold;

// to unset a flag:
m_Flags &= ~MyStates.CanBeSold;
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top