2013-04-09 4 views
8

Ich habe 3 Boolesche Werte in meinem Code (C#) und einer int32-Eigenschaft, die davon abhängt, welche booleschen Werte true und false sind. Was ist der beste Weg, um dies auf eine andere Weise zu erreichen, als wenn Aussagen wie:Beste Möglichkeit, mehrere boolesche Bedingungen in C# zu überprüfen if-Anweisungen

if(a && b && !c) 
    d = 1; 
if(a && !b && !c) 
    d = 2; 
//etc.. ect... 

EDIT: Die 3 booleans muss jede Kombination haben möglich, den int32 Wert einzustellen.

EDIT 2: Der Wert von "d" kann für zwei verschiedene boolesche Vergleiche gleich sein.

+4

Wenn es immer genau drei booleans, könnten Sie einen Tisch im voraus bauen und dann nur das spezifische Element, um die booleans als Taste nachschlagen. – cdhowie

+0

Ein Array von Ganzzahlen und dann die 3 Booleschen, die als einzelne Bits verwendet werden, um den richtigen Eintrag zu indizieren. Art der kompakten Darstellung eines Binärbaums. –

+0

Zum BEARBEITEN: meine Antwort zeigt, wie man einen 'Kombinationsindex' aus den konstituierenden Bedingungen berechnet – sehe

Antwort

25

Es ist besser, die Absicht des Betriebs zu erfassen statt überprüfen explizit die Booleschen Werte .

Zum Beispiel:

public void Check() 
{ 
    if (HasOrdered()) 
    { 
     // do logic 
    } 
} 

private bool HasOrdered() 
{ 
    return a && !b && !c; 
} 

private bool HasBooked() 
{ 
    return a && b && !c; 
} 
+0

+1 Trifft voll und ganz zu, je nachdem, welcher der kompakteste Weg ist, um die Bedingungen zu überprüfen, sollten wir die Domäne nicht vergessen. –

+0

+1 hier auch. Ich habe immer noch meine Antwort geschrieben, weil es aus dem OP nicht klar ist, dass sein Szenario sich für einen "beschreibenden Domainnamen" eignet. – sehe

+1

Wenn er einen knappen Code machen will, der diesen Zweck besiegt – SamFisher83

2

Sie konnten die Lookup-Tabelle Hinweis von @Adriano gegeben tun, vorausgesetzt, Sie haben lookup_table mit Werten für den Index gefüllt [0..8):

var index = new [] { a,b,c }.Aggregate(0, (a,i) => return 2*a + (i?1:0)); 

int d = lookup_table[index]; 

bearbeiten Die EDIT der Frage machte das irrelevant: Was bedeutet das?

Wenn es die Anzahl der falschen Werte (möglich aus dem Beispielcode) ist, machen es

int d = new [] { a,b,c }.Count(b => !b); 

2

Ich denke, was Sie jetzt Ihre tun, ist völlig in Ordnung und alle anderen Lösungen wäre bis auf Präferenz.

Meine Präferenz, wo es gilt, wäre die Kontrollen zu trennen, wenn möglich.

if (!a) 
    return; 
if (!b) 
    return; 
if (!c) 
    return; 

wäre dies im Fall nützlich, dass Sie bestimmt prereqs vor einer Funktion Ausgabe, wie wenn der Benutzer angemeldet hat, wenn ein Parameter vorhanden ist und im richtigen Kontext überprüfen müssen, zusammen mit anderen Gegenständen.

Wie ich sagte, dies könnte nicht gelten, aber ich wollte nur meine Meinung

0

Ich sehe nichts äußern falsch mit, wie Sie es tun, aber wenn der Ausgang das gleiche gilt für mehrere Bedingungen Sie können in der Lage sein, zu vereinfachen, indem Sie eine Wahrheitstabelle erstellen und die Bedingungen vereinfachen.

Zum Beispiel, wenn d sollte 0jederzeita falsch ist, Sie vereinfachen könnten:

if(a) 
    if(b && !c) 
     d = 1; 
    if(!b && !c) 
     d = 2; 
    ... 
else 
    d = 0; 

Oder wenn es ein mathematisches Muster (zB a, b und c repräsentieren die drei Ziffern eine binäre Zahl), dann könnten Sie Bitarithmetik tun.

Wenn Sie jedoch haben 8 verschiedene Ergebnisse (einer für jede Kombination von a, b und c) dann Ihre Methode ist in Ordnung.

9

Sie könnten eine Karnaugh-Map verwenden, um Ihre Gleichungen zu reduzieren und weniger Wenns zu haben.

https://en.wikipedia.org/wiki/Karnaugh_map

+0

Dies ist die beste Lösung Ich bin schockiert, so viele Leute haben dies nicht vorgeschlagen. –

+1

@Ramhound viele Leute werden einfach lieber die Logik _als es entsteht _ schreiben, nicht, wie es effektiv _ schließlich kombiniert; K-Maps konzentrieren sich auf das Ergebnis _only_ und eliminieren rücksichtslos alle Informationen aus der Eingabe, die das Ergebnis nicht mehr beeinflussen. Diese Information ist daher nicht mehr aus der Quelle ersichtlich. Hene, die Quelle ist nicht mehr eine Reflektion von funktionalen Anforderungen. Es ist _harder_ um Recht zu beweisen, nicht _easier_. Noch schwieriger zu pflegen (zu modifizieren). Stattdessen sollten Sie den Compiler normalerweise um die Optimierung kümmern (was auch nach dem Inlining passieren kann). – sehe

Verwandte Themen