2010-04-02 10 views
5

In Anbetracht der folgenden Flags,C# Enum Flags Vergleich

[Flags] 
    public enum Operations 
    { 
     add = 1, 
     subtract = 2, 
     multiply = 4, 
     divide = 8, 
     eval = 16, 
    } 

Wie könnte ich eine IF-Bedingung implementieren jede Operation durchzuführen? Bei meinem Versuch gilt die erste Bedingung für hinzufügen, Eval, die korrekt ist. Die erste Bedingung gilt jedoch auch für subtrahieren, eval, was falsch ist.

Ich kann nicht sehen, was das Problem ist.

+1

Ist es nur ich, der denkt, dass [Flags] für die angezeigte Operation nicht korrekt ist? Ich habe Mühe, an eine reale Weltprobe zu denken, wo ich Flags auf mathematische Operationen gezeigt hätte ... – Sunny

+0

Ich stimme Sunny zu. Die Flags sollten Zustände in einem Taschenrechner darstellen. Ich bin mir nicht sicher, warum ich es so gemacht habe. Im Nachhinein würde ich es heute nicht mehr so ​​machen. –

+0

Mögliches Duplikat von [Wie vergleicht man Flags in C#?] (Http://stackoverflow.com/questions/40211/how-to-compare-flags-in-c) –

Antwort

23

Ändern Sie Ihre innere & zu |:

if(((operation & Operations.add)==Operations.add) && 
    ((operation & Operations.eval)==Operations.eval)) 

, die besser lesbar sein könnte:

if ((operation & (Operations.add | Operations.eval)) == (Operations.add | Operations.eval)) 

Dies äquivalent ist. Sie könnten auch eine Erweiterung wie dies in Erwägung ziehen:

public static bool HasFlag(this Operations op, Operations checkflag) 
{ 
    return (op & checkflag)==checkflag; 
} 

dann können Sie dies tun:

if(operation.HasFlag(Operations.add) && Operations.HasFlag(Operations.eval)) 

die noch lesbar sein könnte. Schließlich könnten Sie diese Erweiterung für noch mehr Spaß erstellen:

public static bool HasAllFlags(this Operations op, params Operations[] checkflags) 
{ 
    foreach(Operations checkflag in checkflags) 
    { 
     if((op & checkflag)!=checkflag) 
      return false; 
    } 
    return true; 
} 

Dann könnte Ihr Ausdruck verwandeln sich in:

if(operation.HasAllFlags(Operations.add, Operations.eval)) 
+0

+1 Große Antwort! –

+0

Der erste Vorschlag ist falsch; Die endgültige Lösung ist korrekt;) –

+0

Wenn Sie das nicht finden, brauchen Sie "HasAllFlags", weil Sie 'HasFlag' so verwenden können: 'if (operation.HasFlag (Operations.add | Operations.eval))'. – weston

1

Der Grund Ihrer Operation fehlschlägt, weil Sie die falsche Ausdruck haben. (Operations.add & Operations.eval) ist immer Null. Die linke und die rechte Seite Ihres ersten Vergleichs sind beide immer Null. Versuchen Sie stattdessen - ich vermute, es ist das, was Sie waren nach:

public double Evaluate(double input) 
{ 
    if ((operation & (Operations.add | Operations.eval)) == (Operations.add | Operations.eval)) 
     currentResult += input; 
    else if ((operation & (Operations.subtract | Operations.eval)) == (Operations.subtract | Operations.eval)) 
     currentResult -= input; 
    else 
     currentResult = input; 

    operation = null; 

    return currentResult; 
} 
1

Try this:

public double Evaluate(double input) 
{ 
    if ((operation & (Operations.add | Operations.eval)) == (Operations.add | Operations.eval)) 
     currentResult += input; 
    else if ((operation & (Operations.subtract | Operations.eval)) == (Operations.subtract | Operations.eval)) 
     currentResult -= input; 
    else 
     currentResult = input; 

    operation = null; 

    return currentResult; 
} 
11

Wow, ich kann nicht alle der falschen Antworten glauben ..

Es ist wichtig, Verstehen Sie bitweise Mathematik, wenn Sie mit Flags arbeiten. In Ihrem Fall haben Sie die folgenden (für die erste Bedingung):

1 in binary is 00001 
16 in binary is 10000 

    00001 
& 10000 
-------- 
    00000 

Also, sagen wir subtrahieren (2) als die operation

2 in binary is  00010 
previous result is 00000 

    00010 
& 00000 
-------- 
    00000 

Da das vorherige Ergebnis ist 00000 alles und‘haben d mit wird es Null sein. Ihr Zustand wird also immer true seit 0 == 0.

Wenn wir nur Schalter sich dieser auf, dann haben wir folgendes:

1 in binary is 00001 
16 in binary is 10000 

    00001 
| 10000 
-------- 
    10001 (17) 

Nun sagen wir Add (1) als So operation

1 in binary is  00001 
previous result is 10001 (17) 

    00001 
& 10001 
-------- 
    00001 

haben, 1 & 17 => 1 und damit Ihre endgültige Bedingung ist (1 & (1 | 16)) == (1 | 16) =>1 & 17 == 17 =>1 == 17 =>false (immer noch falsch!)

Also, was Sie eigentlich wollen, ist:

((operation | Operations.add | Operations.eval) & (Operations.add | Operations.eval)) == (Operations.add | Operations.eval) 

Dies wird ((1 | 1 | 16) & (1 | 16)) == (1 | 16) =>(17 & 17) == 17 =>17 == 17 == true

Dies ist natürlich nicht lesbar, so sollten Sie sich entscheiden, diese zum Extrahieren in eine Methode (wie vorgeschlagen). Aber es ist immer noch wichtig, zu verstehen, warum Ihr Zustand falsch ist.