aAbfEEAsefEEAECBteXW~| 475454VC 7888}555WC G7845VYBZZZBC-~~ 47VBCC 5557464G74V~ G75V G755V G75VCC 77F8WC 954754754G5556VCC 95475474V~B~B~BZC-~X

Switch.` You find yourself in a mysterious dungeon. There is a dim light from above. The cell door is locked. You notice a box full of 1000 keys, all different.`After trying 5 keys,` you realize a faster way to switch keys is needed. As a developer, you know a switch statement has lookup table optimizations. Switch is your only hope now.`First example.` This program uses a switch. It introduces an int local. With a switch, it tests the int against two constants—1 and 5. Doom is no longer certain. `Caution: `Not every variable can be used in a switch. Most built-in value types, like int or char, work.`Strings: `A switch can handle strings. These are implemented in a different way. They use a hidden Dictionary.`Another example.` This includes curly brackets and the default case. The program accepts an int from the user (with ReadLine). It then tests it for six values. `We see how the curly brackets are used in the switch cases. And we combine some of the case statements.`Strings.` Often we switch on values, like numbers. The contents of strings are not value types—they are collections of characters. But with special support, we switch on strings too. `The C# compiler detects a string switch and can optimize it with a Dictionary lookup.`Note 2: `Small string switches, like this one with just 3 cases, are often not compiled into Dictionaries. Performance is better this way.`Types.` It is possible to switch on integers or other value types, such as enums or chars. Strings are a reference type, but the C# compiler can handle switches on strings as well. `Switch Char `switch-char`Switch Enum `switch-enum`Switch String `string-switch`Case.` We use this keyword to specify a matching constant. Some cases (default) do not use the case keyword. We end a case with "break" or "return." `Case `case`Goto.` We can use goto statements in switches. These are different from other gotos. With goto we can run multiple cases for a single expression. `Goto, Switch `goto`Break.` This keyword is used within switches. And continue may also be used. These 2 keywords are used also within loops. Sometimes they are used in both loop and switch statements. `Break `break`Continue `continue`So: `Are you breaking out of a switch, or out of the enclosing loop? Scope is important: the deepest construct is broken first.`Double.` Some values may not be switched upon. Floating-point values, like doubles, will cause an error in a switch expression. Most classes and custom types will also fail. `Bool: `A bool may be used in the expression of a switch. But this is somewhat strange as only true and false are allowed.`Nullable: `A nullable type can be used, but only if the nullable type "wraps" a valid switch type like an enum.`Nested switch.` Sometimes one switch is not enough. But we can nest a switch within another switch, successively testing values. This approach is sometimes helpful. `Nested Switch `nested-switch`But: `Our code logic, with nested switches, quickly turns into a mess. With comments, this approach may succeed.`I test the first two elements in an int array with switches. The second element is tested if the first is 4.`Fall through.` Every case must have a break, continue, goto, return or throw at its end. In C# we cannot have cases with statements fall through to the following case. `Goto: `We can use the goto statement, as in "goto case 1," to run both cases on a 0 value. As shown, the program does not compile.`Duplicate cases.` A switch can only have unique case labels—each constant value must be distinct. This program will not compile. But it shows us what happens when we have duplicate cases. `Constants.` We must use only constants for case statements. This is a limitation, but it is part of the language specification. The C# compiler is not even tempted. `Benchmark.` A switch statement helps optimize some programs. Suppose a method that must return a value based on a small range of inputs. We can use switch to test these values. `Method 1 uses a switch statement. But method 2 instead uses a series of if-statements.`The benchmark shows that the switch statement version is slightly faster. Those nanoseconds may come in handy someday.`Pattern matching, types.` We can use pattern matching on types in a switch. We switch on a variable. In each case, we can match its type. A local variable (cast to that type) can be used. `We introduce a class hierarchy—the Bird and Cat classes inherit from Animal. We then create some class instances.`We match the types of the Animal class. The most derived class is matched first—in this switch form, order matters.`Pattern matching, when.` We can place a condition on each case statement. This can test another variable. Here we test a local variable called secondValue on the first 2 cases. `We have repeat "case 200" statements. They are different only because of their "when" clauses.`Tip 2: `With the "when pattern-matching" syntax, order matters in a switch. This is an enhanced syntax form.`Speed.` Switch can be implemented with a jump table in the intermediate language. Large switches can be much faster than long series of if-else statements. `1. If and switch. `The if-statement sometimes performs better than the switch. Testing is essential.`If, Switch Comparison `if-switch-performance`2. Regex and switch. `The switch statement can be used to replace a Regex method call. This can make programs much faster.`Regex, Switch `regex-versus-loop`3. Intermediate language: `Switch is often implemented at a lower level with the switch opcode. We show an example.`IL: switch `il`Usage.` Should we use switches everywhere? This is probably a bad idea. With polymorphism, we abstract selections with virtual methods and inheritance. This leads to cleaner code. `Virtual `virtual`So: `If you want to use switches everywhere in your code, go ahead. But don't expect to be admired for it.`Refactoring.` We consider a quote from the book Refactoring, an excellent treatise on how to improve code so it is not terrible. Well-designed code is easier to maintain. `Quote: `The problem with switch statements is essentially that of duplication. Often you find the same switch statement scattered around a program in different places. If you add a new clause to the switch, you have to find all these switch statements and change them (Refactoring).`Some thoughts.` Switches often outperform if-statements. But more importantly, they help with code design. They enforce all values tested are constants.`Symmetry.` This construct imparts a greater sense of symmetry. Switches test value types and strings. They speed up selections. And with them, we write clearer code.

FGXKjXXGDGQGbGJGAX{XFG%F{XFFGiGhGyj5j;XFFjGHj (Gh)XFF{XFFFjcasej j1j:XFFFFG'1);XFFFFGGXFFFjcasej j5j:XFFFFG'5);XFFFFGGXFF}XF}X}XXjXX5jXXGJGAX{XFG%F{XFFGR (true)XFF{XFFFGQ.G'KType GEGVpress ReturnK);XFFFtryXFFF{XFFFFGiiGyGz.Parse(GQ.G5.GuLine());XFFFFjGHj (i)XFFFF{XFFFFFGfj0j:XFFFFFGfj1j:XFFFFFGfj2j:XFFFFFF{XFFFFFFFGQ.G'KLow GEK);XFFFFFFFGGXFFFFFF}XFFFFFGfj3j:XFFFFFGfj4j:XFFFFFGfj5j:XFFFFFF{XFFFFFFFGQ.G'KMedium GEK);XFFFFFFFGGXFFFFFF}XFFFFFdefault:XFFFFFF{XFFFFFFFGQ.G'KOther GEK);XFFFFFFFGGXFFFFFF}XFFFF}XFFF}XFFFcatchXFFF{XFFF}XFF}XF}X}XXjXXType GEGVpress ReturnXj5jXMedium GEXType GEGVpress ReturnXj2jXLow GEXType GEGVpress ReturnXj500jXOther GEjXXGDGQGbGJGAX{XFG%F{XFFGP GhGyKturnipK;jXFFG9Switch on the GP.XFFjGHj (Gh)XFF{XFFFGfjKlettuceKj:XFFFFG'KLETTUCEK);XFFFFGGXFFFGfjKsquashKj:XFFFFG'KSQUASHK);XFFFFGGXFFFGfjKturnipKj:XFFFFG'jKTURNIPKj);XFFFFGGXFF}XF}X}XXjXXTURNIPjXXGJGAX{XFG%F{XFFdouble GhGyj1.4j;XFFjGHj (Gh)XFF{XFFFGf1:XFFFFGGXFF}XF}X}XXjXXError 1XA GH expression or Gflabel must be a bool, char, GP,XGzegral, enum, or corresponding nullable type....jXXGDGQGbGJGAX{XFG%F{XFFGz[] GUGy{ j4j, j10j, j14j };XFFjGHj (GU[0])XFF{XFFFGfj3j:XFFFFG'3);j G{Not reached.XFFFFjGGXXFFFGfj4j:XFFFFG'4);jXFFFFG9Use nested GH.XFFFFjGHj (GU[1])XFFFF{XFFFFFGfj10j:XFFFFFFG'10);XFFFFFFGGXFFFF}XFFFFGGXFF}XF}X}XXjXX4X10jXXGDGQGbGJGAX{XFG%F{XFFGiGhGy0;jXFFG9Every GH statement must be terminated.XFFjGHj (Gh)XFF{XFFFjGf0j:XFFFFG'KZeroK);XFFFGf1:XFFFFG'KOneK);XFFFFGGXFF}XF}X}XXjXXError 1XControl cannot fall through from one Gflabel ('Gf0:')GjanotherjXXGDGQGbGJGAX{XFG%F{XFFshort GEGy0;jXFFG9Cases may not be duplicated.XFFjGHj (GE)XFF{XFFFjGf0:jXFFFjGf0:jXFFFFG'KZEROK);XFFFFGK;XFFFGf1:XFFFFG'KONEK);XFFFFGK;XFF}XF}X}XXjXXError 1XThe label 'Gf0:' already occursGpthis GH statementjXXGDGQGbGJGAX{XFG%F{XFFGiGEGy0;XFFGitestGy10;jXFFG9Constant Ghs are required.XFFjGHj (GE)XFF{XFFFjGftestG}1:jXFFFFG'100);XFFFFGK;XFFFGf0:XFFFFG'0);XFFFFGK;XFF}XF}X}XXjXXError 1XA constant Gh is expectedjXXGDGQ;XG!XGJGAX{XFG?GiMGg1(Giv)XF{XFFjGHj (v)XFF{XFFFGf0:XFFFFGK 10;XFFFGf1:XFFFFGK -1;XFFFGf2:XFFFFGK 20;XFFFdefault:XFFFFGK 0;XFF}XF}XXFG?GiMGg2(Giv)XF{XFFjifj (vGx0) GK 10;XFFGmvGx1) GK -1;XFFGmvGx2) GK 20;XFFGK 0;XF}XXFG%F{XFFMGg1(0); MGg2(0);XFFconst GimaxGy100000000GbFFvar s1GyG,.G`New();XFFGw(GiiGy0; i < max; i++)XFF{XFFFMGg1(0);XFFFMGg1(1);XFFFMGg1(2);XFFFMGg1(3);XFF}XFFs1G3;XFFvar s2GyG,.G`New();XFFGw(GiiGy0; i < max; i++)XFF{XFFFMGg2(0);XFFFMGg2(1);XFFFMGg2(2);XFFFMGg2(3);XFF}XFFs2G3;XFFG'(G0(s1.G# * 1000000) /XFFFmax).ToGO(K0.00 nsK));XFFG'(G0(s2.G# * 1000000) /XFFFmax).ToGO(K0.00 nsK));XFFG5.Gu();XF}X}XXjResultsjXXj9.25 nsjF[GH]Xj9.85 nsjF[if]jXXGDGQGbGJAnimalX{XFGBGisize;X}XXGJBird : AnimalX{XFGBGicolor;X}XXGJCat : AnimalX{XFGBbool wild;X}XXGJGAX{XFG?GcTest(Animal animal)XF{jXFFG{Switch on a GJtype with pattern matching.XFFjGH (animal)XFF{XFFFjcasej jCat cj:XFFFFG'j$KCAT wildGy{c.wild}Kj);XFFFFGGXFFFjcasej jBird bj:XFFFFG'j$KBIRD colorGy{b.color}Kj);XFFFFGGXFFFjcasej jAnimal aj:XFFFFG'j$KANIMAL sizeGy{a.size}Kj);XFFFFGGXFF}XF}XXFG%F{jXFFG{CG_ some GJinstances.XFFjCatj catGyGqCat();XFFcat.wildGytrue;XFFjBirdj birdGyGqBird();XFFbird.colorGy5;XFFjAnimalj animalGyGqAnimal();XFFanimal.sizeGy10;jXXFFG{Test GJinstances.XFFjTest(cat);XFFTest(bird);XFFTest(animal);XF}X}XXjXXCAT wildGyTrueXBIRD colorGy5XANIMAL sizeGy10jXXGDGQGbGJGAX{XFG%F{XFFGiGhGy200;XFFGisecondGXGy300;jXFFG{Use GH with pattern matching.XFFjGH (Gh)XFF{XFFFjcasej 200 jwhen secondGXGx0j:XFFFFG'jKYKj);XFFFFGGXFFFjcasej 200 jwhen secondGXGx300j:XFFFFG'jKGX is 200, secondGX is 300Kj);XFFFFGGXFFFjcasej 400:XFFFFG'jKZKj);XFFFFGGXFF}XF}X}XXjXXGX is 200, secondGX is 300j

+VZ2:]6231enswitchint switchswitches on stringcauses switch double errornested switchhas fall-through errorhas duplicate caselacks constant casebenchmarks switchswitch, matches typespattern matching, when keyword