7

I just had an idea last nigth when writing an if-expression and sometimes the expression tend to be long when you have it like this:

if(x == 1 || x == 2 || x == 33 || x == 4 || x == -5 || x == 61) { ... }

x can be enums,strings,ints,chars you get the picture.

I want to know if there are an easier way of writing this. I think of sql's operator 'in' for example as a eay to shorten the expression:

if(x in (1,2,33,4,-5,61)) { ... }

I know you can't write an expression like this with 'in' because the lexer and parser of the compiler won't recognize it.

Perhaps other solutions as extension methods of different types of x is the solution? In the coming .NET 4.0 i heard something about parameterized methods, should that solve the n amount of parameters supplied to the if-expression ?

Perhaps you understand me, have you an idea of a good practice/solution to this question?

/Daniel

Pop Catalin
  • 61,751
  • 23
  • 87
  • 115
Daniel Svensson
  • 169
  • 2
  • 5
  • I find the title a bit confusing. Seems like you want to use C# in an operator overload. I put the IN in caps for lack of better idea of how to make that more clear. – Boris Callens Nov 04 '09 at 09:51

6 Answers6

18

I usually write an Extension Method as follows:

public static bool In<T>(this T source, params T[] list)
{
  if(null==source) throw new ArgumentNullException("source");
  return list.Contains(source);
}

Which can be used like this:

if(x.In(1,6,9,11))
{
      // do something....
}
Winston Smith
  • 21,585
  • 10
  • 60
  • 75
  • 1
    I like this one because it is generic and uses the Contains method rather then the == operator. – Boris Callens Nov 04 '09 at 10:05
  • I can't thumbs up this enough... It feels so much more natural. I also added an overload: public static bool In(this T source, IEnumerable list) with the same body. – Chris Pfohl Nov 01 '10 at 17:56
13

Try the following

if ( (new []{1,2,33,4,-5,61}).Any(i => x == i) ) {
  ...
}
JaredPar
  • 733,204
  • 149
  • 1,241
  • 1,454
  • 3
    With type inference you can even skip the `int` (I think). – Svish Nov 04 '09 at 09:15
  • @Svish, didn't realize that was possible but verified it works with 2010 Beta2. Updated answer – JaredPar Nov 04 '09 at 09:18
  • 7
    I would use `new []{1,2,33,4,-5,61}).Contains(x)`, Contains is usually used to determine if a sequence contains an element and therefore more explicit in expressing the intent, Any() is more generic even of you can make it act like contains by using a simple equality check – Pop Catalin Nov 04 '09 at 09:22
  • 1
    I think the extension method route is better design. In your solution, you are duplicating the logic of the In function every time you use it. With the extension method, the algorithm is centralised and can be changed globally if required - plus it also looks cleaner at the point of use. – Winston Smith Nov 04 '09 at 09:54
  • That's pretty ugly. The extension method approach is much clearer and easier to read. – Ash Nov 04 '09 at 10:15
1
    public static bool In<T>(this T X, params T[] list)
    {
        foreach (var item in list)
        {
            if (X.Equals(item))
                return true;
        }
        return false;
    }
Alex Reitbort
  • 13,504
  • 1
  • 40
  • 61
0
   string[] possible = new string[3] { 1, 2, 3);

   if (possible.Contains(x)) { ...
Paddy
  • 33,309
  • 15
  • 79
  • 114
0
    bool In<T>(T num, params int args)
    {
        return (new List<T>(args)).Contains(num);
    }
Boris Modylevsky
  • 3,029
  • 1
  • 26
  • 42
  • 1
    Why have a generic method, which only takes a list of ints? Consider using params T[] args instead - which you can then call .Contains on directly. – Winston Smith Nov 04 '09 at 10:02
0

Given that x is an int you could write an extension method like so:

public static bool In(this int i, params int[] values){
    foreach(int v in values) {
        if (i == v) {
            return true;
        }
    }
    return false;
}
Cros
  • 4,367
  • 9
  • 41
  • 47