Предложения Cases оцениваются в порядке, указанном в коде.
Переключение - это не более, чем последовательность, если затем, если еще, тогда и еще, и так далее, в кратком и более читаемом виде.
Таким образом, он прерывает синтаксический анализ при первом истинном условии, если вы ставите оператор break или return, или throw, или оператор goto, иначе они также проверяются последовательно.
Например, вы можете написать:
case 0:
case 1:
DoSomething();
break;
Но вы не можете написать:
case 0:
DoSomething();
// break or return or throw or goto needed here
case 1:
DoAnotherSomething();
break;
Вы можете отладить строку за строкой с некоторым примером, чтобы проверить это.
Ваш второй пример не компилируется, потому чтоусловия должны быть заданы от общего к общему.
Пример:
object instance = new Form();
switch ( instance )
{
case Form f when f.Text == "Test":
return;
case Form f:
return;
case Label l:
return;
}
Сгенерирован код IL:
// object obj = new Form();
IL_0001: newobj instance void [System.Windows.Forms]System.Windows.Forms.Form::.ctor()
IL_0006: stloc.0
// object obj2 = obj;
IL_0007: ldloc.0
IL_0008: stloc.s 7
// object obj3 = obj2;
IL_000a: ldloc.s 7
IL_000c: stloc.1
// if (obj3 == null)
IL_000d: ldloc.1
// (no C# code)
IL_000e: brtrue.s IL_0012
// }
IL_0010: br.s IL_002c
// if ((form = (obj3 as Form)) == null)
IL_0012: ldloc.1
IL_0013: isinst [System.Windows.Forms]System.Windows.Forms.Form
// (no C# code)
IL_0018: dup
IL_0019: stloc.2
IL_001a: brfalse.s IL_0020
IL_001c: br.s IL_002e
IL_001e: br.s IL_0048
// if ((label = (obj3 as Label)) != null)
IL_0020: ldloc.1
IL_0021: isinst [System.Windows.Forms]System.Windows.Forms.Label
// (no C# code)
IL_0026: dup
IL_0027: stloc.3
IL_0028: brfalse.s IL_002c
IL_002a: br.s IL_004f
IL_002c: br.s IL_0056
// Form form2 = form;
IL_002e: ldloc.2
IL_002f: stloc.s 4
// if (!(form2.Text == "Test"))
IL_0031: ldloc.s 4
IL_0033: callvirt instance string [System.Windows.Forms]System.Windows.Forms.Control::get_Text()
IL_0038: ldstr "Test"
IL_003d: call bool [mscorlib]System.String::op_Equality(string, string)
// (no C# code)
IL_0042: brtrue.s IL_0046
IL_0044: br.s IL_001e
IL_0046: br.s IL_0056
// Form form3 = form;
IL_0048: ldloc.2
IL_0049: stloc.s 5
// (no C# code)
IL_004b: br.s IL_004d
IL_004d: br.s IL_0056
// Label label2 = label;
IL_004f: ldloc.3
IL_0050: stloc.s 6
// (no C# code)
IL_0052: br.s IL_0054
IL_0054: br.s IL_0056
IL_0056: ret
Как видите, этот код является последовательностьютесты и разветвления.
https://docs.microsoft.com/dotnet/api/system.reflection.emit.opcodes