在代码进行优化的时候,发现了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太长的方法的更多相关文章

  1. insert语句太长,有StringBuilder优化一下

    private void btnSave_Click(object sender, RoutedEventArgs e) { if (IsInsert) { //假设日历控件没有选日期,那帮它赋一个当 ...

  2. spark SQL读取ORC文件从Driver启动到开始执行Task(或stage)间隔时间太长(计算Partition时间太长)且产出orc单个文件中stripe个数太多问题解决方案

    1.背景: 控制上游文件个数每天7000个,每个文件大小小于256M,50亿条+,orc格式.查看每个文件的stripe个数,500个左右,查询命令:hdfs fsck viewfs://hadoop ...

  3. java反射机制性能优化

    import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.uti ...

  4. Google IO 2019 Android 太长不看版

    Google I/O 2019, 这里有个playlist是所有Android开发相关的session视频合集: Android & Play at Google I/O 2019 当然啦每个 ...

  5. Asp.Net SignalR 使用记录 技术回炉重造-总纲 动态类型dynamic转换为特定类型T的方案 通过对象方法获取委托_C#反射获取委托_ .net core入门-跨域访问配置

    Asp.Net SignalR 使用记录   工作上遇到一个推送消息的功能的实现.本着面向百度编程的思想.网上百度了一大堆.主要的实现方式是原生的WebSocket,和SignalR,再次写一个关于A ...

  6. C#如何反射出委托的签名,如何使用反射调用委托

    本文阐述C#中如何反射出委托的签名,假如我们有委托FooDelegate定义如下 delegate double FooDelegate (string param, bool condition); ...

  7. URL 路径长度限制(错误:指定的文件或文件夹名称太长)

    本节讨论 URL 的构成.SharePoint 2010 构建 URL 的方式.URL 的编码和加长以及作为其他 URL 中的参数传递的方式. SharePoint URL 的构成 SharePoin ...

  8. paip.数据挖掘--导出词库 清理太长的iptcode

    paip.数据挖掘--导出词库 清理太长的iptcode 原来eng2atian的时候儿,有些cnchar无对眼的atian,走临时使用nonex代替... 而个,要不个那清理给挂了.. #keywo ...

  9. 如果一条SQL语句太长,我们可以通过回车键来创建一个新行来编写SQL语句,SQL语句的命令结束符为分号(;)。

    1.如果一条SQL语句太长,我们可以通过回车键来创建一个新行来编写SQL语句,SQL语句的命令结束符为分号(;). 2.select查询的多个字段之间要用逗号“,”分割,如果查询涉及多个表,那多个表之 ...

随机推荐

  1. Redis(三)内存模型

    本文转载自编程迷思,原文链接 深入学习Redis(1):Redis内存模型 前言 Redis是目前最火爆的内存数据库之一,通过在内存中读写数据,大大提高了读写速度,可以说Redis是实现网站高并发不可 ...

  2. Linux 下让终端走代理的方法

    转载: https://blog.fazero.me/2015/09/15/%E8%AE%A9%E7%BB%88%E7%AB%AF%E8%B5%B0%E4%BB%A3%E7%90%86%E7%9A%8 ...

  3. 2019年,200道面试题打造最受企业欢迎的iOS程序猿!

    在2018年底,小编混迹在各种iOS交流群中,整理出了将近两百道大厂最喜欢在面试问到的问题,今天在这里分享给大家[免费获取方式在最后]!                           小编就不在 ...

  4. C++练习 | 在递增序列中查找最后一个小于等于指定数的元素

    #include <iostream> using namespace std; int mid,l0; int solve(int a1[],int l,int r,int x) { & ...

  5. navicat mysql 存储过程

    存储过程如同一门程序设计语言,同样包含了数据类型.流程控制.输入和输出和它自己的函数库. 一.基本数据类型:略 二.变量: 自定义变量:DECLARE   a INT ; SET a=100; 可用以 ...

  6. 完全卸载MySQL数据库,实现重装

    一.在控制面板,卸载MySQL的所有组件 控制面板——>所有控制面板项——>程序和功能,卸载所有和MySQL有关的程序 二.找到你的MysQL安装路径,看还有没有和MySQL有关的文件夹, ...

  7. 两种方法实现Linux不活动用户登录超时后自动登出

    在平常的工作中,windows系统使用的比较多一些,身边的很多同事都会对自己的电脑进行一些个性化设置,比如离开一段时间后自动锁屏.自动关闭屏幕.自动注销当前登录等.在windows下可以这样操作,那么 ...

  8. Mysql存中文字符出错:Incorrect string value: '\xC2\xE9\xD7\xED\解决方法

    1.数据库连接设置编码格式为UTF-8 jdbc:mysql://localhost:3306/jbpm_test?useUnicode=true&characterEncoding=UTF- ...

  9. iview中tree的事件运用

    iview中的事件和方法如下: 案例说明: html代码 <Tree :data="data4" @on-check-change="choiceAll" ...

  10. MongoDB DBA 实践3-----安装mongdb4.0发生错误

    在安装mongodb时,常常会出现一些错误,导致无法安装完全,下面则是各种错误与它们的解决方法: 1.在window机安装mongodb4.0, 其中的一种:由于缺失系统补丁,而导致无法完全安装,具体 ...