簡體   English   中英

C#中的枚舉成員聯盟

[英]Union of enum members in C#

讓我們說,我有一個enum BasicType ,其定義如下:

    public enum ObjectType{
        A = 1,
        B = 2,
        C = 3,
    }

BasicType標識對任何Object執行三元分類。 隨后,我意識到對象A和對象B的處理方式與對象C相似,因此我定義了另一個enum ObjectGroupType ,如下所示:

public enum ObjectGroupType
{
   AB = 1,
   C = 2,
}

使用新的枚舉,我可以將幾種已知類型的對象作為一個存儲桶。 因此,當我收到各種類型的對象流時,實際上會確定它們是屬於AB類型還是屬於C類型。 是否有一個優雅的解決方法? 例如,是否可以在ObjectGroupType為A和B分配相同的枚舉值?

編輯1 :我無法在此處找到與問題的相似之處

編輯2 :謝謝Maurice的建設性投入-借鑒您的回答,我提出了這個重新定義的ObjectGroupType

 public enum ObjectGroupType
 {
    AB = ObjectType.A | ObjectType.B
    C = 2,
 }

這有效嗎?

本質上,當我處理AB類型的對象流時,我想確定Type A或Type B對象。 這與分層兩級決策樹非常相似:

    object
    /     \
 AB        C
 /\
A  B

如果我誤讀了您的意圖,我會向您道歉,但這聽起來像是您想允許基於枚舉值在代碼中作用多種不同的枚舉類型。 好消息是,您可以使用按位運算和枚舉來完成此操作。

給定一個如下所示的枚舉:

[Flags]
enum ObjectType
{
    A = 1,
    B = 2,
    C = 4,
    D = 8
}

您可以設置一個比較值,它是多個值的按位或:

var allowedValues = ObjectType.A | ObjectType.C;

之所以可行,是因為枚舉中的值的作用就像是幕后的位字段。

運行代碼時,您對allowedValues變量和測試變量進行按位“與”運算,並查看其是否與測試變量匹配。 如果是這樣,則它是您想要的值之一:

if ((test & allowed) == test) ...

下面是一個使用上面的枚舉的工作示例,向您展示了它的工作原理。

void Main()
{
    var allowed = ObjectType.A | ObjectType.C;

    var values = new int [] { 1, 2, 4, 8 };

    foreach (var i in values)
    {
        var test = (ObjectType)i;

        if ((test & allowed) == test)
        {
            Console.WriteLine("Found a match: {0}", test);
        }
        else
        {
            Console.WriteLine("No match: {0}", test);
        }
    }
}

祝你好運!

您可以使用int而不是enum,使用組合時不重疊的值(即,其二進制表示形式僅具有一位的值),然后對參數的ObjectType執行掩碼操作以確定其是否為AB:

class SomeClass
{
    public static class ObjectType
    {
        public const int A = 1;
        public const int B = 2;
        public const int C = 4;
        public const int D = 8;
    }

    public int MyType;
    public string Title;
    static void Main(string[] args)
    {
        List<SomeClass> list = new List<SomeClass>()
        {
            new SomeClass() {Title ="I am of type A", MyType = ObjectType.A }
            ,new SomeClass() {Title ="I am of type B", MyType = ObjectType.B }
            ,new SomeClass() {Title ="I am of type AB", MyType = ObjectType.A | ObjectType.B }
        };

        list.ForEach(p => { if (p.MyType == (ObjectType.A | ObjectType.B)) Console.WriteLine(p.Title); });
    }
}

這種方法的缺點是失去了對象類型的強大功能,即您可以分配任何值,而不僅僅是在ObjectType中定義的值。

編輯:

我發現莫里斯·里夫斯的答案非常好,我只想帶來一些更多信息:

   [Flags]
    public enum ObjectType
{
    None=0,
    A = 1,
    B = 2,
    C = 4,
    D = 8,
    E = 16,
    AorB=A|B,
    BorCorD=B|C|D,

}

通過使用[Flags]屬性,您可以創建枚舉項目集,這可以幫助您為每個集合建立不同的業務規則。

為了檢查集合中是否存在和項目,您可以執行以下操作:

public static bool IsAorB(this ObjectType item)
{
      return ObjectType.AorB.HasFlag(item);
}

如果您想即時創建新的項目集,則可以執行以下操作:

var newGroup=ObjectType.A | ObjectType.BorCorD;

如果要對某個項目(項目除外)應用某些業務規則,則可以執行以下操作:

var newGroupExceptC =newGroup^=ObjectType.C;

現在,如果您檢查元素C是否存在於集合中,您將得到false:

bool exist=newGroupExceptC.HasFlag(ObjectType.C) // =false

您可以在這里找到更多信息

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM