亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > C# > 正文

解析C#中斷言與異常的應用方式及異常處理的流程控制

2020-01-24 01:19:08
字體:
來源:轉載
供稿:網友

斷言與異常(Assertion Vs Exception)
在日常編程實踐中,斷言與異常的界限不是很明顯,這也使得它們常常沒有被正確的使用。我也在不斷的與這個模糊的怪獸搏斗,僅寫此文和大家分享一下我的個人看法。我想我們還可以從很多角度來區別斷言和異常的使用場景,歡迎大家的意見和建議。

異常的使用場景:用于捕獲外部的可能錯誤

斷言的使用場景:用于捕獲內部的不可能錯誤

我們可以先仔細分析一下我們在.net中已經存在的異常。

  • System.IO.FileLoadException
  • SqlException
  • IOException
  • ServerException

首先,我們先不將它們看成異常,因為我們現在還沒有在異常和斷言之間劃清界限,我們先將它們看成錯誤。

當我們在編碼的第一現場考慮到可能會出現文件加載的錯誤或者服務器錯誤后,我們的第一直覺是這不是我們代碼的問題,這是我們代碼之外的問題。

例如下面這段代碼

public void WriteSnapShot(string fileName, IEnumerable<DbItem> items)    {      string format = "{0}/t{1}/t{2}/t{3}/t{4}/t{5}";      using (FileStream fs = new FileStream(fileName, FileMode.Create))      {        using (StreamWriter sw = new StreamWriter(fs, Encoding.Unicode))        {           ...          foreach (var item in items)          {            sw.WriteLine(string.Format(format, new object[]{              item.dealMan,              item.version,              item.priority,              item.bugStatus,              item.bugNum,              item.description}));          }          sw.Flush();        }      }    }

上面的代碼在寫入文件,很顯然會導致IOException。稍微有經驗的程序員都會考慮到IO上可能出問題,那我們應該如何處理這個問題呢?在這個上下文中,我們別無它法,只能讓這個錯誤繼續往上拋,通知上面一層的調用者,有一個錯誤發生了,至于上一層調用者會如何處理,不是這個函數要考慮的問題。但在這個函數中,要記得一點,將當前函數中所占用的資源釋放了。因此,當我們不能控制的外部錯誤出現時,我們可以將其作為異常往上拋,這時,我們該使用異常。

現在再來看看斷言,我們還是以下面的一段代碼為例子。

public Entities.SimpleBugInfo GetSimpleBugInfo(string bugNum)    {      var selector = DependencyFactory.Resolve<ISelector>();      var list = selector.Return<Entities.SimpleBugInfo>(        reader => new Entities.SimpleBugInfo        {          bugNum = reader["bugNum"].ToString(),          dealMan = reader["dealMan"].ToString(),          description = reader["description"].ToString(),          size = Convert.ToInt32(reader["size"]),          fired = Convert.ToInt32(reader["fired"]),        },        "select * from bugInfo",        new WhereClause(bugNum, "bugNum"));      Trace.Assert(list != null);            if (list.Count == 0)        return null;      else        return list[0];    }

當我貼出這段代碼時,心情有些坎坷,因為我本人在這里也糾結了很久,這也是我一直沒有將斷言和異常劃清界線的原因之一。

首先我們來回顧一下之前定義的斷言使用場景:內部不可能發生的錯誤。

selector.Return這段代碼是不是內部代碼?如果我們能夠修改Return中的代碼,說明它是內部代碼;反之,說明它是外部代碼。對于內部代碼,我們可以用斷言來保護其邏輯的不變性,當斷言被觸發時,我們就可以確信是內部代碼的錯誤,我們應該立即修復。

再糾結一下,假設Return是外部代碼,我們沒有辦法去修改它。那么上面的代碼可以有兩種寫法(如果你有更多的想法,請賜教)。

第一種,直接拋出異常。

If(list == null){  throw new NullReferenceException();}

第二種,調整代碼。

if(list == null || list.Count == 0){  return null;}else{  return list[0];}

當然,還有一種就是什么也不做,讓代碼執行下去直至系統為你拋出空引用錯誤。但這種做法違背了防卸性編程的原則,我們總是應行盡早或離錯誤的發生地最近的地方處理錯誤,避免錯誤數據流向系統的其它地方,產生更加嚴重的錯誤。

總結

對異?;驍嘌缘氖褂萌Q于你要防卸的是一個內部錯誤還是外部錯誤以及你認為它是一個內部錯誤或外部錯誤。如果你決定防卸一個內部錯誤,那請果斷使用斷言,反之,請使用異常。

異常處理
異常處理對于流程的控制,就像拋出與捕獲一樣分為兩個方面:

如果錯誤(或某種情況)發生,是否允許程序的控制流繼續執行下去(異常的拋出)
如果當前有異常發生,當前的代碼是否有機會讓程序的控制流進入到一個合理的狀態(異常的捕獲)
我認為可以用以上兩條,作為判斷異常處理的準繩。其實大家現在應該可以發現,這個所謂的準繩的著重點在于異常對于流程的影響,而不再是在什么情況下才使用異常。

對于流程控制,最直接的莫過于下面這段代碼

try          {            foreach (var lockGroup in lockGroups)            {               ...               foreach (var newlock in lockGroup.ToArray())              {                ...                if (diningBlocks.Exists(n => testLockRange.IsOverlapped(n.StartTime, n.EndTime)))                {                  status = LockStatus.InResourceBlock;                  throw new LockException();                }                 var diningAvail = availabilities.Find(n => n.Time == newlock.StartTime.TimeOfDay);                if (diningAvail == null)                {                  status = LockStatus.Failed;                  throw new LockException();                }                 ...                                 if (newLockQuantity > diningAvail.MaxAvail && !canOverrideLock.AllowOverBook)                {                  status = LockStatus.Override;                  throw new LockException();                }                else if (newLockQuantity + reservedQuantity + currentLockedAvail > diningAvail.MaxAvail && !canOverrideLock.AllowOverBook)                {                  status = LockStatus.Override;                  throw new LockException();                }                 ...              }            }          }          catch (LockException)          {            return new DiningLock[] { };          }

在上面的代碼中,有兩層for循環,當最內層出現某種情況時,要求停止整個for循環的執行,顯然用兩個break是不行的,還得加入一個輔助變量。

但是,如果用異常,這個處理就簡單多了??梢灾苯釉谧顑葘拥膾伋霎惓?,在最外層(或是流程控制需要的地方)捕獲異常。

在上面的代碼中,異常處理起到了流程控制的作用,而不僅僅傳遞錯誤信息,對代碼的簡化做出了貢獻。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
欧美另类精品xxxx孕妇| 欧美视频中文在线看| 精品性高朝久久久久久久| 97视频色精品| 伦伦影院午夜日韩欧美限制| 亚洲美女精品成人在线视频| 欧美性生交xxxxx久久久| 国产精品视频yy9099| 91网站在线免费观看| 精品久久久久国产| 日本免费久久高清视频| 美女国内精品自产拍在线播放| 精品久久久久久中文字幕| 精品国产一区二区三区久久久狼| 浅井舞香一区二区| 日韩精品在线视频美女| 国产成人在线一区二区| 欧美专区中文字幕| 91久久在线播放| 欧美精品手机在线| 日韩欧美在线免费| 亚洲色在线视频| 亚洲精品国产精品国产自| 国产精品777| 欧美猛男性生活免费| 国产精品扒开腿做爽爽爽视频| 欧美国产中文字幕| 日本在线观看天堂男亚洲| 欧美在线观看视频| 亚洲视频视频在线| 国产日韩欧美黄色| 成人福利网站在线观看11| 久久久久久久91| 91精品91久久久久久| 视频在线观看99| 日韩av理论片| 久久精品成人欧美大片古装| 成人h视频在线观看播放| 亚洲va欧美va国产综合久久| 日韩中文字幕在线播放| 国产美女精品免费电影| 精品亚洲永久免费精品| 欧美高清不卡在线| 一区二区日韩精品| 久久久电影免费观看完整版| 亚洲视频欧美视频| 欧美一级黄色网| 日本精品视频在线| 亚洲自拍中文字幕| 国产亚洲精品久久久| 日韩免费精品视频| 成人情趣片在线观看免费| 精品国内自产拍在线观看| 欧美成在线视频| 91国内产香蕉| 国产精品视频1区| 中文字幕无线精品亚洲乱码一区| 久久久久久久久久久免费精品| 视频在线一区二区| 黑人巨大精品欧美一区二区一视频| 成人乱色短篇合集| 91精品国产91久久久久久最新| 一区二区亚洲精品国产| 97成人超碰免| 欧美劲爆第一页| 国产成人精品免费视频| 欧美日韩中文字幕在线| 日韩有码片在线观看| 最新日韩中文字幕| 日韩中文有码在线视频| 久久夜色精品国产| 欧美日韩激情视频8区| 欧美激情欧美狂野欧美精品| www.日韩.com| 亚洲人成电影在线观看天堂色| 国产精品丝袜视频| 欧美一区二区色| 久久久99久久精品女同性| 成人做爰www免费看视频网站| 啪一啪鲁一鲁2019在线视频| 欧美午夜精品伦理| 欧美日韩国产一区中文午夜| 国产一区欧美二区三区| 国产成人精彩在线视频九色| 国产丝袜一区二区三区| 日韩欧美亚洲国产一区| 韩国视频理论视频久久| 国产91精品视频在线观看| 色婷婷**av毛片一区| 亚洲欧美在线一区| 久久久免费观看视频| 国产一区二区三区在线免费观看| 国产精品中文在线| 91社影院在线观看| 丰满岳妇乱一区二区三区| 日韩免费av片在线观看| 国内精品一区二区三区四区| 中文字幕亚洲欧美日韩在线不卡| 国产精品久久婷婷六月丁香| 国产亚洲精品久久久| 日韩av三级在线观看| 欧美日韩福利在线观看| 日韩精品视频三区| 欧美性极品xxxx娇小| 国产美女精彩久久| 91日韩在线视频| 国产精品高清网站| 亚洲一区二区三区在线免费观看| 亚洲毛片在线看| 亚洲欧美日韩一区二区三区在线| 国产精品自产拍在线观看中文| 成人黄色免费看| 日韩三级成人av网| 亚洲国产高潮在线观看| 久久久久亚洲精品国产| 久久久在线免费观看| 久久久精品国产| 欧美大尺度激情区在线播放| 国产97在线视频| 国产精品久久一| 日本免费久久高清视频| 国产成人avxxxxx在线看| 亚洲成人黄色在线| 亚洲国产精品人人爽夜夜爽| 日韩精品久久久久| 久久久免费av| 欧美在线性视频| 久久人人97超碰精品888| 国产精品扒开腿做爽爽爽视频| 欧美午夜视频在线观看| 自拍偷拍亚洲区| 日韩小视频在线观看| 国产精品a久久久久久| 国产精品网站大全| 亚洲国产天堂久久国产91| 欧美一区在线直播| 成人动漫网站在线观看| 欧美在线视频网| 日韩一中文字幕| 欧美成人在线网站| 日韩精品亚洲元码| 欧美精品一本久久男人的天堂| 日韩不卡中文字幕| 欧美另类在线观看| 国产一区二区三区在线视频| 久久韩国免费视频| 久久久国产精品x99av| 88xx成人精品| 久久久99久久精品女同性| 456亚洲影院| 日韩精品有码在线观看| 欧美激情一区二区三区久久久| 国产成人精品在线视频| 日韩电影中文字幕在线观看| 成人有码在线视频| 日韩在线欧美在线| 国产精品一区二区三区久久| 日韩大胆人体377p| 中文字幕在线视频日韩| 欧美日韩裸体免费视频| 久久99精品久久久久久青青91| 久久99久久久久久久噜噜| 国产黑人绿帽在线第一区| 亚洲欧美日韩在线高清直播|