tags:

views:

221

answers:

7

Quite often in my code I need to compare a variable to several values :

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

I keep on thinking I can do :

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

But of course thats SQL that allows this.

Is there a tidier way in C#?

A: 

Try using C# HashSet for list of values. This can be especially useful if you need to compare many values to single set of values.

Sergiy Byelozyorov
+3  A: 

Assuming type is an enumeration, you could use the FlagsAttribute:

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

if ((type & (BillType.Bill | BillType.Payment | BillType.Receipt)) != 0)
{
    //do stuff
}
Yuriy Faktorovich
Unfortunately this will only work for enums that havent had their values already defined. In this particular case our BillTypes have already been defined as 1-8... Sadly.. I like the neatness of this one..
Mongus Pong
I'd recommend reserving the FlagsAttribute for things that are, well, flags. Decorating the BillType with `[Flags]` says to me that any combination of BillTypes can be applied to the value, which clearly isn't the case.
Mike Powell
@Mike in that case why would the same thing need to be done to them. In a different system, a BillType may indeed be a flag. Although you are right, does seem like a code smell to me. I can take it down.
Yuriy Faktorovich
A: 

Try checking out the Strategy Design Pattern (a.k.a. the Policy Design Pattern).

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...
    }
}

Here's a great post on how to dynamically resolve the policy from Los Techies.

Jarrett Meyer
Good pattern, wrong problem. This doesn't answer the original question!
Dan Puzey
I do see where youre coming from. Its a higher level solution to the problem and could be worth contemplating in some cases if Im putting lots of if statements all around the place.
Mongus Pong
+6  A: 

You could do with with .Contains like this:

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

Or, create your own extension method that does it with a more readable syntax

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

Then call it by:

if(type.IsIn(BillType.Receipt,BillType.Bill,BillType.Payment)){}
Mark
+3  A: 

There's also the switch statement

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

Try using a switch

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

        break;
    }
bleeeah
A: 

What about getting an array of all Enums values and iterate through this?

http://maniish.wordpress.com/2007/09/27/iterate-through-enumeration-c/

p.marino