热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

用反射或委托优化switch太长的方法

在代码进行优化的时候,发现了switchcase太长,有的竟然长达30个远远超过一屏这样在代码的可读性来说很差。特别在我们看代码的时候要拉下拉框我个人觉得这是不合理的。但是我不建议有switch

  在代码进行优化的时候,发现了switch case太长,有的竟然长达30个远远超过一屏这样在代码的可读性来说很差。特别在我们看代码的时候要拉下拉框我个人觉得这是不合理的。但是我不建议有switch就进行反射或委托来解决。看实际的情况比喻10个以为还是可以接受的。因为switch看起来更加的直接而且效率相对来说是最好的。那下面就用代码来一点点进行解释

1:传统的用法

1.1:现在我们有一个需求通过传递参数来获取相关的信息。首先我们先看方法

 1 public class SwitchMethod {        
2 public string GetSerialNumber(string serialNumber)
3 {
4 return serialNumber;
5 }
6
7 public string GetName(string name)
8 {
9 return name;
10 }
11
12 public string GetAge(string age)
13 {
14 return age;
15 }
16
17 public string GetBirthday(string birthday)
18 {
19 return birthday;
20 }
21
22 }
调用的方法

1.2:客户端的调用

 1 string action =Console.ReadLine() ;
2 var switchMethod=new SwitchMethod();
3 switch (action)
4 {
5 case "serialNumber":
6 Console.WriteLine(switchMethod.GetSerialNumber("1234"));
7 break;
8 case "name":
9 Console.WriteLine(switchMethod.GetName("zhangsan"));
10 break;
11 case "age":
12 Console.WriteLine(switchMethod.GetAge("21"));
13 break;
14 case "birthday":
15 Console.WriteLine(switchMethod.GetBirthday("19960201"));
16 break;
17 }
客户端调用

1.3:效果

以上是我们最常规的用法看起来最直观但是你想过没有如果有30个方法呢你还这样进行switch case吗 50,100个呢所以下面我用委托来代码

2:委托替代switch

上面我又发现一个问题action凌乱,如果太多了就搞不清什么是什么了所以我们加入枚举

2.1:建立枚举

 1 public enum ActionEnum
2 {
3 ///
4 /// 编号
5 ///

6 SerialNumber = 0,
7 ///
8 /// 姓名
9 ///

10 Name = 1,
11 ///
12 /// 年龄
13 ///

14 Age = 2,
15 ///
16 /// 生日
17 ///

18 Birthday = 3
19 }
action枚举

2.2:我采取字典把需要switch的都存起来

 1 private static void LoadDictionary()
2 {
3 if (AllDictionary.Count<=0)
4 {
5 var switchMethod = new SwitchMethod();
6 AllDictionary.Add(ActionEnum.SerialNumber, switchMethod.GetSerialNumber);
7 AllDictionary.Add(ActionEnum.Age, switchMethod.GetAge);
8 AllDictionary.Add(ActionEnum.Birthday, switchMethod.GetBirthday);
9 AllDictionary.Add(ActionEnum.Name, switchMethod.GetName);
10 }
11 }
字典保存

2.3:建立委托(这是比较简单的其实在方法中还可以提取相似的操作放在委托执行)

1 public static string Exec(string str,Func<string, string> method) {
2 return method(str);
3 }
委托

2.4:客户端调用

1 Console.WriteLine(Exec("21", AllDictionary[ActionEnum.Age]));
客户端调用

2.5:效果

3:反射替代switch

 3.1建立一个自定义Attribute类(目的是为了附带方法中的信息)

1 public class MethodAttribute : Attribute
2 {
3 public ActionEnum MethodName;
4
5 public MethodAttribute(ActionEnum methodName)
6 {
7 this.MethodName = methodName;
8 }
9 }
特性类

3.2:定义一个基类

 1 public class BaseMethod
2 {
3 public Hashtable GetMethodAttribute(T t)
4 {
5 var hashtable = new Hashtable();
6 Type type = t.GetType();
7 foreach (MethodInfo method in type.GetMethods())
8 {
9 var methodArray = (MethodAttribute[]) method.GetCustomAttributes(typeof (MethodAttribute), false);
10 foreach (MethodAttribute actionMethodAttribute in methodArray)
11 {
12 ActionEnum actiOnName= actionMethodAttribute.MethodName;
13 hashtable.Add(actionName, method);
14 }
15 }
16 return hashtable;
17 }
18
19
20 public string DoAction(ActionEnum actionName,string str) {
21 Hashtable ht = GetMethodAttribute(this);
22 string message = ht.Contains(actionName)
23 ? ((MethodInfo) ht[actionName]).Invoke(this, new object[] {str}).ToString()
24 : string.Format("{0} 超过范围", actionName);
25 return message;
26 }
27 }
基类

3.3:修改SwitchMethod类并给方法加上特性

 1     public class SwitchMethod : BaseMethod
2 {
3 [Method(ActionEnum.SerialNumber)]
4 public string GetSerialNumber(string serialNumber)
5 {
6 return serialNumber;
7 }
8
9 [Method(ActionEnum.Name)]
10 public string GetName(string name)
11 {
12 return name;
13 }
14
15 [Method(ActionEnum.Age)]
16 public string GetAge(string age)
17 {
18 return age;
19 }
20
21 [Method(ActionEnum.Birthday)]
22 public string GetBirthday(string birthday)
23 {
24 return birthday;
25 }
26 }
SwitchMethod 类

3.4:客户端调用

string result = new SwitchMethod().DoAction(ActionEnum.SerialNumber,"1332");

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


推荐阅读
  • 本文分享了一个关于在C#中使用异步代码的问题,作者在控制台中运行时代码正常工作,但在Windows窗体中却无法正常工作。作者尝试搜索局域网上的主机,但在窗体中计数器没有减少。文章提供了相关的代码和解决思路。 ... [详细]
  • 开发笔记:加密&json&StringIO模块&BytesIO模块
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了加密&json&StringIO模块&BytesIO模块相关的知识,希望对你有一定的参考价值。一、加密加密 ... [详细]
  • 本文介绍了一个在线急等问题解决方法,即如何统计数据库中某个字段下的所有数据,并将结果显示在文本框里。作者提到了自己是一个菜鸟,希望能够得到帮助。作者使用的是ACCESS数据库,并且给出了一个例子,希望得到的结果是560。作者还提到自己已经尝试了使用"select sum(字段2) from 表名"的语句,得到的结果是650,但不知道如何得到560。希望能够得到解决方案。 ... [详细]
  • 本文详细介绍了GetModuleFileName函数的用法,该函数可以用于获取当前模块所在的路径,方便进行文件操作和读取配置信息。文章通过示例代码和详细的解释,帮助读者理解和使用该函数。同时,还提供了相关的API函数声明和说明。 ... [详细]
  • 本文介绍了Java工具类库Hutool,该工具包封装了对文件、流、加密解密、转码、正则、线程、XML等JDK方法的封装,并提供了各种Util工具类。同时,还介绍了Hutool的组件,包括动态代理、布隆过滤、缓存、定时任务等功能。该工具包可以简化Java代码,提高开发效率。 ... [详细]
  • 如何使用Java获取服务器硬件信息和磁盘负载率
    本文介绍了使用Java编程语言获取服务器硬件信息和磁盘负载率的方法。首先在远程服务器上搭建一个支持服务端语言的HTTP服务,并获取服务器的磁盘信息,并将结果输出。然后在本地使用JS编写一个AJAX脚本,远程请求服务端的程序,得到结果并展示给用户。其中还介绍了如何提取硬盘序列号的方法。 ... [详细]
  • 在重复造轮子的情况下用ProxyServlet反向代理来减少工作量
    像不少公司内部不同团队都会自己研发自己工具产品,当各个产品逐渐成熟,到达了一定的发展瓶颈,同时每个产品都有着自己的入口,用户 ... [详细]
  • [大整数乘法] java代码实现
    本文介绍了使用java代码实现大整数乘法的过程,同时也涉及到大整数加法和大整数减法的计算方法。通过分治算法来提高计算效率,并对算法的时间复杂度进行了研究。详细代码实现请参考文章链接。 ... [详细]
  • 利用Visual Basic开发SAP接口程序初探的方法与原理
    本文介绍了利用Visual Basic开发SAP接口程序的方法与原理,以及SAP R/3系统的特点和二次开发平台ABAP的使用。通过程序接口自动读取SAP R/3的数据表或视图,在外部进行处理和利用水晶报表等工具生成符合中国人习惯的报表样式。具体介绍了RFC调用的原理和模型,并强调本文主要不讨论SAP R/3函数的开发,而是针对使用SAP的公司的非ABAP开发人员提供了初步的接口程序开发指导。 ... [详细]
  • 前景:当UI一个查询条件为多项选择,或录入多个条件的时候,比如查询所有名称里面包含以下动态条件,需要模糊查询里面每一项时比如是这样一个数组条件:newstring[]{兴业银行, ... [详细]
  • 第四章高阶函数(参数传递、高阶函数、lambda表达式)(python进阶)的讲解和应用
    本文主要讲解了第四章高阶函数(参数传递、高阶函数、lambda表达式)的相关知识,包括函数参数传递机制和赋值机制、引用传递的概念和应用、默认参数的定义和使用等内容。同时介绍了高阶函数和lambda表达式的概念,并给出了一些实例代码进行演示。对于想要进一步提升python编程能力的读者来说,本文将是一个不错的学习资料。 ... [详细]
  • SpringMVC接收请求参数的方式总结
    本文总结了在SpringMVC开发中处理控制器参数的各种方式,包括处理使用@RequestParam注解的参数、MultipartFile类型参数和Simple类型参数的RequestParamMethodArgumentResolver,处理@RequestBody注解的参数的RequestResponseBodyMethodProcessor,以及PathVariableMapMethodArgumentResol等子类。 ... [详细]
  • Android自定义控件绘图篇之Paint函数大汇总
    本文介绍了Android自定义控件绘图篇中的Paint函数大汇总,包括重置画笔、设置颜色、设置透明度、设置样式、设置宽度、设置抗锯齿等功能。通过学习这些函数,可以更好地掌握Paint的用法。 ... [详细]
  • Todayatworksomeonetriedtoconvincemethat:今天在工作中有人试图说服我:{$obj->getTableInfo()}isfine ... [详细]
  • 本文总结和分析了JDK核心源码(2)中lang包下的基础知识,包括常用的对象类型包和异常类型包。在对象类型包中,介绍了Object类、String类、StringBuilder类、StringBuffer类和基本元素的包装类。在异常类型包中,介绍了Throwable类、Error类型和Exception类型。这些基础知识对于理解和使用JDK核心源码具有重要意义。 ... [详细]
author-avatar
饱和深潜者_463
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有