OR in C #

Can i reach

if (a == "b" || "c") 

instead

 if (a == "b" || a== "c") 

?

+4
source share
7 answers

No, you can do:

 if (new[] { "b", "c" }.Contains(a)) 

if you have LINQ extensions, but this is unlikely to improve.


In response to a performance comment, here are a few basic time codes. Please note that the code must be viewed with a critical eye, I could do something here that distorts the timings.

First results:

 ||, 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 code was executed twice, and only pass nr. 2, to remove JITting overhead from the equation. Both passes performed each type of verification one million times and performed it as where the element to search for was one of the elements to search for it (that is, the if statement executed its block), and once when the element was not (the block will not be executed ) The timings of each of them are reported. I tested both the ready-made array and the one that is built every time, this part, I'm not sure how much the compiler outputs and optimizes away, there may be a drawback.

In any case, it seems that using the switch statement with or without string interpolation at first gives roughly the same results as the simple or -operator that you should expect, while array lookups are much more expensive, which I also expected.

Please change the code and correct (or comment on) it if problems arise.

And here is the source code, quite 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" }; } } } 
+14
source

Well, closest to what you can get:

 switch (a) { case "b": case "c": // variable a is either "b" or "c" break; } 
+16
source

As far as I know, this is not an option.

+3
source

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)$")) 
+3
source

No, not with this syntax. But there are many options for this.

 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)) { } 

You might be able to do some operator overloading and make your syntax work, but it really depends on what you want to achieve, and it's hard to tell from your simple example.

+2
source

You can in certain situations. Namely, the noted listings:

 [Flags] enum MyEnum { None = 0, A = 1, B = 2, C = 4, D = 8 } //... MyEnum a = MyEnum.B if((a & (MyEnum.B | MyEnum.C)) > 0) // do something 

is equivalent to:

 if((a & MyEnum.B) > 0 || (a & MyEnum.C) > 0) // do something 

The reason for this is related to bit masks. In binary format

 None = 00000 A = 00001 B = 00010 C = 00100 D = 01000 

So when we use | operator, we gradually compare the search for any 1 in the column and copy them to the result. If there is no 1 in the column, you copy 0.

  B 00010 & C 00100 --------- 00110 

Then, when we apply the and operator, we look for 1 in all rows in each column before copying 1.

  (B & C) 00110 & (a = B) 00010 --------------- 00010 

What is> 0, thus returning true.

Oddly enough, this is the most efficient way to do this, as it saves you a numerical comparison (>) and a logical operator (||) that does all this a fantastic short circuit and something else.

+2
source

No, this is not how the operator or operator (||) works in C #.

An alternative solution, although making the code less readable, is to create a function that checks the required value, something similar to:

 public static bool Any(object a, params object[] b) { foreach(object item in b) { if(a == b) { return true; } } return false; } 
0
source

All Articles