2010-03-01 14 views
38

Molto spesso nel mio codice ho bisogno di confrontare una variabile a diversi valori:Confrontando una variabile a valori multipli

if (type == BillType.Bill || type == BillType.Payment || type == BillType.Receipt) 
{ 
    // Do stuff 
} 

continuo a pensare che posso fare:

if (type in (BillType.Bill, BillType.Payment, BillType.Receipt)) 
{ 
    // Do stuff 
} 

Ma di questo è naturalmente SQL che consente questo.

C'è un modo più ordinato in C#?

+1

linguaggi come Python e Ruby hanno la "in" operatore, anche. –

+0

@Can Berk Güder: Ho appena cercato questo operatore "in" in Ruby ma non riesco a trovarlo o qualcosa di simile. Qualche idea? –

+1

[1,2,3] .include? (1) –

risposta

58

Si potrebbe fare con con .Contains come questo:

if(new[]{BillType.Receipt,BillType.Bill,BillType.Payment}.Contains(type)){} 

Oppure, creare il proprio metodo di estensione che lo fa con una sintassi più leggibile chiamarla con

public static class MyExtensions 
{ 
    public static bool IsIn<T>(this T @this, params T[] possibles) 
    { 
     return possibles.Contains(@this); 
    } 
} 

Poi:

if(type.IsIn(BillType.Receipt,BillType.Bill,BillType.Payment)){} 
0

Provare a utilizzare C# HashSet per un elenco di valori. Questo può essere particolarmente utile se è necessario confrontare molti valori con un singolo set di valori.

6

tipo Supponendo è un'enumerazione, è possibile utilizzare il FlagsAttribute:

[Flags] 
enum BillType 
{ 
    None = 0, 
    Bill = 2, 
    Payment = 4, 
    Receipt = 8 
} 

if ((type & (BillType.Bill | BillType.Payment | BillType.Receipt)) != 0) 
{ 
    //do stuff 
} 
+0

Sfortunatamente ciò funzionerà solo per enumerazioni che non hanno già definito i loro valori. In questo caso particolare i nostri BillTypes sono già stati definiti come 1-8 ... Purtroppo ... Mi piace l'accuratezza di questo .. –

+5

Consiglierei di riservare FlagsAttribute per le cose che sono, beh, le bandiere. Decorare il BillType con '[Flags]' mi dice che qualsiasi combinazione di BillTypes può essere applicata al valore, che chiaramente non è il caso. –

+0

@Mike in quel caso, perché la stessa cosa dovrebbe essere fatta a loro. In un sistema diverso, un BillType può effettivamente essere una bandiera. Anche se hai ragione, sembra un odore di codice per me. Posso portarlo giù. –

0

Prova a controllare il pattern Strategy Design (anche noto come il modello di politica di Design).

public interface IBillTypePolicy 
{ 
    public BillType { get; } 
    void HandleBillType(); 
} 
public class BillPolicy : IBillTypePolicy 
{ 
    public BillType BillType { get { return BillType.Bill; } } 

    public void HandleBillType() 
    { 
     // your code here... 
    } 
} 

Ecco un great post on how to dynamically resolve the policy da Los Esperti in tecnologia.

+0

Buon modello, problema sbagliato. Questo non risponde alla domanda originale! –

+0

Vedo da dove vieni. È una soluzione di livello più alto al problema e potrebbe valere la pena di contemplare in alcuni casi se sto mettendo molte dichiarazioni if ​​in tutto il luogo. –

9

C'è anche l'istruzione di commutazione

switch(type) { 
    case BillType.Bill: 
    case BillType.Payment: 
    case BillType.Receipt: 
     // Do stuff 
     break; 
} 
3

provare a utilizzare un interruttore

switch (type) 
    { 
     case BillType.Bill: 
     case BillType.Payment: 

     break; 
    }