用反射或委托优化switch太长的方法
在代码进行优化的时候,发现了switch case太长,有的竟然长达30个远远超过一屏这样在代码的可读性来说很差。特别在我们看代码的时候要拉下拉框我个人觉得这是不合理的。但是我不建议有switch就进行反射或委托来解决。看实际的情况比喻10个以为还是可以接受的。因为switch看起来更加的直接而且效率相对来说是最好的。那下面就用代码来一点点进行解释
1:传统的用法
1.1:现在我们有一个需求通过传递参数来获取相关的信息。首先我们先看方法
- public class SwitchMethod {
- public string GetSerialNumber(string serialNumber)
- {
- return serialNumber;
- }
- public string GetName(string name)
- {
- return name;
- }
- public string GetAge(string age)
- {
- return age;
- }
- public string GetBirthday(string birthday)
- {
- return birthday;
- }
- }
调用的方法
1.2:客户端的调用
- string action =Console.ReadLine() ;
- var switchMethod=new SwitchMethod();
- switch (action)
- {
- case "serialNumber":
- Console.WriteLine(switchMethod.GetSerialNumber(""));
- break;
- case "name":
- Console.WriteLine(switchMethod.GetName("zhangsan"));
- break;
- case "age":
- Console.WriteLine(switchMethod.GetAge(""));
- break;
- case "birthday":
- Console.WriteLine(switchMethod.GetBirthday(""));
- break;
- }
客户端调用
1.3:效果
以上是我们最常规的用法看起来最直观但是你想过没有如果有30个方法呢你还这样进行switch case吗 50,100个呢所以下面我用委托来代码
2:委托替代switch
上面我又发现一个问题action凌乱,如果太多了就搞不清什么是什么了所以我们加入枚举
2.1:建立枚举
- public enum ActionEnum
- {
- /// <summary>
- /// 编号
- /// </summary>
- SerialNumber = ,
- /// <summary>
- /// 姓名
- /// </summary>
- Name = ,
- /// <summary>
- /// 年龄
- /// </summary>
- Age = ,
- /// <summary>
- /// 生日
- /// </summary>
- Birthday =
- }
action枚举
2.2:我采取字典把需要switch的都存起来
- private static void LoadDictionary()
- {
- if (AllDictionary.Count<=)
- {
- var switchMethod = new SwitchMethod();
- AllDictionary.Add(ActionEnum.SerialNumber, switchMethod.GetSerialNumber);
- AllDictionary.Add(ActionEnum.Age, switchMethod.GetAge);
- AllDictionary.Add(ActionEnum.Birthday, switchMethod.GetBirthday);
- AllDictionary.Add(ActionEnum.Name, switchMethod.GetName);
- }
- }
字典保存
2.3:建立委托(这是比较简单的其实在方法中还可以提取相似的操作放在委托执行)
- public static string Exec(string str,Func<string, string> method) {
- return method(str);
- }
委托
2.4:客户端调用
- Console.WriteLine(Exec("", AllDictionary[ActionEnum.Age]));
客户端调用
2.5:效果
3:反射替代switch
3.1建立一个自定义Attribute类(目的是为了附带方法中的信息)
- public class MethodAttribute : Attribute
- {
- public ActionEnum MethodName;
- public MethodAttribute(ActionEnum methodName)
- {
- this.MethodName = methodName;
- }
- }
特性类
3.2:定义一个基类
- public class BaseMethod
- {
- public Hashtable GetMethodAttribute<T>(T t)
- {
- var hashtable = new Hashtable();
- Type type = t.GetType();
- foreach (MethodInfo method in type.GetMethods())
- {
- var methodArray = (MethodAttribute[]) method.GetCustomAttributes(typeof (MethodAttribute), false);
- foreach (MethodAttribute actionMethodAttribute in methodArray)
- {
- ActionEnum actionName = actionMethodAttribute.MethodName;
- hashtable.Add(actionName, method);
- }
- }
- return hashtable;
- }
- public string DoAction(ActionEnum actionName,string str) {
- Hashtable ht = GetMethodAttribute(this);
- string message = ht.Contains(actionName)
- ? ((MethodInfo) ht[actionName]).Invoke(this, new object[] {str}).ToString()
- : string.Format("{0} 超过范围", actionName);
- return message;
- }
- }
基类
3.3:修改SwitchMethod类并给方法加上特性
- public class SwitchMethod : BaseMethod
- {
- [Method(ActionEnum.SerialNumber)]
- public string GetSerialNumber(string serialNumber)
- {
- return serialNumber;
- }
- [Method(ActionEnum.Name)]
- public string GetName(string name)
- {
- return name;
- }
- [Method(ActionEnum.Age)]
- public string GetAge(string age)
- {
- return age;
- }
- [Method(ActionEnum.Birthday)]
- public string GetBirthday(string birthday)
- {
- return birthday;
- }
- }
SwitchMethod 类
3.4:客户端调用
- string result = new SwitchMethod().DoAction(ActionEnum.SerialNumber,"");
3.5:注释
3.5.1:type.GetMethods():获取这个类中所有的方法包括基类的方法
3.5.2:method.GetCustomAttributes(typeof (MethodAttribute), false):获取这个方法所有关于MethodAttribute类型的自定义特性
3.5.3:MethodInfo:表示对类中方法的访问
3.6:运行效果
三种方式总结
1:传统的用法
优点:简单易读,效率高
缺点:当量很多的时候会造成方法很长,不易维护,可能修改其中某一个case会引起未知的错误
2:委托
优点:使用委托将公有的进行提取,减少代码量
缺点:加入字典后每次添加都需要在字典后手动添加一个子项。总是觉得别扭,效率稍微差点
3:反射
优点:代码量减少,不在考虑内部如何实现,而且符合开闭原则,只需要添加新的方法,其他地方不作修改。维护性强
缺点:很明显这个效率最差(此处并未加入缓存)
第三种方式参考:http://www.cnblogs.com/vipsoft/archive/2012/10/19/2731126.html
用反射或委托优化switch太长的方法的更多相关文章
- insert语句太长,有StringBuilder优化一下
private void btnSave_Click(object sender, RoutedEventArgs e) { if (IsInsert) { //假设日历控件没有选日期,那帮它赋一个当 ...
- spark SQL读取ORC文件从Driver启动到开始执行Task(或stage)间隔时间太长(计算Partition时间太长)且产出orc单个文件中stripe个数太多问题解决方案
1.背景: 控制上游文件个数每天7000个,每个文件大小小于256M,50亿条+,orc格式.查看每个文件的stripe个数,500个左右,查询命令:hdfs fsck viewfs://hadoop ...
- java反射机制性能优化
import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.uti ...
- Google IO 2019 Android 太长不看版
Google I/O 2019, 这里有个playlist是所有Android开发相关的session视频合集: Android & Play at Google I/O 2019 当然啦每个 ...
- Asp.Net SignalR 使用记录 技术回炉重造-总纲 动态类型dynamic转换为特定类型T的方案 通过对象方法获取委托_C#反射获取委托_ .net core入门-跨域访问配置
Asp.Net SignalR 使用记录 工作上遇到一个推送消息的功能的实现.本着面向百度编程的思想.网上百度了一大堆.主要的实现方式是原生的WebSocket,和SignalR,再次写一个关于A ...
- C#如何反射出委托的签名,如何使用反射调用委托
本文阐述C#中如何反射出委托的签名,假如我们有委托FooDelegate定义如下 delegate double FooDelegate (string param, bool condition); ...
- URL 路径长度限制(错误:指定的文件或文件夹名称太长)
本节讨论 URL 的构成.SharePoint 2010 构建 URL 的方式.URL 的编码和加长以及作为其他 URL 中的参数传递的方式. SharePoint URL 的构成 SharePoin ...
- paip.数据挖掘--导出词库 清理太长的iptcode
paip.数据挖掘--导出词库 清理太长的iptcode 原来eng2atian的时候儿,有些cnchar无对眼的atian,走临时使用nonex代替... 而个,要不个那清理给挂了.. #keywo ...
- 如果一条SQL语句太长,我们可以通过回车键来创建一个新行来编写SQL语句,SQL语句的命令结束符为分号(;)。
1.如果一条SQL语句太长,我们可以通过回车键来创建一个新行来编写SQL语句,SQL语句的命令结束符为分号(;). 2.select查询的多个字段之间要用逗号“,”分割,如果查询涉及多个表,那多个表之 ...
随机推荐
- spring整合mongo及调用
spring整合mongo(maven工程下): 1.web.xml文件中配置需要加载的配置文件: <listener> <listener-class>org.springf ...
- list详解
#include <iostream> #include <vector> #include <list> std::list<std::string> ...
- VC++使用socket进行TCP、UDP通信实例总结
1. 两台计算机通信需要协议,通信的两台计算机IP必须唯一 2. 同一个计算机可以进行多个应用程序与其他计算机通信,IP地址唯一,而端口号是区别同一计算机(同一IP)的唯一 ...
- [LuoguP1064][Noip2006]金明的预算方案
金明的预算方案(Link) 题目描述 现在有\(M\)个物品,每一个物品有一个钱数和重要度,并且有一个\(Q\),如果\(Q = 0\),那么该物件可以单独购买,当\(Q != 0\)时,表示若要购买 ...
- Linux下Java性能监控
Linux下Java性能监控 一.JVM堆内存使用监控 获取thread dump的3种方法: 1)使用$JAVA_HOME/bin/jcosole中的MBean,到MBean>com.sun. ...
- ubuntu snmp Error: unknown payload OID
ubuntu snmp Error: unknown payload OID 2013-11-12 15:51:48 标签:ubuntu Error snmp unknown payload OID ...
- 8. DBNEWID 工具(使用nid命令修改db name及dbid)
以下参考自:https://www.2cto.com/database/201305/207860.html Oralce官网:https://docs.oracle.com/cd/E11882_01 ...
- iOS 类似微博或朋友圈的信息流
1.先上图: image.png image.png 因为做过了好几次这样的需求,所以这次想到把它拿出来,下次再需要做的时候直接拿过来改改就能用了,节约时间. 2.功能 文字收起和展开,行高自 ...
- ABAP术语-V1 Module
V1 Module 原文;http://www.cnblogs.com/qiangsheng/archive/2008/03/21/1115707.html Function module creat ...
- CentOS7.6离线安装JDK1.8
卸载CentOS自带的openJDK: 查看openJDK命令:rpm -qa|grep java 结果: java-1.8.0-openjdk-headless-1.8.0.181-7.b13.el ...