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);
 

点击下载免费的敏捷开发教材:《火星人敏捷开发手册

posted @ 2011-04-27 10:52  Java EE  阅读(228)  评论(0编辑  收藏  举报