zoukankan      html  css  js  c++  java
  • 将switch case转为条件驱动

    switch case是一种.net里面常用的条件分支语句,挺好用的;不过有些缺点:

    1.在有包含大量条件和执行语句的时候代码结构会很乱。

    2.不太符合面对对象的设计原则。

    3.对于查询条件是否满足一定范围这样的逻辑不太好用。
     

    将其转为条件驱动的实现,(本例使用Dictionary+Delegate的方式)

    View Code
        class SwitchTest
    {
    /// <summary>
    /// 常规写法
    /// </summary>
    /// <param name="type"></param>
    public static void Test(EnumType type)
    {
    switch (type)
    {
    case EnumType.A:
    break;
    case EnumType.B:
    break;
    case EnumType.C:
    break;
    case EnumType.D:
    break;
    case EnumType.E:
    break;
    case EnumType.F:
    break;
    case EnumType.G:
    break;
    case EnumType.H:
    break;
    case EnumType.I:
    break;
    case EnumType.J:
    break;
    case EnumType.K:
    break;
    default:
    break;
    }
    }


    #region 下面所有的代码是另一种实现方法. 关键是handlers的初始化
    static Dictionary<EnumType, Action<object>> handlers = new Dictionary<EnumType, Action<object>>();
    static SwitchTest()
    {
    var methods = typeof(SwitchTest).GetMethods();
    var fields = Enum.GetNames(typeof(EnumType)).ToList();
    foreach (var item in methods)
    {
    if (item.Name.StartsWith("Handle"))
    {
    var commandTypeName = item.Name.Substring(6, item.Name.Length - 6);
    if (fields.Contains(commandTypeName))
    {
    EnumType type = (EnumType)Enum.Parse(typeof(EnumType), commandTypeName);
    handlers[type] = (Action<object>)Delegate.CreateDelegate(typeof(Action<object>), item);
    }
    }
    }

    //也可以通过下面的代码,初始化Dictionary
    //handlers[EnumType.A] = new Action<object>(HandleA);
    //handlers[EnumType.B] = new Action<object>(HandleB);
    //handlers[EnumType.C] = new Action<object>(HandleC);
    // ....

    //当然 也可以通过其他逻辑初始化Dictionary
    }

    /// <summary>
    /// 使用Dictionary 加上 Delegate的写法
    /// </summary>
    /// <param name="enumType"></param>
    internal static void Test2(EnumType enumType)
    {
    //如果要设计为可以处理一定范围的逻辑, 可以在这里添加一个方法处理输入值,例如1-20的值都认为是处理逻辑A

    if (handlers.ContainsKey(enumType))
    {
    handlers[enumType](null);
    }
    else
    {
    //默认处理逻辑
    }
    }

    public static void HandleA(object obj)
    {
    }
    public static void HandleB(object obj)
    {
    }
    public static void HandleC(object obj)
    {
    }
    public static void HandleD(object obj)
    {
    }
    public static void HandleE(object obj)
    {
    }
    public static void HandleF(object obj)
    {
    }
    public static void HandleG(object obj)
    {
    }
    public static void HandleH(object obj)
    {
    }
    public static void HandleI(object obj)
    {
    }
    public static void HandleJ(object obj)
    {
    }

    #endregion
    }

    /// <summary>
    /// 用于演示的枚举类型
    /// </summary>
    public enum EnumType
    {
    A = 1,
    B = 2,
    C = 3,
    D = 4,
    E = 5,
    F = 6,
    G = 7,
    H = 8,
    I = 9,
    J = 10,
    K = 11,
    }

    1.常用的委托有Action<T> 和 Func<T>

    2.也可以自己定义委托以支持任意方法

    3.可以传递Delegate的方式实现更为复杂的多重逻辑

    4.毫无疑问,在简单的情况下不是很使适用条件驱动这样相对复杂的方案
     

    关于性能问题:

                //准备数据
    Random random = new Random();
    int length = 1000000;
    EnumType[] testData = new EnumType[length];
    for (int i = 0; i < length; i++)
    {
    testData[i] = (EnumType)Enum.Parse(typeof(EnumType), random.Next(1, 11).ToString());
    }

    Stopwatch sw = new Stopwatch();
    sw.Start();
    for (int i = 0; i < testData.Length; i++)
    {
    SwitchTest.Test(testData[i]);
    }
    sw.Stop();
    Console.WriteLine(sw.ElapsedMilliseconds);//13 执行100万次


    sw.Restart();
    for (int i = 0; i < testData.Length; i++)
    {
    SwitchTest.Test2(testData[i]);
    }
    sw.Stop();
    Console.WriteLine(sw.ElapsedMilliseconds);//62 执行100万次

    执行10万次分别消耗9毫秒 和7毫秒,

    执行100万次分别消耗13毫秒 和62毫秒,

    (可能有点误差,不过这样小的消耗主要是为了表明其实两种写法的性能权重都不高)

    好久之前的东西了。。。最近正好又遇到,就记录在blog中,顺便看看有没有什么可以优化的地方

  • 相关阅读:
    Linux入门-ssh scp rsync
    Linux入门-samba
    Linux入门-vsftp
    Linux入门-nfs
    MySQL卸载(rpm)
    rust_3_所有权
    rust_1_入门指南与猜猜看游戏
    vscode首次ssh remote linux连不上
    vbox新装ubuntu虚拟机注意事项
    IBM Rational Rose和Start UML的c++逆向工程自动生成UML类图组件
  • 原文地址:https://www.cnblogs.com/PurpleTide/p/2275552.html
Copyright © 2011-2022 走看看