干掉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

原文地址:https://www.cnblogs.com/poissonnotes/p/1769227.html