博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
C#: switch语句的重构『网摘』
阅读量:5104 次
发布时间:2019-06-13

本文共 2605 字,大约阅读时间需要 8 分钟。

http://bj007.blog.51cto.com/1701577/345100/

switch语句是我们日常工作中最常见也是争论最多的(goto被忽视的前提下)。在重构中也把switch语句看成是一种代码的坏味道。但如何改造现有的switch代码并在今后去避免呢?本文从两方面进行探讨。
1 类型转化 
    在不同的抽象层次上对于同一个对象可能会用不同的定义。举个简单的例子,在计算器中,用户输入的操作符号可能是字符型的,而程序内部实现的时候需要用枚举型。因此可能就会有这样的函数。 
        
public 
class Calculator 
        { 
                
public 
enum OPERATOR {Add, Minus, Multiply, Divide, Unknown};
                
public 
static OPERATOR GetOperator(
char ch) 
                { 
                        OPERATOR op = OPERATOR.Unknown;
                        
switch (ch) 
                        { 
                                
case '+': 
                                        op = OPERATOR.Add; 
                                        
break
                                
case '-': 
                                        op = OPERATOR.Minus; 
                                        
break
                                
case '*': 
                                        op = OPERATOR.Multiply; 
                                        
break
                                
case '/': 
                                        op = OPERATOR.Divide; 
                                        
break
                                
default
                                        
break
                        } 
                        
return op; 
                } 
        }
   代码不长,不过写的过程中我却拷贝几次(case部分的代码)。原因就是代码的结构性重复还是比较严重的,而且如果以后支持其他新的操作时候,这代码不仅要改变,而且还会不断变冗长。认真想想,避免的办法还是有的,用Dictionary做一个映射表就可以实现。 
 
     
public 
class Calculator 
        { 
                
public 
enum OPERATOR { Add, Minus, Multiply, Divide, Unknown};
                
static 
private var OperatorMap = 
new Dictionary<
char, OPERATOR> { 
                        { '+', OPERATOR.Add }, 
                        { '-', OPERATOR.Minus }, 
                        { '*', OPERATOR.Divide }, 
                        { '/', OPERATOR.Multiply }, 
                };
                
public 
static OPERATOR GetOperator2(
char ch) 
                { 
                        
if (OperatorMap.ContainsKey(ch)) 
                                
return OperatorMap[ch]; 
                        
else 
                                
return OPERATOR.Unknown; 
                } 
        }
这样,不仅代码简洁了很多,而且从本质上已经从逻辑代码维护变成了映射表的维护。
2 动作调用 
接续刚才的例子,这次不仅要实现操作符转化,而且要实现真正的运算。第一个反应又是想到了switch。实现如下:
 
     
public 
class Calculator 
        { 
                
static 
public 
int Calculate(
char op, 
int number1, 
int number2) 
                { 
                        
int result = 0;
                        
switch (GetOperator(op)) 
                        { 
                                
case OPERATOR.Add: 
                                        result = number1 + number2; 
                                        
break
                                
case OPERATOR.Minus: 
                                        result = number1 - number2; 
                                        
break
                                
case OPERATOR.Multiply: 
                                        result = number1 * number2; 
                                        
break
                                
case OPERATOR.Divide: 
                                        result = number1 / number2; 
                                        
break
                                
default
                                        
throw 
new Exception(
"Unsupported Operation!"); 
                        } 
                        
return result; 
                } 
        }
   跟之前遇到的问题有些类似,不过这回需要调用函数。通过.Net环境提供的Dictionary以及Func Delegate的解决如下: 
        
public 
class Calculator 
        { 
                
static 
private Dictionary<OPERATOR, Func<
int
int
int>> calculationAction = 
new Dictionary<OPERATOR, Func<
int
int
int>> { 
                        { OPERATOR.Add, Add }, 
                        { OPERATOR.Minus, Minus }, 
                        { OPERATOR.Multiply, Multiply }, 
                        { OPERATOR.Divide, Divide }            
                };
                
public 
static OPERATOR GetOperator2(
char ch) 
                { 
                        
if (OperatorMap.ContainsKey(ch)) 
                                
return OperatorMap[ch]; 
                        
else 
                                
return OPERATOR.Unknown; 
                }
                
static 
int Add(
int number1, 
int number2) 
                { 
                        
return number1 + number2; 
                }
                
// Others are omitted here for brevity 
        }
通过这个简单的例子,我们可以看出Switch通常会带来一些结构性的重复,通过利用Dictionary等二维表结构,我们可以尽量去避免switch语句,从而实现更好的灵活性和可维护性。最后需要支持的是,在Switch语句的重构过程中需要注意几点:
* 共通化以使得各个case中调用函数的签名一致 
* if...else if...else结构同switch在某些情况下具有互换性,也可以考虑这种方法 
* switch语句的重构是也可以考虑State Pattern以及Strategy Pattern等设计模式。选择的时候可以考虑视具体情况而定。

本文出自 “” 博客,请务必保留此出处

转载于:https://www.cnblogs.com/tylertang/p/6588757.html

你可能感兴趣的文章
request的响应时间elapsed和超时timeout
查看>>
javascript的字符串大小比较
查看>>
大型网站的 HTTPS 实践(一)—— HTTPS 协议和原理(转)
查看>>
【洛谷P1558】色板游戏
查看>>
程序猿修仙之路--算法之快速排序到底有多快
查看>>
HTTP代理实现请求报文的拦截与篡改9--实现篡改功能后的演示+源码下载
查看>>
Linux常用命令与操作
查看>>
thinkphp5 composer安装验证码
查看>>
Eclipse中最常用的热键
查看>>
PL/SQL恢复默认窗口样式
查看>>
IOS--UISwitch的使用方法
查看>>
VC6工具下查看反汇编代码、机器码的使用技巧
查看>>
LeeTCode题解之Remove Duplicates from Sorted List
查看>>
Silverlight多线程技术Thread的应用
查看>>
前端知识点回顾之重点篇——CSS中vertical align属性
查看>>
我的软件终于被发布了!
查看>>
HDU_1004 Let the Balloon Rise
查看>>
SQLCLR(一)入门
查看>>
C# 串口操作系列(3) -- 协议篇,二进制协议数据解析(转)
查看>>
EasyUI实现图片的上传后与其他文本框的提交以及DataGrid中图片的展示
查看>>