嵌套开关?或其他解决方案检查不同条件?

use*_*661 3 c# if-statement coding-style case-statement switch-statement

好的,情况如下:

我有一个客户端有2个设置:ConnectionState和ConnectionSollState,都是相同的可枚举(TypeConnectionState),它们存储客户端连接的实际状态和连接应该是的状态.在to的每个组合上,都会发生不同的事情,例如ConnectionState为"已连接"但ConnectionSollState为"已关闭" - >拆除客户端.所以我有4种可能性需要检查.现在每个客户端都可以处理无限数量的会话,并且每个会话都有一个状态(StreamState和StreamSollState),这些状态可以有6个可枚举的选项.

从现在开始,我正在制作20个切换条件,我的代码看起来非常混乱,我在编码时每5分钟做错一次.有没有更简单的方法来处理这样的情况?(if/else)会让事情变得更糟.

例:

private void RTSPWorker() {
    try {
        byte[] buffer = new byte[2048];
        while (!mb_RTSPWorkerAbbort) {
        // Call TransportWD
            Thread.Sleep(100 * mi_ConnectionTimeOut);

            // Check ConnectionSollState
            switch(ConnectionSollState) {
                case TypeConnectionState.Connected:
                    // ConnectionSollState = Connected, check ConnectionState
                    switch(ConnectionState) {
                        case TypeConnectionState.Connected:
                            // ConnectionState is connected, keep-alive!
                            if(GET_PARAMETER() == null) {
                                DESCRIBE();
                            }
                            // Check streams too
                            foreach (cRTSPStream oStream in mo_StreamDict.Values) {
                                // Check StreamSollState
                                switch(oStream.RTSPStreamSollState) {
                                    case cRTSPStream.TypeRTSPStreamState.Play:
                                        // SollState is PLAY, check State
                                        switch(oStream.RTSPStreamState) {
                                            case cRTSPStream.TypeRTSPStreamState.Play:
                                                //Stream is alive, keep-alive!
                                                if (oStream.PLAY() == null) { oStream.DESCRIBE(); } break;
                                            case cRTSPStream.TypeRTSPStreamState.Closed:
                                                // Reinitialise.
                                                if (oStream.SETUP() != null) { oStream.PLAY(); } break;
                                            default:
                                                // Default, send play.
                                                oStream.PLAY(); break;
                                        }
                                    break;
                                case cRTSPStream.TypeRTSPStreamState.Pause:
                                    // SollState is on pause, check State
                                    switch(oStream.RTSPStreamState) {
                                        case cRTSPStream.TypeRTSPStreamState.Closed:
                                            // Reinitialise.
                                            if (oStream.SETUP() != null) { oStream.PLAY(); } break;
                                        default:
                                            oStream.PAUSE();
                                            break;
                                    }
                                break;
                                case cRTSPStream.TypeRTSPStreamState.Closed:
                                    // SollState is closed, check State
                                    switch(oStream.RTSPStreamState) {
                                        case cRTSPStream.TypeRTSPStreamState.Closed:
                                            // Is closed, do nothing
                                            break;
                                        default:
                                            // Default teardown, remove session
                                            oStream.TEARDOWN();
                                            this.RemoveRTSPSession(oStream);
                                            break;
                                        }
                                default:
                                    // Default, what do?
                                    break;
                                }
                            }
                            break;
                        case TypeConnectionState.Closed:
                            // ConnectionState should be connected, re-connect!
                                while(Connect() != true) {
                                    // Sleep for 200ms, try again
                                    Thread.Sleep(200);
                                }
                            break;
                        default:
                            // TODO anything else
                            break;
                    }
                    break;
                case TypeConnectionState.Closed:
                    // Check ConnectionState
                    switch(ConnectionState) {
                        case TypeConnectionState.Connected:
                            // Is connected, should be closed. Close connection & clean up!
                            Close(null);
                            break;
                        default:
                            // Anything other than Connected, do nothing.
                            break;
                    }
                    break;

                default:
                    break;
            }
        }
    } catch {

    }
}
Run Code Online (Sandbox Code Playgroud)

Mar*_*ers 8

神圣的烟雾,蝙蝠侠,这是你在那里难以理解的代码.以下提示可能会改善您的情况.我必须补充一点,这些提示有点偏颇,因为他们更喜欢个人编码风格:

  1. 将switch语句重写为IF语句.嵌套的IF语句比嵌套的switch语句更容易阅读,即使你必须编写更多的代码来获得相同的结果.
  2. 将您的方法分解为几个子方法.你的方法可能试图同时做太多事情.- > 分离关注单一责任原则
  3. 使用改进的真值表.在有逻辑根据变量组合产生某些结果的情况下,您可能希望使用真值表构造.例如,使用List<Tuple<T1,T2,T etc..>>结构.

例如:

var truthTable = List<Tuple<NavigationTab, Role, Action>>
{
    new Tuple<NavigationTab, Role, Action>(NavigationTab.Users, Role.UsersAdministration, MVC.Administration.Users.Index()),
    new Tuple<NavigationTab, Role, Action>(NavigationTab.Users, Role.RolesAdministration, MVC.Administration.Roles.Index()),
    new Tuple<NavigationTab, Role, Action>(NavigationTab.Products, Role.ProductsAdministration, MVC.Administration.Products.Index()),
}
Run Code Online (Sandbox Code Playgroud)

  • 非常正确,但这是纳秒级的性能差异.在99.9%的现实生活场景中,这种性能差异水平绝对可以忽略不计.相反,代码易读性和可维护性等问题更为重要. (2认同)