C#编码简单性之语义篇(如何编写简短的C#代码,随时更新)

 

以前写C++的时候曾经在自己网站上发表过一个编码“简单性”之文章,现在编写C#了才发现自己无意之间就会写下一些浪费屏幕的代码。
下面是自己编码中偶然发现的一些案例,欢迎中等水平的编程者参考。因为要积累案例,所以随时更新。

--------------------------------------------------------------------------------
从语义角度看编码简单性的“心法”就是:只要屏幕上有需要思量一下的代码,则一定有办法简化。
所谓语义,就是“用人的思维理解的代码的含义”。机器很容易懂a = b + c /3 * 2 ^3.14,但人就要想想这到底是想干什么。尤其如果新手写的程序,老手居然看不懂,那就是语义出了问题。

--------------------------------------------------------------------------------
案例1
这个是我一位朋友在研究生开卷考试中遇到的:编写一个函数求三个整数中的最大值。
因为当时刚学C++,所以他的答案可以变成另外一道题:这个函数的目的是什么?(如果不看函数名)
原来是:
public int Max(int a, int b, int c)
{
if (a > b)
{
if (a > c)
return a;
else
return c;
}
else
{
if (b > c) //有人还能把这里写成 c < b,也对,但更乱
return b;
else
return c;
}
}
 
正解是:
public int Max(int a, int b, int c)
{
return Max(Max(a, b), c);
}
public int Max(int a, int b)
{
return (a > b) ? a : b;
}
 
后者并没有节省多少代码,但却更容易理解,中真正亮点其实是Max(Max(a, b), c)中的两个Max,很好地用人类语言解释了自己想干什么。
案例2
01年做IC卡的时候遇到的一个:“卡号0X9999的顾客加入了卡组0X1234”原代码:
“蛮力”编码:
char cmd[46];
cmd[0]=0x04;
cmd[1]=0xF0;
cmd[2]=0x3C;
cmd[13]=0x99;
cmd[14]=0x99;
cmd[21]=0x12;
cmd[22]=0x34;
cmd[45]=0x00;
后来变成:
char *cmd=“04F03C……9999……1234……00”
当然要处理一下才能给卡片读取。
这个符合做IC卡的人的习惯(他们喜欢暴露的人能阅读的指令),但不符合编VC++的人的喜欢,所以后来有了:
AddICtoCG(9999, 1234)
以及符合测试人员的纯TXT伪码:
IC9999 CG1234
乃至伪码群:
nIC11 CG21 PG12 P140
n CG34 PG22 P143
n CG45 P23
n PG13 P121
这些简化工作花费了大约1周的时间(包括一个将伪码群编辑器,以及将分解为单条指令发送给IC卡的软件),但后来的工作因此变得非常简单。
案例3
同期的工作,生成或解析授权码流。原代码:
szData[0] = szData[0] & (0xFF - 0x03) + nType & 0x03;
……以下省略大约1000行
非常疯狂的一段代码,但却由一位非常丰富经验的程序员写成(他是我们在1.5年里筛选4000份简历后找到的最好的前5个人之一,他后来解释说想先调试通过了,再封装。所以老虎也有打盹的时候啊),结果是2个月的工作被完全放弃。
2周后变成:
新代码大约有400行,其中CPack 和CKit的加起来是110行,开发时间是原来的1/4。
改好这段代码后,我们定了个制度:所有代码完成后均必须交由上级经理检查后方可进入代码库。这个工作的工作量庞大,但公司之后若干年上市了,市场占有率为国内的60%。6年后聚会的时候提到了我原来编写的7个模块,很高兴地知道其中5个还在使用和维护,因为整体上它们都很短小简单易于后继者理解。
总结一下就是代码整体上是写给人看的而不是写给机器看的,不能以编译通过来作为判断标准。
从语义的角度理解代码简单性,就是无论代码长短,放眼望去就知道在干什么,就是简单的代码。
nCPack Pack(szData);
nPack << CKit(nType, 3) //程序说:我要把码流的Type占3bit放进码流去。
n << CKit(nLength, 4) //程序说:我要把码流长度占4bit放进码流去。
n << CKit(bReserved, 1) //程序说:为了对齐字节,跳过一位吧。
n << CKit(nCode, 16)
n……
n << CKit(dwCRC, 32);

本文转自火星人陈勇 51CTO博客,原文链接:http://blog.51cto.com/cheny/1100072

上一篇:Base64编解码(C++版)


下一篇:Windows Phone 下开发 LBS 应用