今天在项目中遇到了使用switch语句判断条件,但问题是条件比较多,大概有几十个条件,满屏幕的case判断,是否有更优雅的写法替代switch语句呢?

假设有这样的一个场景:商场经常会根据情况采取不同的打折方案,如果打折方案比较少,可以考虑使用switch语句作判断。但如果有几十甚至几百种打折方案的时候,用switch语句就不够优雅。

先来一个打折接口。

    public interface IValueProcessor
    {
        decimal DaZhe(short policy,decimal orginPrice);
    }

形参policy用来接收有关打折的枚举项,形参orginPrice表示打折前的价格。有关打折的枚举项为:

    public enum PolicyEnum
    {
        Wuzhe = 0,
        LiuZhe = 1,
        QiZhe =2,
        BaZhe =3,
        JiuZhe = 4
    }

实现IValueProcessor接口,根据不同的PolicyEnum项采取不同的算法。

   public class MyValueProcessor : IValueProcessor
    {
        public decimal DaZhe(short policy,decimal orginPrice)
        {
            switch (policy)
            {
                case (short)PolicyEnum.Wuzhe:
                    return orginPrice / 2;
                case (short)PolicyEnum.LiuZhe:
                    return orginPrice * (decimal)0.6;
                case (short)PolicyEnum.QiZhe:
                    return orginPrice * (decimal)0.7;
                case (short)PolicyEnum.BaZhe:
                    return orginPrice * (decimal)0.8;
                case (short)PolicyEnum.JiuZhe:
                    return orginPrice * (decimal)0.9;
                default:
                    return orginPrice / 2;
            }
        }
    }

客户端调用如下:

        static void Main(string[] args)
        {
            Console.WriteLine("请输入打折政策,0表示5折,1表示6折,2表示7折,3表示8折,4表示9折:");
            string policy = Console.ReadLine();
            decimal originPrice = (decimal)100.00;
            Console.WriteLine("打折前的价格为:"+ originPrice);

            MyValueProcessor processor = new MyValueProcessor();
            Console.WriteLine("打折后的价格为:"+ processor.DaZhe(short.Parse(policy),originPrice));
            Console.ReadKey();
        }

以上写法没有太大的问题,是否有替换switch判断,一种更优雅的写法呢?

在MyValueProcessor类的DaZhe(short policy,decimal orginPrice)方法中,接收一个short类型的形参和一个decimal类型的形参,返回decimal类型,在方法内部,把short类型的形参作为switch语句的判断条件,再使用不同的算法得到返回值。可以进一步抽象:把short类型作为字典集合中的key,把算法,即委托作为字典集合的value。这样,我们就可以把各种打折方案封装在字典集合中。修改如下:

    public class MyValueProcessor : IValueProcessor
    {
        private readonly Dictionary<short, Func<decimal, decimal>> _dic;

        public MyValueProcessor()
        {
            _dic = new Dictionary<short, Func<decimal, decimal>>
            {
                {0, m => m * (decimal)0.5},
                {1, m => m * (decimal)0.6},
                {2, m => m * (decimal)0.7},
                {3, m => m * (decimal)0.8},
                {4, m => m * (decimal)0.9}
            };
        }

        public decimal DaZhe(short policy,decimal orginPrice)
        {
            if (_dic.ContainsKey(policy))
            {
                return _dic[policy].Invoke(orginPrice);
            }
            return orginPrice / 2;
        }
    }

这样,在DaZhe(short policy,decimal orginPrice)方法内部,只要判断传入的short类型实参是否是字典集合的key就可以了。

C#中一种替换switch语句更优雅的写法的更多相关文章

  1. SQL中两种表复制语句

    Insert是T-sql中常用语句,Insert INTO table(field1,field2,...) values(value1,value2,...)这种形式的在应用程序开发中必不可少.但我 ...

  2. php中switch语句case后表达式写法记录一

    可作等级评价: $var = 95; switch(true){ case $var < 100; $level = 1; break; case $var < 95; $level = ...

  3. eclipse中更改配置使得switch语句不出错

    分别点击: windows---preference--->java---->compiler--->error/waring---->potential programmin ...

  4. MySQL比like语句更高效的写法locate position instr find_in_set

    使用内部函数instr,可代替传统的like方式查询,并且速度更快. instr函数,第一个参数是字段,第二个参数是要查询的串,返回串的位置,第一个是1,如果没找到就是0. 例如, select na ...

  5. C# 多个个Dictionary合并更优雅的写法

    Dictionary 现在有两个Dictionary的对象,想把两个对象的中数据合并成一个. 使用for循环的话觉得非常不合适,于是考虑是否有相应的方法,网上找了很多,都是for循环,最后终于找到了一 ...

  6. if else 更优雅的写法(转)

    https://www.cnblogs.com/y896926473/articles/9675819.html

  7. Python 为什么不支持 switch 语句?

    本文出自"Python为什么"系列,请查看全部文章 在这篇文章里,我们会聊一聊为什么 Python 决定不支持 switch 语句. 为什么想要聊这个话题呢? 主要是因为 swit ...

  8. 2、Golang基础--包的使用、if-else语句、循环、switch语句、数组、切片、可变函数参数、map类型

    1 包的使用 // 为了便于组织代码,同一种类型的代码,写在同一个包下,便于管理 // 定义包 -新建一个文件夹 -内部有很多go文件 -在每个go文件的第一行,都要声明包名,并且包名必须一致 -在一 ...

  9. 多路开关模式的switch语句

    在实例10中,将break语句去掉之后,会将符合检验条件后的所有语句都输出.利用这个特点,可以设计多路开关模式的switch语句,例如:在平年一年12个月,1.3.5.7.8.10.12月是31天,4 ...

随机推荐

  1. git使用常用命令

    第一部分:个人整理部分(读<Git教程By廖雪峰.pdf>笔记) /* 配置全局参数 */git config --global user.name "username" ...

  2. Phantomjs 抓取、分析某个页面加载时浏览器发起的所有的子请求

    var page = require('webpage').create(), system = require('system'), address; if (system.args.length ...

  3. 006使用Grafana展示时间序列数据

    简介 Grafana是一个独立运行的系统,内置了Web服务器.它可以基于仪表盘的方式来展示.分析时间序列数据. Grafana支持多种数据源,例如:Graphite.OpenTSDB.InfluxDB ...

  4. Linux umount的device is busy问题

    现象: [root@dbserver ~]# df -h文件系统 容量 已用 可用 已用%% 挂载点/dev/vda1 9.9G 3.9G 5.6G 41% /tmpfs 3.9G 100K 3.9G ...

  5. 二、vue中组件的使用

    1.组件拆分 1.组件实质上也是一个vue实例,因此组件中也可以使用vue的对象属性,反过来每一个vue实例也是一个vue组件(注:1.唯一不同的是el是根实例的特有选项,2.组件中的data必须是一 ...

  6. 小白学习安全测试(四)——扫描工具-Vega

    WEB扫描工具-Vega 纯图形化界面,Java编写的开源web扫描器.两种工作模式:扫描模式和代理模式[主流扫描功能].用于爬站.处理表单,注入测试等.支持SSL:http://vega/ca.cr ...

  7. C++ Primer读书笔记(3)

    vector: 本科时学C++的时候没学过vector,正好补一下. 第一个要注意的地方是要正确区分列表初始值还是元素数量. 第二点是不能使用范围for向vector对象添加元素,范围for语句体内不 ...

  8. yum安装tomcat

    http://www.cnblogs.com/liaolongjun/p/5638740.html http://www.awspack.com/os/linux/yum-install-tomcat ...

  9. 第三届CCF软件能力认证

    1.门禁系统 问题描述 涛涛最近要负责图书馆的管理工作,需要记录下每天读者的到访情况.每位读者有一个编号,每条记录用读者的编号来表示.给出读者的来访记录,请问每一条记录中的读者是第几次出现. 输入格式 ...

  10. 关于gitignore无效的一些记录

    git 远程上已经有了 .idea *.iml文件 拉到本地之后,添加.gitignore 此时由于远程有了这些文件,所以.gitignore无法忽略这些文件了 挽救做法: 思路是在本地的git缓存中 ...