C#迭代开关的情况

时间:2009-09-01 08:16:12

标签: c# switch-statement il

是否可以通过编程方式检索所有交换机的情况?我不知道,也许是IL,但不知道怎么办......

实际上我的全局问题如下:我得到了一个siwtch案例,其中字符串作为属性名称。该方法非常重要,不允许回归。我不希望重构打破这个,所以我想要一个方法来测试所有case字符串实际上是我的对象的真实属性。 (注意:默认值返回一些东西,所以我不能为重构的无效值抛出exceptino)。

4 个答案:

答案 0 :(得分:2)

有很多方法可以避免在代码中直接使用属性名称作为字符串。我发布了一个代码段here

然后,不要使用switch语句,而是实现类似这样的东西:

private IDictionary<string, Action> _actions;

public void RegisterAction(string propertyName, Action action)
{
    _actions.Add(propertyName, action);
}

public void DoSomething(string propertyName)
{
    _actions[propertyName]();
}

当您调用这两种方法时,请确保使用代码段的Member类(请参阅链接),而不是直接使用属性名称。所以你可以确保你的代码是重构证明的,因为它不包含任何“魔术字符串”。

最好的问候

答案 1 :(得分:2)

在IL中,switch语句编译成如下:

// ...
L_000c: ldloc.1 
L_000d: ldstr "case1"
L_0012: call bool [mscorlib]System.String::op_Equality(string, string)
L_0017: brtrue.s L_0035
L_0019: ldloc.1 
L_001a: ldstr "case2"
L_001f: call bool [mscorlib]System.String::op_Equality(string, string)
L_0024: brtrue.s L_0042
L_0026: ldloc.1 
L_0027: ldstr "case3"
L_002c: call bool [mscorlib]System.String::op_Equality(string, string)
L_0031: brtrue.s L_004f
// ...

编写可以在所有情况下正确分析这些代码的代码是相当多的工作。

我能看到测试这个的唯一方法是实际覆盖所有情况,并确保不会以null PropertyInfo结束。如果您正在使用的代码非常重要且无法失败,那么在任何情况下使用反射都可能非常危险。你能采用更安全的设计吗?

答案 2 :(得分:1)

在交换机中获取值并不是一件容易的事......

如果在开关中使用枚举而不是字符串,则可以使用Enum.GetValues轻松获取枚举值。

答案 3 :(得分:0)

在AWK或Perl或其他任何内容中编写脚本以检查源本身,并在每次构建之前运行它。