写C#逻辑判断,不要只知道if-else 和switch

1,492 阅读3分钟

那天看到一篇文章《写 JS 逻辑判断,不要只知道用 if-else 和 switch》,感觉写的非常好,然后就想到这些想法同样也适用于C#,于是就有了今天这篇文章。

其实无论是JS还是C#,更或者Java,Python...,当遇到有很多逻辑判断的时候,我们第一想到的可能就算if-else或者switch。当条件很多时,我们就会发现一个方法中大概有数不清的if-else或者switch(数不清有点夸张…大家懂得…),总之呢看起来非常头疼,那么如何写出更优雅的代码来代替if-else或者switch呢?

比如下面一段代码:

private void jumpIfElse(string status)
        {
            if(status == "1")
            {
                sendLog("processing");
                jumpTo("IndexPage");
            }
            else if(status == "2" || status == "3")
            {
                sendLog("fail");
                jumpTo("FailPage");
            }
            else if(status == "4")
            {
                sendLog("success");
                jumpTo("SuccessPage");
            }
            else if(status == "5")
            {
                sendLog("success");
                jumpTo("SuccessPage");
            }
            else
            {
                sendLog("other");
                jumpTo("Index");
            }
        }

可以看到上述代码逻辑就是根据不同的状态值产生日志和页面跳转,这段代码用switch重写如下:

private void jumpSwitch(string status)
        {
            switch (status)
            {
                case "1":
                    sendLog("processing");
                    jumpTo("IndexPage");
                    break;
                case "2":
                case "3":
                    sendLog("fail");
                    jumpTo("FailPage");
                    break;
                case "4":
                    sendLog("success");
                    jumpTo("SuccessPage");
                    break;
                case "5":
                    sendLog("cancel");
                    jumpTo("CancelPage");
                    break;
                default:
                    sendLog("other");
                    jumpTo("Index");
                    break;
            }
        }

看起来比if-else好一些,那么有没有更简洁的方式呢,请看下面:

private string [] generateStr(string status)
        {
            Dictionary<string, string[]> dictionary = new Dictionary<string, string[]>();
            dictionary.Add("1", "processing,IndexPage".Split(','));
            dictionary.Add("2", "fail,FailPage".Split(','));
            dictionary.Add("3", "fail,FailPage".Split(','));
            dictionary.Add("4", "success,SuccessPage".Split(','));
            dictionary.Add("5", "cancel,CancelPage".Split(','));
            dictionary.Add("0", "other,Index".Split(','));
            return dictionary[status];
        }
        private void jump(string status)
        {
            sendLog(generateStr(status)[0]);
            jumpTo(generateStr(status)[1]);
        }

上面的代码看起来是不是舒服很多呢?将判断条件作为字典的key值,处理逻辑作为字典的value值,每次只需要维护字典部分即可,特别适用于处理单项条件判断逻辑嘻嘻。

现在我们要升级问题难度了哦,这个方法中不仅要判断状态,还要验证身份:

 private void jumper(string status,string identity)
        {
            if (identity == "guest")
            {
                if (status == "1")
                {
                    doSomething();
                }
                else if (status == "2" || status == "3")
                {
                    doSomething();
                }
                else if (status == "4")
                {
                    doSomething();
                }
                else if (status == "5")
                {
                    doSomething();
                }
                else
                {
                    doSomething();
                }
            }
            else if (identity == "admin")
            {
                if (status == "1")
                {
                    doSomething();
                }
                else if (status == "2" || status == "3")
                {
                    doSomething();
                }
                else if (status == "4")
                {
                    doSomething();
                }
                else if (status == "5")
                {
                    doSomething();
                }
                else
                {
                    doSomething();
                }
            }
        }

从上面的例子可以看出,每加一层判断,代码就要加一倍,可想而知,要是一直这样加下去....额额额,我相信你一定不想读这样的代码。

那么有没有什么干净利索的方式呢,没错那就是用反射,字典的value值传方法名。

 private string generateStr(string status,string identity)
        {
            Dictionary<string, string> dictionary = new Dictionary<string, string>();
            dictionary.Add("guest_1", "doSomething");//doSomething是方法名
            dictionary.Add("guest_2", "doSomething");
            dictionary.Add("guest_3", "doSomething");
            dictionary.Add("guest_4", "doSomething");
            dictionary.Add("guest_5", "doSomething");
            dictionary.Add("admin_1", "doSomething");
            dictionary.Add("admin_2", "doSomething");
            dictionary.Add("admin_3", "doSomething");
            dictionary.Add("admin_4", "doSomething");
            dictionary.Add("admin_5", "doSomething");
            dictionary.Add("0", "doSomething");
            return dictionary[identity_status];
        }
       public void jump(string status, string identity)
        {
            string methodName = generateStr(identity + "_" + status);
            Type type = Type.GetType("ClassName");      // 通过类名获取同名类(替换自己的类名)
            Object obj = System.Activator.CreateInstance(type);       // 创建实例
            MethodInfo method = type.GetMethod(methodName, new Type[] { });      // 获取方法信息
            object[] parameters = null;
            method.Invoke(obj, parameters);                           // 调用方法,参数为空
        }

上述代码的核心是将两个判断条件拼接成字符串作为字典的key值,然后执行的方法名作为字典的value值,然后用反射去调用方法。每次增加判断条件或者处理逻辑,只需要修改字典部分即可,是不是看着舒服了许多,而且也不容易出错。 总结以下,本文主要主要提到了:

  1. if-else
  2. switch
  3. 单一判断,存储到字典中
  4. 多重判断,将条件拼接字符串作为字典的key值,将方法名作为字典的value值,然后用反射调用方法。 当然还有很多其他方式,比如可以使用工厂模式+策略模式去重构if-else和switch过多的情况,这里也只是给大家一个思路。 不一定不用if-else就不好,适合自己的代码就是最好的代码。

题外话:本来想多写一点,可是有点累,先到这了。

第一次掘金平台发文章,也希望大家多多支持哦!!!

新手请大家多多指教!!!

另外可以关注我的微信公众号: