代码之家  ›  专栏  ›  技术社区  ›  Toto

C迭代开关的情况

  •  1
  • Toto  · 技术社区  · 15 年前

    是否可以以编程方式检索开关的所有情况?我不知道,也许是我,但不知道怎么做…

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

    4 回复  |  直到 15 年前
        1
  •  2
  •   Community Mike Causer    7 年前

    有一些方法可以避免在代码中直接将属性名用作字符串。我发布了一个代码片段 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]();
    }
    

    调用这两个方法时,请确保使用代码段的成员类(请参见链接),而不是直接使用属性名。因此,您可以确保您的代码是可重构的,因为它不包含任何“魔力字符串”。

    最好的问候

        2
  •  2
  •   bobbymcr    15 年前

    在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
    // ...
    

    编写能够在所有情况下正确分析这一点的代码将是相当大的工作量。

    我能看到的测试这一点的唯一方法是实际覆盖所有情况,并确保最终不会得到空的propertyinfo。如果您正在使用的代码非常重要并且不会失败,那么在任何情况下使用反射可能都非常危险。你能改成更安全的设计吗?

        3
  •  1
  •   Guffa    15 年前

    在一个开关中获取值并不是一件小事…

    如果在开关中使用枚举而不是字符串,则可以使用 Enum.GetValues .

        4
  •  0
  •   CannibalSmith    15 年前

    用awk或perl或其他任何语言编写一个脚本来检查源代码本身,并在每次构建之前运行它。