switch-case的替代方案

3
我想知道这种 switch-case 用法是否适当,或者是否有其他替代方案(模式)?
以下是我的程序的一部分:
基本上我正在执行一系列操作:
1. 通常情况下,程序控制按顺序一个接一个地跟随每个 case;
2. 通常情况下,任何特定的 case 在第一次调用时都没有完成,我们必须等到 procX 返回 true。(等待设备响应或操作完成);
3. 跳转到特定的 case 是可能的(在采样代码中改变 StepCurrent)。
我发现这种 switch-case 很难维护,特别是通过更改 StepCurrent 直接控制流程。而且代码看起来很丑陋。
是否有更好的方法?
注意:虽然我使用的是 C#,但问题可能不仅限于它。
    while (true)
        {
            if (sig_IsExit())
            {
                break;
            }

            Thread.Sleep(500);

            bRetSts = false;
            switch (StepCurrent) // nSeq)
            {
                case 0:
                     bRetSts = proc0();
                     break;

                case 1:

                     bRetSts = proc1();
                    break;
                case 2:
                     bRetSts = proc2();
                    break;

                case 3:
                     bRetSts = proc3();
                    break;

                case 4:
                   ...
            }

            if( bRetSts )
                StepCurrent++;
        }

你可以使用状态模式。每个过程在每个状态中都被使用。然后你可以切换到下一个状态。 - ntohl
你可以创建一个以数字为键、函数委托为值的字典。这将使代码变得更加简洁。 - etalon11
创建一个类似于Action的Func<Boolean>数组,参考这个链接:https://dev59.com/hGAg5IYBdhLWcg3wjbZt - James Black
这看起来不错。不可避免的是,当某一天插入一个新进程时,例如在proc0和proc1之间,我必须更新任何对以前的proc1的引用,现在变成了proc2。这种头痛可能是不可避免的。 - Chengting
3个回答

12
你可以使用一个 Dictionary<int,Func<bool>>,这样就会有更少的圈复杂度,参考以下示例:

注意:我使用Dictionary仅是为了展示你可以使用任何类型作为键,例如具有名称的stringenum

Dictionary<int,Func<bool>> proc = new Dictionary<int,Func<bool>>
{
   {0, proc0},
   {1, proc1},
   {2, proc2},
   {3, proc3},
}

然后像这样使用:

  while (true)
    {
        if (sig_IsExit())
           break;
        Thread.Sleep(500);

        bRetSts = false;
        bRetSts = proc[StepCurrent]();

        if( bRetSts )
            StepCurrent++;
    }

1
这看起来不错。不可避免的是,当有一天插入一个新的过程,例如在proc0和proc1之间时,我必须更新对先前的proc1的任何引用,现在它是proc2。这种头痛可能是不可避免的。 - Chengting

2
bRetSts = (StepCurrent == 0)? proc0():
          (StepCurrent == 1)? proc1():
          (StepCurrent == 2)? proc2():
          (StepCurrent == 3)? proc3():
          false; // it could be more proper to throw an exception

或者,如果所有的procX具有相同的签名,可能更合适:

var funcs = new Func<bool>[] { proc0, proc1, proc2, proc3 };
funcs[StepCurrent]();

o.o,我也会做,kkkkk - Joel R Michaliszen

0

那是我的第二个想法。但是现在已经无法回头了。因此,责任链在使用案例2后不会再使用案例1。如果可能的话,我会使用责任链。从问题中并不清楚。 - ntohl

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接