2016-07-24 9 views
0

Lassen Sie uns sagen, ich habe eine enum BasicType, die wie folgt definiert ist:Union von Enum-Mitglieder in C#

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

Die Basictype identifiziert führt eine ternäre Einstufung eines Object. Anschließend stellte ich fest, dass die Objekte A und B Bedarf in ähnlicher Weise behandelt werden, im Vergleich zu C, so definiert ich eine andere enum ObjectGroupType wie folgt:

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

Mit dem neuen Enum, ich Ich bin in der Lage, Objekte mehrerer bekannter Typen als einen zu gruppieren. Wenn ich also einen Strom von Objekten in verschiedenen Typen erhalte, identifiziere ich tatsächlich, ob sie zum AB- oder C-Typ gehören. Gibt es dafür einen eleganten Workaround? Zum Beispiel werde ich die gleichen Enum-Werte für A und B in den ObjectGroupType übertragen kann:

Edit 1: Ich bin nicht in der Lage, die Ähnlichkeit mit der Frage here

Edit 2 zu finden : Danke Maurice für deine konstruktiven Inputs - indem du Hinweise aus deiner Antwort nimmst, kam ich auf diese neu definierte ObjectGroupType.

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

Ist das gültig?

Im Wesentlichen, wenn ich einen Strom von Objekten des Typs AB verarbeite, möchte ich Typ A oder Typ B Objekte feststellen. Das ist ganz ähnlich wie ein hierarchischer Zwei-Ebenen-Entscheidungsbaum:

object 
    / \ 
AB  C 
/\ 
A B 
+0

Haben Sie ein funktionierendes Beispiel dafür, wie Sie möchten, dass diese 'enum' benutzen? – Jace

+3

Warum hast du Java getaggt? – ganesshkumar

+1

Dies scheint wie ein Duplikat von https://stackoverflow.com/questions/8043027/non-unique-enum-values ​​ – Olathe

Antwort

0

Sie könnten statt ein ENUM einen int verwenden, Gebrauchswerte, die sich nicht überlappen, wenn sie kombiniert (dh Werte, deren binären Darstellung haben nur ein Bit auf) und dann eine Maskenoperation auf dem Objekttyp eines Parameters durchführen, um festzustellen, ob es AB ist:

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

der Nachteil dieses Ansatzes starke Typisierung von Objekttyp verliert, dh Sie können einen beliebigen Wert zuweisen können nicht nur diejenigen, Sie definieren im ObjectType.

4

Ich entschuldige mich im Voraus, wenn ich Ihre Absicht falsch gelesen habe, aber es klingt fast so, als ob Sie in Ihrem Code mehrere verschiedene Aufzählungstypen basierend auf dem Aufzählungswert verwenden möchten. Das Gute daran ist, dass Sie dies bereits mit bitweisen Operationen und Enums tun können.

ein Aufzählungstyp, der wie folgt aussieht:

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

können Sie einen Vergleichswert festgelegt, dass die bitweise ODER mehrerer Werte ist:

var allowedValues = ObjectType.A | ObjectType.C; 

Diese im Enum Akt, weil die Werte funktioniert wie Bitfelder unter der Decke.

Wenn Sie Ihren Code ausführen, führen Sie ein bitweises AND für die Variablen "allowedValues" und die Testvariable aus und prüfen, ob sie mit Ihrer Testvariablen übereinstimmt.Ist dies der Fall, dann ist es einer der Werte, die Sie wünschen:

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

Im Folgenden ein funktionierendes Beispiel ist mit dem Enum oben, dass Sie zeigt, wie es funktioniert.

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

Viel Glück!

+0

Dies ist eine sehr interessante Lösung. Wie würden Sie die Namen der einzelnen Objekttypen (in diesem Fall A und C) extrahieren? Ich glaube, das 'Enum.GetName (erlaubt)' wird nicht funktionieren. –

+1

Wenn Sie das Beispiel ausführen, sehen Sie, dass es tatsächlich den Namen für die Enumeration ausgibt, und wenn Sie in die Konsole erlaubt schreiben, sollte es Ihnen auch die verbundenen Werte anzeigen. –

0

Edit:

ich die Antwort von Maurice Reeves sehr gut gefunden, ich will nur ein paar mehr Infos bringen:

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

} 

von [Flags] Attribut verwenden, können Sie Sätze von ENUM-Elemente erstellen, die kann Ihnen helfen, verschiedene Geschäftsregeln für jeden Satz festzulegen.

Um wenn und Artikel zu überprüfen, gibt es in einem Satz, den Sie wie folgt tun:

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

, wenn Sie auf der fliegen neuen Satz von Artikel creat möchten, können Sie tun:

var newGroup=ObjectType.A | ObjectType.BorCorD; 

, wenn Sie einige Geschäftsregel auf einen Satz, mit Ausnahme eines Artikels anwenden möchten, können Sie tun:

var newGroupExceptC =newGroup^=ObjectType.C; 

Nun, wenn Sie, wenn Verput überprüfen t C existieren in dem Satz werden Sie falsch erhalten:

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

weitere Informationen können Sie finden here

+0

Ich hatte unabhängig voneinander den gleichen Ansatz, aber der 'bool' Rückgabetyp ist nicht skalierbar - was wäre, wenn es einen neuen dritten Typ von Ereignissen {D, E} gäbe. Also, mein Ziel ist es, auf Typen zu gruppieren. –

+1

Mein Beispiel war eine Erweiterungsmethode, um zu überprüfen, ob GroupAorB ist, aber Sie können so viele Erweiterungen machen, wie Sie wollen/brauchen. Am Ende müssen Sie nach Gruppentyp suchen, nicht wahr? –