注:本博文面向初學者。 前兩天幫QQ羣中的一個同窗遠程解決一個問題,這個同窗聽說本身折騰了一天都沒搞定,給他結果之後感想很是多,今天有時間把這個問題以及背後隱藏的問題分享給你們。 下面說的吃異常的錯誤不只初學者會犯,不少工做不少年的人也常常會犯這種錯誤,所以雖然在不少人看起來很簡單,我仍是在這裏羅嗦了,但願對有的人有幫助。 這位同窗說他寫的程序老是報錯說字段ParentId沒找到,可是數據庫中是有代碼的。他是經過SQLHelper得到一個DataTable,而後把DataTable展現到ListView中進行數據展現的。示例性代碼以下: DataSet ds = SQLHelper.ExecuteDataSet("select * from T_Persons"); listview1.DataSource = ds; listview1.FilterExpression = "ParentId=3"; 其實他的這個程序是有很大缺陷的,由於他是在UI層中進行數據過濾的,這個問題暫且不提。 主要問題是,T_Persons表中是有ParentId這個字段的,可是老是報異常「沒有ParentId字段」。 一直讓他很費解,所以我就猜想程序中有被吃掉的異常,所以我在VisualStudio中打開異常檢測,打開主菜單→調試→異常,將Common Language Runtime Exception勾選上,這樣就表示對於捕獲的異常也Break,這樣就能夠發現被吃掉的異常了。 程序運行,果真在SQLHelper.ExecuteDataSet調用SqlConnection環節中看到異常拋出了,是「數據庫鏈接失敗」,示例性代碼以下: DataSet ds = new DataSet(); try { SqlConnection conn = new SqlConnection(.........); //... adapter.Fill(ds); } catch { } return ds; 原來是他的鏈接字符串寫錯了。因爲他想「耳根子清淨」,就可恥的把異常給吃掉了,這樣雖然數據庫根本就沒鏈接上,ExecuteDataSet方法仍然好像啥事都沒發生同樣假模假樣的返回一個空的DataSet,因爲這個DataSet什麼表結構都沒有,最後報異常「沒有ParentId字段」也就不足爲奇。 異常就是一種程序中沒有預料到的問題,既然屬於沒有預料到的,就不該該不想看異常就把全部異常catch吃掉,原本ExecuteDataSet執行數據庫操做已經失敗了,後續的代碼也就沒有意義了,不該該繼續執行了,應該讓用戶或者開發人員知道「這裏出錯了」,而不是繼續掩耳盜鈴的執行下去,不然很容易形成程序進入一個邏輯混亂的狀態,出現各類奇怪的問題。 異常也就是意外,是沒有預料到的狀況,既然是意外,通常狀況不須要開發人員去處理。異常了就異常了,沒什麼大不了的,異常了反而容易發現程序中的錯誤。對於有的狀況確實須要catch異常的地方,只要不是處理後從新拋出,也最好將異常經過Log4Net等日誌工具記錄下來,方便開發人員排查問題。 有人說程序一旦出現異常多難看呀?「客戶看到一堆異常的英文界面就發怒,仍是吃了好呀」,其實不要吃異常和不讓用戶看到「一堆異常的英文界面」並不衝突,好比在ASP.Net中就能夠經過定製錯誤頁的方式來解決,將錯誤頁顯示的模式設置爲「RemoteOnly」,這樣普通用戶看的是定製後的沒有「一堆異常的英文界面」的頁面,而對於開發人員和系統管理員看到的則仍是異常頁面,「兩不耽誤」! 「不要吃異常」、「不要使用魔法數」、「資源最好用using進行管理」等這些很是常見的好的編程習慣是最容易被初學者忽略的,最終不遵照好習慣而自作自受的例子也家常便飯,建議你們要認真遵照這些基本的原則,最終受益的仍然是本身。 |