c 壞的程式設計習慣

2022-03-10 03:12:40 字數 3545 閱讀 5147

摘自:

1、在c#程式設計中,字元型型別是最容易處理出錯的地方,代價是非常昂貴,在.net framwork中,字串是乙個相當特別的引用型別,string本省就是乙個不可繼承的密封類,但是它具有了值型別所應用的特點,但是它在clr中內 存還是儲存於託管堆之上,也就是說,當我們每次定義乙個字串型別的時候,就在堆記憶體中開闢一端記憶體,而當我們字串被修改之後,它會建立乙個新的記憶體, 注意這裡的記憶體是不連續的,而是通過修改棧內位址引用而拼湊字串,不會改變源字串在記憶體中的位址,所以有些程式設計師總是喜歡使用這樣的方法格式化字元 串:

string

selecttext=

"select * from "

+tablename+

" where username='"

+name+

"'"; 

上述**,使用了字串拼湊的方法,因為使用了多重串聯,因此會在記憶體中建立兩個不必要的字串垃圾副本。

其實在c#中,已經為我們提供了stringbuilder和string.fromat來解決此問題,雖然他們可以實現同樣的功能,但是他們有質 的變化,stringbuilder在記憶體中開闢的是一段連續記憶體,當增加新字串時候,它會在棧中指向的同乙個堆記憶體中連續存放字元,這就形成了效能的 提公升。所以我們將上面**改成:

string

selecttext=

string

.format(

"select  *  from  where username="

,tablename,name); 

2、大多數開發人員都不知道內建的驗證資料型別的方法,如system.int32,因此很多人都是自己實現的,其實這是不妥的,因為這些基本型別中都存在自己固有的型別驗證方法,下面這個就是自己實現驗證的乙個字串是否是數值的**:

public

bool

checkifnumeric(

string

value)  

catch

(formatexception excepiton)  

return

isnumeric;  

} 雖然使用了try catch語句,這不是最佳的做法,更好的方法是下面使用int.tryparse;

intoutput=0;  

bool

isnumeric=

int.tryparse(value,

outoutput); 

int.tryparse是更快、更簡潔的方法。

3、自己利用idisposable介面手動釋放記憶體

在.net framework中,物件的處理和使用一樣重要,理想的方法是在使用完物件的時候,在類中實現idisposable介面中的dispose方法進行內 存的釋放,當然在.net本身提供的垃圾**機制(gc)中就提供了這樣的功能,在我們例項化類物件時,在類本身的析構函式中會呼叫dispose方 法,gc在各級記憶體堆滿的情況下,自動檢查物件使用情況,去相應的釋放記憶體,但是執行在非託管平台上的方法,需要我們自己手動釋放記憶體,比如我們常見的 sqlconnection物件,也就有了下面的建立、使用和處理方法:

public

void

dalonemethod()  

catch

(exception exception)  

finally

} 上述**是大部分程式設計師會出現的**,乍看沒啥問題,連線處理在最後乙個**中被明確呼叫,但是如果發生了乙個異常,catch**塊就被執行,然 後再執行最後乙個**塊處理連線,因此在最後乙個**塊執行之前,連線將一直留在記憶體中,大部分我們會在此處記錄錯誤,一般涉及到io操作,如果延時時間 比較長的話,這個連線將在記憶體時間長時間停留。我們乙個原則就是當物件不再使用的時候我們裡面釋放資源。

我們採用程式邏輯域來處理這個問題會更好:

public

void

dalonemethod()  

} 當使用using**快時,物件上的dispose()方法將在執行推出邏輯域的時候呼叫,這樣就保證了sqlconnection的資源處理被盡 早釋放,當然這個方法也適用於實現idisposable介面的類,當時個人不推薦這樣做,在非常有把握的情況下可以手動釋放,但是沒把握還是叫 給.net系統釋放,因為本身類的析構函式就實現這個方法,當我們自己重寫後,反而會導致系統誤以為你自己定義了方法,而推遲釋放資源,有興趣可以研究下 gc執行本質,假如能在第一代被釋放的記憶體,如果我們重寫dispose方法反而推遲到第二代記憶體堆中釋放,顯然是不可取的。

4、學會合理的管理公共變數,我們在系統中經常會濫用公共變數,沒有做到合適的封裝好。

static

void

main(

string

args)  

public

class

myaccount  

} 在上面的myaccount類中生命了乙個accountnumber公共變數,理想情況下,accountnumber應該是唯讀的,不能讓外界修改,但是這裡myaccount類卻沒有對它做任何控制。

宣告公共做法應該是使用屬性,如:

public

class

myaccount  

}  public

myaccount()  

} 這裡我們封裝了accountnumber公共變數,它變成了唯讀,不能由呼叫者類進行修改。

5、巢狀的異常處理,有的開發人員喜歡在方法末尾加上處理的巢狀方法,如

public

class

nestedexceptionhandling  

catch

(exception exception)  

}  private

void

childmethod1()  

catch

(exception exception)  

}  private

void

childmethod2()  

catch

(exception exception)  

}  } 如果相同的異常被處理多次,效能開銷將會增加。

我們的解決方法是讓異常處理方法獨立開來,如:

public

class

nestedexceptionhandling  

catch

(exception exception)  

}  private

void

childmethod1()  

private

void

childmethod2()  

} 6、大資料量上使用dataset和datareader混用,當單錶資料量很大的情況,使用dataset是一種很不明智的選擇,應為 dataset是以datatable記憶體形式存放資料量,一次性將資料拖入記憶體,當資料很大的情況下,這種方式是很吃記憶體的,相比 dataser,datareader就顯得優雅很多,它是每次讀取一條資料,然後輪詢呼叫機制,但是也有它的弊端,就是相對長連線,但是對記憶體消耗而言 這是有利的,當然dataset在大部分應用場景下也是有自己的優點,充分解耦、一次性操作、領域模型操作等方面,兩者分情況分場景而用,這裡只是稍微提 提,根據場景分析區別。

C 程式設計習慣

1 初始化列表,盡量使用。2 函式是否加const,只用而不改變就推薦加上const。如自定義的get某個屬性的函式。3 函式引數盡量用引用傳遞,返回值也優先考慮引用型別 引用必須保證在使用前,本體不能消失。所以返回值是區域性變數,就不可以用引用型別,出了大括號,本體就消亡了 函式引數如果只拿來使用...

C 新手程式設計習慣

習慣應該從新手養成 在以後將會受益匪淺 程式設計要有命名規則 使變數名看起來簡單明瞭 便於閱讀修改 程式設計風格要注意排版,縮排和注釋 例如 適當的縮排,每個花括號佔一行,bin並與使用花括號的語句對其。注釋在程式設計中同時進行,不要期望程式開發完成後再補寫注釋。必要的注釋內容應包括 源程式總體注釋...

C 程式設計好習慣

1.不要在建構函式中做初始化操作 要求類 尤其是對外介面類 提供init 函式,在該函式中進行相關初始化操作,初始化失敗能夠返回錯誤碼。可以規避問題 建構函式中難以返回錯誤碼,外部呼叫者無從判斷初始化結果。當該類作為全域性變數使用時,構造函式呼叫發生在main 函式執行之前,出現問題難以追蹤。2.所...