gpt4 book ai didi

c# - 带有 when 子句的 switch 语句的评估顺序是什么?

转载 作者:太空宇宙 更新时间:2023-11-03 11:57:54 25 4
gpt4 key购买 nike

考虑以下示例:

public static double ComputeArea_Version3(object shape)
{
switch (shape)
{
case Square s when s.Side == 0:
case Circle c when c.Radius == 0:
return 0;

case Square s:
return s.Side * s.Side;
case Circle c:
return c.Radius * c.Radius * Math.PI;
default:
throw new ArgumentException(
message: "shape is not a recognized shape",
paramName: nameof(shape));
}
}

when 子句 case Square s when s.Sid​​e == 0: 是否保证在更通用的 case Square s: 之前执行?是什么决定了 switch 中的顺序和位置?如果我改为写:

public static double ComputeArea_Version3(object shape)
{
switch (shape)
{
case Square s:
return s.Side * s.Side;
case Circle c:
return c.Radius * c.Radius * Math.PI;

case Square s when s.Side == 0:
case Circle c when c.Radius == 0:
return 0;

default:
throw new ArgumentException(
message: "shape is not a recognized shape",
paramName: nameof(shape));
}
}

永远不会评估 when 子句吗?

最佳答案

Cases 子句按照代码指示的顺序求值。

switch 只不过是一系列的 if then else if then else 等等,以一种简洁且更具可读性的方式。

因此,如果您放入 break 或 return 或 throw 或 goto 语句,它会在第一个 true 条件下中断解析,否则它们也会被连续检查。

例如你可以这样写:

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://learn.microsoft.com/dotnet/api/system.reflection.emit.opcodes

关于c# - 带有 when 子句的 switch 语句的评估顺序是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58772427/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com