這兩天新的專案設計工作快完畢了,我要出乙份新專案中的異常書寫規則.在msdn上查詢了些資料,發現裡面很多都是程式設計師常犯的錯誤.總結出來,希望對大家有所提高.
異常引發準則:
不要返回錯誤**。異常是報告框架中的錯誤的主要手段。
通過引發異常來報告執行故障。如果某一成員無法按預期方式成功執行,則應將這種情況視為乙個執行故障並引發乙個異常。
如果**遇到繼續執行則不安全的情況,應考慮通過呼叫 system.environment.failfast(system.string)(.net framework 2.0 中的一種功能)來終止程序,而不是引發異常。
盡可能不對正常控制流使用異常。除了系統故障及可能導致爭用狀態的操作之外,框架設計人員還應設計一些 api 以便使用者可以編寫不引發異常的**。例如,可以提供一種在呼叫成員之前檢查前提條件的方法,以便使用者可以編寫不引發異常的**。
考慮引發異常的效能影響。
記錄公共可呼叫的成員因成員協定衝突(而不是系統故障)而引發的所有異常,並將這些異常視為協定的一部分。包含在協定中的異常不應從乙個版本更改到下乙個版本。
不要包含可以根據某一選項引發或不引發異常的公共成員。
例如,不要定義如下所示的成員:
uri parseuri(string urivalue, bool throwonerror)
不要包含將異常作為返回值或輸出引數返回的公共成員。
不要從異常篩選器塊中引發異常。當異常篩選器引發異常時,公共語言執行庫 (clr) 將捕獲該異常,然後該篩選器返回 false。此行為與篩選器顯式執行和返回 false 的行為無法區分,因此很難除錯。
避免從 finally 塊中顯式引發異常。可以接受因呼叫引發異常的方法而隱式引發的異常。
異常處理準則:
不要在框架**中捕捉非特定異常(如 system.exception、system.systemexception 等)以至忽略錯誤。
下面的**示例演示的異常處理是不正確的。
public class badexceptionhandlingexample1
public void methodwithbadhandler()
catch (exception e)
} }
避免在應用程式**中捕捉非特定異常(如 system.exception、system.systemexception 等)以至忽略錯誤。某些情況下,可以在應用程式中忽略錯誤,但這種情況極少。
如果捕捉異常是為了傳輸異常,則不要排除任何特殊異常。
下面的**示例演示對以再次引發為目的特殊異常進行的不正確測試。
public class badexceptionhandlingexample2
public void methodwithbadhandler()
catch (exception e)}}
如果了解特定異常在給定上下文中引發的條件,請考慮捕捉這些異常。
不要過多使用 catch。通常應允許異常在呼叫堆疊中往上傳播。
使用 try-finally 並避免將 try-catch 用於清理**。在書寫規範的異常**中,try-finally 比 try-catch 使用得更多。
捕捉並再次引發異常時,首選使用空引發。這是保留異常呼叫堆疊的最佳方式。
下面的**示例演示乙個可引發異常的方法。
public void dowork(object anobject)
// do work with o.
}下面的**示例演示捕捉乙個異常,並在再次引發該異常時對它進行錯誤的指定。這會使堆疊跟蹤指向再次引發作為錯誤位置,而不是指向
dowork
方法。
public void methodwithbadcatch(object anobject)
catch (argumentnullexception e)
} 不要使用無引數 catch 塊來處理不符合 cls 的異常(不是從 system.exception 派生的異常)。支援不是從 exception 派生的異常的語言可以處理這些不符合 cls 的異常。
捕捉和引發標準異常型別:
exception 和 systemexception
不要引發 system.exception 或 system.systemexception。
不要在框架**中捕捉 system.exception 或 system.systemexception,除非打算再次引發。
避免捕捉 system.exception 或 system.systemexception,在頂級異常處理程式中除外。
invalidoperationexception
如果處於不適當的狀態,則引發 system.invalidoperationexception 異常。如果沒有向屬性集或方法呼叫提供適當的物件當前狀態,則應引發 system.invalidoperationexception。
例如,向已開啟用於讀取的 system.io.filestream 寫入時,應引發 system.invalidoperationexception 異常。
argumentexception、argumentnullexception 和 argumentoutofrangeexception
如果向成員傳遞了錯誤的引數,則引發 system.argumentexception 或其子型別之一。如果適用,首選派生程度最高的異常型別。
在引發 system.argumentexception 或其派生型別之一時,設定 system.argumentexception.paramname 屬性。此屬性儲存導致引發異常的引數的名稱。注意,使用其中乙個建構函式過載可以設定該屬性。
使用屬性 setter 的隱式值引數的名稱的值。
不要允許公開可呼叫的 api 顯式或隱式引發 system.nullreferenceexception、system.accessviolationexception、system.invalidcastexception 或 system.indexoutofrangeexception。進行引數檢查以避免引發這些異常。引發這些異常會公開方法的實現細節,這些細節可能會隨時間發生更改。
stackoverflowexception
不要顯式引發 system.stackoverflowexception。此異常只應由公共語言執行庫 (clr) 顯式引發。
不要捕捉 system.stackoverflowexception。
以程式設計方式處理堆疊溢位極為困難。應允許此異常終止程序並使用除錯確定問題的根源。
outofmemoryexception
不要顯式引發 system.outofmemoryexception。此異常只應由 clr 基礎結構引發。
comexception 和 sehexception
不要顯式引發 system.runtime.interopservices.comexception 或 system.runtime.interopservices.sehexception。這些異常只應由 clr 基礎結構引發。
不要顯式捕捉 system.runtime.interopservices.sehexception。
executionengineexception
不要顯式引發 system.executionengineexception。
設計自定義異常:
避免使用深的異常層次結構。
一定要從 system.exception 或其他常見基本異常之一派生異常。
異常類名稱一定要以後綴 exception 結尾。
應使異常可序列化。異常必須可序列化才能跨越應用程式域和遠端處理邊界正確工作。
一定要在所有異常上都提供(至少是這樣)下列常見建構函式。請確保引數的名稱和型別與使用者相同
.**如下:
public class newexception : baseexception, iserializable
public newexception(string message)
public newexception(string message, exception inner)
// this constructor is needed for serialization.
protected newexception(serializationinfo info, streamingcontext context)
} 一定要只在要求適合的許可權後,才通過 system.object.tostring 的重寫報告安全敏感資訊。如果許可權要求失敗,則返回乙個不包括安全敏感資訊的字串。
一定要以私有異常狀態儲存有用的安全敏感資訊。請確保只有受信任的**才能獲取該資訊。
考慮提供異常屬性,以便可以以程式設計方式訪問除訊息字串之外與異常相關的額外資訊。
異常和效能:
不要由於擔心異常可能會對效能造成不良影響而使用錯誤**。
對於可能在常見方案中引發異常的成員,可以考慮使用 tester-doer 模式來避免與異常相關的效能問題。
doer的**如下:
public class doer
} // other methods... }
tester**如下:
public class tester
} } }
對於可能在常見方案中引發異常的成員,可以考慮使用 tryparse 模式來避免與異常相關的效能問題。
**如下:
int i = 0;
int j = 0;
bool ispre1 = int32.tryparse("30",out i);
bool ispre2 = int32.tryparse("12s",out j);
//執行之後i = 30 , j = 0 ; ispre1 = true, ispre2 = false;
為每個使用 tryparse 模式的成員提供乙個引發異常的成員。
專案中的一些認識和總結
在隨著專案經驗的積累可以體會到很多在書本上難以理解的知識,認識其中的重要性。1 在專案編碼之前,一定要對功能有足夠的認識,比如所涉及的介面,表,類,輸入輸出等。2 編碼的規範。類,類方法 特別是介面方法 資料庫表名等要在編碼之前有統一的規範。可以方便閱讀,還有spring 中對事務管理。3 就是常在...
關於dlopen在專案中的一些坑
關於dlopen在專案中的一些坑 前提背景 我們的專案中是10多年的迭代 裡面有載入很多dll lib在專案中。今天在專案中在解決乙個bug的時候,通過除錯 發現了dlopen dlclose等linux中的api函式給坑了。源於我在vs2010除錯 的時候,是針對debug版本的 進行修改除錯,當...
springboot專案中的異常處理
1.首先自定義異常類繼承runtimeexception類,以notfoundexception為例 使用messageformat.format 方法做資訊和可變參的處理。public class notfoundexception extends runtimeexception 2.定義全域性...