2016-07-24 123 views
0

讓我們說,我有一個enum BasicType,其定義如下:枚舉的聯盟成員在C#

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

的BasicType標識執行任何Object的三元分類。隨後,我意識到對象需要以類似的方式進行處理相比,Ç,所以限定的另一enum ObjectGroupType如下:

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

隨着新的枚舉,我我能夠將多種已知類型的對象作爲一個對象。因此,當我收到各種類型的對象流時,我實際上會識別它們是屬於AB還是C類型。有沒有一個優雅的解決方法呢?舉例來說,我將能夠在ObjectGroupType指定爲A和B相同的枚舉值:?

編輯1:我無法找到相似的問題here

編輯2 :感謝Maurice對你的建設性意見 - 從你的回答中得到線索,我想出了這個重新定義的ObjectGroupType

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

這是有效的嗎?

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

object 
    / \ 
AB  C 
/\ 
A B 
+0

你有,你想如何使用這個'enum'工作的例子嗎? – Jace

+3

你爲什麼要標記java? – ganesshkumar

+1

這看起來像是一個副本https://stackoverflow.com/questions/8043027/non-unique-enum-values – Olathe

回答

0

您可以使用一個int,而不是一個枚舉,結合時不重疊的使用價值即(即值,其二進制表示只有一位上),然後在參數的對象類型進行屏蔽操作,以確定它是否是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中定義。

4

如果我誤讀了你的意圖,我很抱歉,但它幾乎聽起來像你希望允許多種不同的枚舉類型在你的代碼中基於枚舉值起作用。好處是你可以通過按位運算和枚舉來完成。

由於看起來像這樣的枚舉:

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

你可以設置一個比較值是按位或幾個值:

var allowedValues = ObjectType.A | ObjectType.C; 

這工作,因爲在枚舉行爲的值像封面下的位域。

當你運行你的代碼時,你對allowedValues變量和測試變量進行按位AND操作,看它是否與你的測試變量相匹配。如果是的話,那麼它就是你想要的值之一:

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

祝你好運!

+0

這是一個非常有趣的解決方案。你將如何去提取每個對象類型的名稱(在本例中爲A和C)?我相信'Enum.GetName(允許)'不起作用。 –

+1

如果你運行這個例子,你會發現它實際上打印出了這個枚舉的名字,如果你寫入控制檯允許的話,它應該會顯示你加入的值。 –

0

編輯:

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

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

現在,如果你檢查的Elemen噸,碳集合中的存在,您會得到錯誤:

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

更多信息,你可以找到here

+0

我已經獨立地提出了相同的方法,但是'bool'返回類型不可擴展 - 如果有新的第三類事件{D,E}會怎麼樣。所以,我的目標是對類型進行分組。 –

+1

我的例子是檢查是否是groupAorB的擴展方法,但是你可以根據需要做很多擴展。最後,你需要檢查組類型,不是嗎? –