OR operator in C#
Solution 1
No, you can do:
if (new[] { "b", "c" }.Contains(a))
if you have the LINQ extensions available, but that's hardly an improvement.
In response to the comment about performance, here's some basic timing code. Note that the code must be viewed with a critical eye, I might have done things here that skew the timings.
The results first:
||, not found: 26 ms
||, found: 8 ms
array.Contains, not found: 1407 ms
array.Contains, found: 1388 ms
array.Contains, inline array, not found: 1456 ms
array.Contains, inline array, found: 1427 ms
switch-statement, not interned, not found: 26 ms
switch-statement, not interned, found: 14 ms
switch-statement, interned, not found: 25 ms
switch-statement, interned, found: 8 ms
All the code was executed twice, and only pass nr. 2 was reported, to remove JITting overhead from the equation. Both passes executed each type of check one million times, and executed it both where the element to find was one of the elements to find it in (that is, the if-statement would execute its block), and once where the element was not (the block would not execute). The timings of each is reported. I tested both a pre-built array and one that is built every time, this part I'm unsure how much the compiler deduces and optimizes away, there might be a flaw here.
In any case, it appears that using a switch-statement, with or without interning the string first, gives roughly the same results as the simple or-statement, which is to be expected, whereas the array-lookup is much more costly, which to me was also expected.
Please tinker with the code, and correct (or comment) it if there's problems.
And here's the source code, rather long:
using System;
using System.Linq;
using System.Diagnostics;
namespace StackOverflow826081
{
class Program
{
private const Int32 ITERATIONS = 1000000;
static void Main()
{
String a;
String[] ops = CreateArray();
Int32 count;
Stopwatch sw = new Stopwatch();
Int32 pass = 0;
Action<String, Int32> report = delegate(String title, Int32 i)
{
if (pass == 2)
Console.Out.WriteLine(title + ": " + sw.ElapsedMilliseconds + " ms");
};
for (pass = 1; pass <= 2; pass++)
{
#region || operator
a = "a";
sw.Start();
count = 0;
for (Int32 index = 0; index < ITERATIONS; index++)
{
if (a == "b" || a == "c")
{
count++;
}
}
sw.Stop();
report("||, not found", count);
sw.Reset();
a = "b";
sw.Start();
count = 0;
for (Int32 index = 0; index < ITERATIONS; index++)
{
if (a == "b" || a == "c")
{
count++;
}
}
sw.Stop();
report("||, found", count);
sw.Reset();
#endregion
#region array.Contains
a = "a";
sw.Start();
count = 0;
for (Int32 index = 0; index < ITERATIONS; index++)
{
if (ops.Contains(a))
{
count++;
}
}
sw.Stop();
report("array.Contains, not found", count);
sw.Reset();
a = "b";
sw.Start();
count = 0;
for (Int32 index = 0; index < ITERATIONS; index++)
{
if (ops.Contains(a))
{
count++;
}
}
sw.Stop();
report("array.Contains, found", count);
sw.Reset();
#endregion
#region array.Contains
a = "a";
sw.Start();
count = 0;
for (Int32 index = 0; index < ITERATIONS; index++)
{
if (CreateArray().Contains(a))
{
count++;
}
}
sw.Stop();
report("array.Contains, inline array, not found", count);
sw.Reset();
a = "b";
sw.Start();
count = 0;
for (Int32 index = 0; index < ITERATIONS; index++)
{
if (CreateArray().Contains(a))
{
count++;
}
}
sw.Stop();
report("array.Contains, inline array, found", count);
sw.Reset();
#endregion
#region switch-statement
a = GetString().Substring(0, 1); // avoid interned string
sw.Start();
count = 0;
for (Int32 index = 0; index < ITERATIONS; index++)
{
switch (a)
{
case "b":
case "c":
count++;
break;
}
}
sw.Stop();
report("switch-statement, not interned, not found", count);
sw.Reset();
a = GetString().Substring(1, 1); // avoid interned string
sw.Start();
count = 0;
for (Int32 index = 0; index < ITERATIONS; index++)
{
switch (a)
{
case "b":
case "c":
count++;
break;
}
}
sw.Stop();
report("switch-statement, not interned, found", count);
sw.Reset();
#endregion
#region switch-statement
a = "a";
sw.Start();
count = 0;
for (Int32 index = 0; index < ITERATIONS; index++)
{
switch (a)
{
case "b":
case "c":
count++;
break;
}
}
sw.Stop();
report("switch-statement, interned, not found", count);
sw.Reset();
a = "b";
sw.Start();
count = 0;
for (Int32 index = 0; index < ITERATIONS; index++)
{
switch (a)
{
case "b":
case "c":
count++;
break;
}
}
sw.Stop();
report("switch-statement, interned, found", count);
sw.Reset();
#endregion
}
}
private static String GetString()
{
return "ab";
}
private static String[] CreateArray()
{
return new String[] { "b", "c" };
}
}
}
Solution 2
Well, the closest to that you can get is:
switch (a) {
case "b":
case "c":
// variable a is either "b" or "c"
break;
}
Solution 3
You can use Regular Expressions:
if(Regex.IsMatch(a, "b|c"))
If the contents of "a" can be longer than one character use this:
if(Regex.IsMatch(a, "^(b|c)$"))
Solution 4
To my knowledge that isn't an option.
Solution 5
No, not with that syntax. But there are many options to code that.
if ("bc".Contains(a)) { } // Maybe check a.Length == 1, too.
if ((a[0] & 0x62) == 0x62) { } // Maybe check a.Length == 1, too.
if (new String[] { "b", "c" }.Contains(a)) { }
Maybe you could do some operator overloading and get your syntax working, but this really depends on what you want to achieve and is hard to tell from your simple example.
Saif Khan
Updated on June 04, 2022Comments
-
Saif Khan 12 months
Can I achieve
if (a == "b" || "c")
instead of
if (a == "b" || a== "c")
?
-
Darren Kopp about 14 years... don't you mean || operator?
-
Summer Sun about 14 yearsThe | operator is not exclusively a binary operator in C#, it still has an important purpose: stackoverflow.com/questions/579352/calling-methods-inside-if-c/…
-
Lasse V. Karlsen about 14 years| is both logical and binary, depending on expression, but it evaluates both sides, so while the code wasn't the typical code, it was still correct.
-
Greg about 14 yearsI've wished for this ability for a long time.
-
cregox almost 11 yearsI've wished for something similar. Just remove all quotes and there you go.
-
-
Nathan Ridley about 14 yearsThe accepted answer is less code, but using a switch statement has less overhead I believe.
-
Lucas B about 14 yearsI recommend this solution instead. First, it is more readable. Second, it has less overhead. Third, if the logic has to change in the future it is easier to maintain.
-
Kon about 14 yearsAccepted answer might fit nicer on a single line, but this one doesn't allocate extra memory for an array.
-
Richard about 14 yearsIf the array is allocated statically, then performance test might be interesting (if time taken by the expression is long enough to be measured against the overhead of the timing).
-
Patrik Hägne almost 14 yearsI would argue that the alternative given in the question - "if(a == "b" || a== "c")" - is the closest you can get and is - in my opinion - a way better solution than introducing the switch-statement.