关于switch case怎么优化代码啊

Zanvimocvy 2013-07-10 10:37:31
大家都知道一个语句代码太多,维护会不方便,且难以理解。这个时候我们就要用到重构,请问switch case语句怎么重构呢,怎么优化这样的代码,给个链接也可以,要有效才行,立即给分。
下面是一个例子
int i;
switch(i)
{
case 0;
DoResult(i);
break;

case 1:
Doresult(i);
break;

case 2:
DoResult(i);
break;

.....
下面有一百个这样的case语句
}
//DoResult()是一个函数,其实这里应该有一个返回值吧,简单点,大家懂就行。


当case太多的时候,显然不合理。这里的重复代码太多,麻烦大家想一下,怎么能去掉这个switch case,换做其他的语句代替它。
...全文
903 32 打赏 收藏 转发到动态 举报
写回复
用AI写文章
32 条回复
切换为时间正序
请发表友善的回复…
发表回复
Zanvimocvy 2013-08-01
  • 打赏
  • 举报
回复
问题解决了,谢谢各位的回答!
橘色的喵 2013-07-12
  • 打赏
  • 举报
回复
引用 29 楼 bambuz 的回复:
建议使用查表法
听过这个方法,怎么实现啊?建表是不是要小心?
bambuz 2013-07-12
  • 打赏
  • 举报
回复
建议使用查表法
Zanvimocvy 2013-07-12
  • 打赏
  • 举报
回复
方法都没用上。
橘色的喵 2013-07-11
  • 打赏
  • 举报
回复
肯定是存在修改的类,有些类设计出来就是为了修改的,如工厂类,manager类等 比较赞同6楼和8楼的方法。不赞成13楼的方法,会产生大量的类,晃眼!!
  • 打赏
  • 举报
回复
我就想问函数每次传入的参都是i,返回的值不一样么?
h576514515 2013-07-11
  • 打赏
  • 举报
回复
如果只是想便于维护的话就用工厂模式,给你个案例吧,我也是重网上看的
public partial class Optimization : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            Employee emp = Employee.GetEmployee(EmployeeType.ENGINEER);
            label_Show.Text += emp.GetDescription();
            label_Show.Text += emp.PayAmount().ToString();
        }
    }


    public enum EmployeeType
    {
        ENGINEER,
        SALESMAN,
        MANAGER
    }

    public abstract class Employee
    {
        protected int basicSalary;
        protected int commission;
        public static Employee GetEmployee(EmployeeType empType)
        {
            switch (empType)
            {
                case EmployeeType.ENGINEER:
                    return new Enginessr();
                case EmployeeType.SALESMAN:
                    return new SalesMan();
                case EmployeeType.MANAGER:
                    return new Manager();
                default:
                    throw new Exception("no such employee type!");
            }
        }

        public abstract int PayAmount();
        public abstract string GetDescription();
    }

    public class Enginessr : Employee
    {
        public override int PayAmount()
        {
            return basicSalary;
        }
        public override string GetDescription()
        {
            return "Coding, Debug, Optimization";
        }
    }

    public class SalesMan : Employee
    {
        public override int PayAmount()
        {
            return basicSalary + commission;
        }
        public override string GetDescription()
        {
            return "Getting contranct";
        }
    }

    public class Manager : Employee
    {
        public override int PayAmount()
        {
            return 2 * basicSalary;
        }
        public override string GetDescription()
        {
            return "Analysis, Scheduling, Reporting";
        }
    }
moonwrite 2013-07-11
  • 打赏
  • 举报
回复
引用 7 楼 goodhtml 的回复:
[quote=引用 6 楼 moonwrite 的回复:] 《代码大全2》 中说可以使用字典来代替N多If else .NET还有linq 是非常爽歪歪的事情 Dictionary<int,委托> dic=new Dictionary<int,委托>() dic.Add(1,DoResult); dic.Add(2,DoResult); var fun=dic.Single(x=>x.Key==N); var result = fun(arg); 没有试过,你自己试试~
呵呵,谢谢你,这个我试过,不过add也解决不了问题呀,重复的也太多了。和case差不多[/quote] 比较容易修改和维护啦~ 8楼说的也差不多是这个意思~
blackboycpp 2013-07-11
  • 打赏
  • 举报
回复
我8楼说法的简单模拟:

// action声明
typedef void (*Action) (void);

// action 1, case 1时执行
void do_1()
{
    cout << "action 1" << endl;
}

// action 2, case 2时执行
void do_2()
{
    cout << "action 2" << endl;
}

// action选择器
void do_action(Action table[], int i)
{
    table[i-1]();
}


int main()
{
    // action表
    Action table[2];
    // 各case值注册到action表
    table[0] = do_1;
    table[1] = do_2;

    // 根据值执行相应的action
    do_action(table, 1);

    return 0;
}
fdjkalfjklajdf 2013-07-11
  • 打赏
  • 举报
回复
感觉情况就是这么多,怎么都得分100种情况,一种一行代码,也要100行。没法从代码再缩减了吧
dongjianhua520520 2013-07-11
  • 打赏
  • 举报
回复
我怎么看都怎么奇怪???? 好像是case N: 执行的都是Doresult(N); void Execute(int N) { Doresult(N); } 这样行么?
blackboycpp 2013-07-11
  • 打赏
  • 举报
回复
这个我觉得得用函数表什么的解决吧 wireshark内部有好多表,用来解析协议。 比如,tcp的端口字段,每个端口可能代表一种应用层协议 它就不是switch/case的 而是维护一张表(应该是hash吧),每个上层协议将它的端口值和对应的解析函数地址注册到此表中。
Zanvimocvy 2013-07-11
  • 打赏
  • 举报
回复
引用 6 楼 moonwrite 的回复:
《代码大全2》 中说可以使用字典来代替N多If else .NET还有linq 是非常爽歪歪的事情 Dictionary<int,委托> dic=new Dictionary<int,委托>() dic.Add(1,DoResult); dic.Add(2,DoResult); var fun=dic.Single(x=>x.Key==N); var result = fun(arg); 没有试过,你自己试试~
呵呵,谢谢你,这个我试过,不过add也解决不了问题呀,重复的也太多了。和case差不多
海洋夜之星 2013-07-11
  • 打赏
  • 举报
回复
建议lz用上泛型和反射机制可以解决……
橘色的喵 2013-07-11
  • 打赏
  • 举报
回复
引用 23 楼 zorou_fatal 的回复:
http://roshanca.com/switch-case-considered-harmful/ 楼主看看这个。command模式重构switch case 代码块
我们的一个winform项目,和服务器通信,定义了大概有200个消息,大概有几十个不同的处理方法。 如果用设计模式的话,会产生大量的类 所以,我觉得6楼和8楼的比较好
E次奥 2013-07-11
  • 打赏
  • 举报
回复
你调用的都是一个函数,传递的是一个参数。直接一句话就行了啊。你输入的i是几传入的就是几啊。
本拉灯 2013-07-11
  • 打赏
  • 举报
回复
我那方案就是23楼相拟,23楼还要那个委托数组里手动去添加方法。 那个Register就是实现了代码自动把这个函数添加到委托数组的过程,其他的都类拟了。
本拉灯 2013-07-11
  • 打赏
  • 举报
回复
引用 22 楼 goodhtml 的回复:
[quote=引用 19 楼 wyd1520 的回复:] [quote=引用 楼主 goodhtml 的回复:] 大家都知道一个语句代码太多,维护会不方便,且难以理解。这个时候我们就要用到重构,请问switch case语句怎么重构呢,怎么优化这样的代码,给个链接也可以,要有效才行,立即给分。 下面是一个例子 int i; switch(i) { case 0; DoResult(i); break; case 1: Doresult(i); break; case 2: DoResult(i); break; ..... 下面有一百个这样的case语句 } //DoResult()是一个函数,其实这里应该有一个返回值吧,简单点,大家懂就行。 当case太多的时候,显然不合理。这里的重复代码太多,麻烦大家想一下,怎么能去掉这个switch case,换做其他的语句代替它。
我自己实现的一方法 只要所有的函数参数个数与类型是一样的,不管你写多少个,函数,你都不要做额外的ADD 只要你写个函数,系统就会自动调用,功能方法你肯定是要实现。然后就把实现的方法自动注册到Handlers下 class Packets { public Packets() { Handlers.Register(this); } [Register(1)] //为注册编号为1 public void Fun1( A a) { } [Register(2)] 为注册编号为2 public void Fun2( A a) { } [Register(3)] public void Fun3( A a) { } ...... } 然后调用就只要Handlers.GetFun(编号).Call(参数) 其他的都不要了。 [/quote]不是很明白,你能用我的例子演示一下吗?[/quote] 只能给你方案。这是我们在项目上实现的一种方案。 被调用的函数有很多,他们共同点就是参数类型与个数是一样的。跟据协议编号调用某个方法,好比你上面的例子 i就是协议号 DoResult(可以有N个,函数名称不同也可以) 就是被调用的方法 还有你那例子被调用的方法都是同一个,那样子用switc没有意义
zorou_fatal 2013-07-11
  • 打赏
  • 举报
回复
http://roshanca.com/switch-case-considered-harmful/ 楼主看看这个。command模式重构switch case 代码块
Zanvimocvy 2013-07-11
  • 打赏
  • 举报
回复
引用 19 楼 wyd1520 的回复:
[quote=引用 楼主 goodhtml 的回复:] 大家都知道一个语句代码太多,维护会不方便,且难以理解。这个时候我们就要用到重构,请问switch case语句怎么重构呢,怎么优化这样的代码,给个链接也可以,要有效才行,立即给分。 下面是一个例子 int i; switch(i) { case 0; DoResult(i); break; case 1: Doresult(i); break; case 2: DoResult(i); break; ..... 下面有一百个这样的case语句 } //DoResult()是一个函数,其实这里应该有一个返回值吧,简单点,大家懂就行。 当case太多的时候,显然不合理。这里的重复代码太多,麻烦大家想一下,怎么能去掉这个switch case,换做其他的语句代替它。
我自己实现的一方法 只要所有的函数参数个数与类型是一样的,不管你写多少个,函数,你都不要做额外的ADD 只要你写个函数,系统就会自动调用,功能方法你肯定是要实现。然后就把实现的方法自动注册到Handlers下 class Packets { public Packets() { Handlers.Register(this); } [Register(1)] //为注册编号为1 public void Fun1( A a) { } [Register(2)] 为注册编号为2 public void Fun2( A a) { } [Register(3)] public void Fun3( A a) { } ...... } 然后调用就只要Handlers.GetFun(编号).Call(参数) 其他的都不要了。 [/quote]不是很明白,你能用我的例子演示一下吗?
加载更多回复(12)

110,526

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧