53

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#?

Mongus Pong
  • 11,337
  • 9
  • 44
  • 72

7 Answers7

88

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)) {}
Amal K
  • 4,359
  • 2
  • 22
  • 44
Mark
  • 9,966
  • 7
  • 37
  • 39
  • Extension, definitely. I really think the `Enum` class should have a similar method to deal with this issue. Either that or the LINQ environment should add enum-related functions. Very elegant solution. – tfrascaroli Jun 13 '18 at 06:21
13

There's also the switch statement

switch(type) {
    case BillType.Bill:
    case BillType.Payment:
    case BillType.Receipt:
        // Do stuff
        break;
}
wasatz
  • 4,158
  • 2
  • 23
  • 30
11

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
  • 67,283
  • 14
  • 105
  • 142
  • 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 Mar 01 '10 at 16:02
  • 7
    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 Mar 01 '10 at 16:21
  • @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 Mar 01 '10 at 16:35
4

Try using a switch

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

        break;
    }
bleeeah
  • 3,534
  • 19
  • 25
0

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 Belozorov
  • 5,856
  • 7
  • 40
  • 73
0

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
  • 19,333
  • 6
  • 58
  • 52
  • Good pattern, wrong problem. This doesn't answer the original question! – Dan Puzey Mar 01 '10 at 16:05
  • 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 Mar 01 '10 at 16:14
0

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
  • 6,244
  • 3
  • 25
  • 36