zoukankan      html  css  js  c++  java
  • 干掉switch语句

    goto,可以说是程序界,名声最差的关键字之一了。有人强烈要求,在高级语言中,应该被和谐掉。
    如果,你在满是高级业务逻辑的代码里,写上些goto,就好比,你在代码里,嵌了些汇编语言(goto应该待它自己的世界).
    其实,我们常用的switch语句中,goto也若隐若现。请参考MSDN关于switch的说明文档

    现在,我分析一下,我们为啥要用switch语句:

    先从一个简单的例子入手:

    [Test(Description="switch可以被if等价代替")]
    public void T1()
    {
    int x = 6;

    //if语句
    if (x % 2 == 0)
    {
    Console.WriteLine(
    "偶数");
    }
    else if (x % 2 == 1)
    {
    Console.WriteLine(
    "奇数");
    }
    else
    {
    Console.WriteLine(
    "未知数");
    }

    //等价的switch语句
    switch (x % 2)
    {
    case 0: Console.WriteLine("偶数"); break;
    case 1: Console.WriteLine("奇数"); break;
    default: Console.WriteLine("未知数");
    break;
    }
    }


    可以看出,ifswitch几乎没啥区别,纯属个人爱好!

    再举个例子:

    [Test(Description="可能用到switch的地方")]
    public void T2()
    {
    int x = 6;

    //if语句分支太多!
    if (x == 0)
    {
    Console.WriteLine(
    "x=0");
    }
    else if (x == 1 || x == 2 || x == 3 || x == 4)
    {
    Console.WriteLine(
    "0<x<5");
    }
    else if (x == 5)
    {
    Console.WriteLine(
    "x=5");
    }
    else if (x == 6 || x == 7 || x == 8 || x == 9)
    {
    Console.WriteLine(
    "5<x<10");
    }
    else
    {
    Console.WriteLine(
    "x<0 or x>9");
    }

    //用switch语句更清晰?
    switch (x)
    {
    case 0: Console.WriteLine("x=0"); break;
    case 1:
    case 2:
    case 3:
    case 4: Console.WriteLine("0<x<5"); break;
    case 5: Console.WriteLine("x=5"); break;
    case 6:
    case 7:
    case 8:
    case 9: Console.WriteLine("5<x<10"); break;
    default: Console.WriteLine("x<0 or x>9");
    break;
    }
    }


    可以看出,遇到这种情况,switch看起来还不错!

    现在,我想用用switch的"高级"功能:

    [Test(Description="可以作为糟糕的笔试题")]
    public void T3()
    {
    int x = 6;

    switch (x)
    {
    case 0: Console.WriteLine("x=0"); goto case 0;//while(true)!!!
    case 1:
    case 2:
    case 3:
    case 4: Console.WriteLine("0<x<5"); goto default;
    case 5: Console.WriteLine("x=5"); break;
    case 6:
    case 7:
    case 8:
    case 9: Console.WriteLine("5<x<10"); goto case 1;
    default: Console.WriteLine("x<0 or x>9");
    break;
    }
    }


    你可以在30"之内,""出结果吗?

    我真正想说的是,除了if...else...switch外,我们仍然有选择的余地:

    [Test(Description="干掉switch语句")]
    public void T4()
    {
    //我用Dictionary来组织这些规则,可以自定义更高级的类
    var rules = new Dictionary<Predicate<int>, Action>
    {
    {x
    => x==0, ()=>Console.WriteLine("x=0")},
    {x
    => 0<x&&x<5, ()=>Console.WriteLine("0<x<5")},
    {x
    => x==5, ()=>Console.WriteLine("x=5")},
    {x
    => 5<x&&x<10, ()=>Console.WriteLine("5<x<10")},
    {x
    => x<0&&9<x, ()=>Console.WriteLine("x<0 or x>9")},
    {x
    => true, ()=>Console.WriteLine("默认")}
    };

    int y = 6;
    //找出所有满足要求的规则
    rules.Where(x => x.Key(y)).each(x => x.Value());
    //只找出一条满足要求的规则
    rules.First(x => x.Key(y)).Value();
    }


    Predicate/Action就解决了问题,感觉还好吗?


    在面向对象编程中,switch还涉及到很多重构,可以参考http://www.refactoring.com/catalog/index.html

    附录:

    代码
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using NUnit.Framework;

    namespace KSharp
    {
    [TestFixture]
    public class TestSwitch
    {
    [Test(Description
    ="switch可以被if代替")]
    public void T1()
    {
    int x = 6;

    //if语句
    if (x % 2 == 0)
    {
    Console.WriteLine(
    "偶数");
    }
    else if (x % 2 == 1)
    {
    Console.WriteLine(
    "奇数");
    }
    else
    {
    Console.WriteLine(
    "未知数");
    }

    //等价的switch语句
    switch (x % 2)
    {
    case 0: Console.WriteLine("偶数"); break;
    case 1: Console.WriteLine("奇数"); break;
    default: Console.WriteLine("未知数");
    break;
    }
    }

    [Test(Description
    ="可能用到switch的地方")]
    public void T2()
    {
    int x = 6;

    //if语句分支太多!
    if (x == 0)
    {
    Console.WriteLine(
    "x=0");
    }
    else if (x == 1 || x == 2 || x == 3 || x == 4)
    {
    Console.WriteLine(
    "0<x<5");
    }
    else if (x == 5)
    {
    Console.WriteLine(
    "x=5");
    }
    else if (x == 6 || x == 7 || x == 8 || x == 9)
    {
    Console.WriteLine(
    "5<x<10");
    }
    else
    {
    Console.WriteLine(
    "x<0 or x>9");
    }

    //用switch语句更清晰?
    switch (x)
    {
    case 0: Console.WriteLine("x=0"); break;
    case 1:
    case 2:
    case 3:
    case 4: Console.WriteLine("0<x<5"); break;
    case 5: Console.WriteLine("x=5"); break;
    case 6:
    case 7:
    case 8:
    case 9: Console.WriteLine("5<x<10"); break;
    default: Console.WriteLine("x<0 or x>9");
    break;
    }
    }

    [Test(Description
    ="可以作为笔试题")]
    public void T3()
    {
    int x = 6;

    switch (x)
    {
    case 0: Console.WriteLine("x=0"); goto case 0;//while(true)!!!
    case 1:
    case 2:
    case 3:
    case 4: Console.WriteLine("0<x<5"); goto default;
    case 5: Console.WriteLine("x=5"); break;
    case 6:
    case 7:
    case 8:
    case 9: Console.WriteLine("5<x<10"); goto case 1;
    default: Console.WriteLine("x<0 or x>9");
    break;
    }
    }

    [Test(Description
    ="干掉switch语句")]
    public void T4()
    {
    //我用Dictionary来组织这些规则,可以自定义更高级的类
    var rules = new Dictionary<Predicate<int>, Action>
    {
    {x
    => x==0, ()=>Console.WriteLine("x=0")},
    {x
    => 0<x&&x<5, ()=>Console.WriteLine("0<x<5")},
    {x
    => x==5, ()=>Console.WriteLine("x=5")},
    {x
    => 5<x&&x<10, ()=>Console.WriteLine("5<x<10")},
    {x
    => x<0&&9<x, ()=>Console.WriteLine("x<0 or x>9")},
    {x
    => true, ()=>Console.WriteLine("默认")}
    };

    int y = 6;
    //找出所有满足要求的规则
    rules.Where(x => x.Key(y)).each(x => x.Value());
    //只找出一条满足要求的规则
    rules.First(x => x.Key(y)).Value();
    }

    [Test]
    public void T5()
    {
    //TODO:实现一般的业务规则类,其中可包括优先级等
    }
    }
    }

     原文地址:http://www.cnblogs.com/k-sharp/archive/2010/07/01/1769125.html

  • 相关阅读:
    修改MFC标题栏上的图标
    【转】子窗口刷新父窗口的问题
    水晶报表添加引用
    【转】MetadataType的使用,MVC的Model层数据验证
    poj 1556 The Doors 线段相交判断+最短路
    poj 1269 Intersecting Lines 求直线交点 判断直线平行共线
    string 函数操作
    poj 1066 Treasure Hunt 线段相交判断
    poj 1410 Intersection 线段相交判断
    poj 3347 Kadj Squares 扩大数据化整数
  • 原文地址:https://www.cnblogs.com/poissonnotes/p/1769227.html
Copyright © 2011-2022 走看看