天天看點

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;

}

if (b > c) //有人還能把這裡寫成 c < b,也對,但更亂

return b;

正解是:

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