那天看到一篇文章《写 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值,然后用反射去调用方法。每次增加判断条件或者处理逻辑,只需要修改字典部分即可,是不是看着舒服了许多,而且也不容易出错。 总结以下,本文主要主要提到了:
- if-else
- switch
- 单一判断,存储到字典中
- 多重判断,将条件拼接字符串作为字典的key值,将方法名作为字典的value值,然后用反射调用方法。 当然还有很多其他方式,比如可以使用工厂模式+策略模式去重构if-else和switch过多的情况,这里也只是给大家一个思路。 不一定不用if-else就不好,适合自己的代码就是最好的代码。
题外话:本来想多写一点,可是有点累,先到这了。
第一次掘金平台发文章,也希望大家多多支持哦!!!
新手请大家多多指教!!!
另外可以关注我的微信公众号: