在.NET中,異常是指成員沒(méi)有完成它的名稱宣稱可以完成的行動(dòng)。在異常的機(jī)制中,異常和某件事情的發(fā)生頻率無(wú)關(guān)。
創(chuàng)新互聯(lián)專注于企業(yè)營(yíng)銷型網(wǎng)站、網(wǎng)站重做改版、銅仁網(wǎng)站定制設(shè)計(jì)、自適應(yīng)品牌網(wǎng)站建設(shè)、H5網(wǎng)站設(shè)計(jì)、商城網(wǎng)站定制開(kāi)發(fā)、集團(tuán)公司官網(wǎng)建設(shè)、外貿(mào)網(wǎng)站建設(shè)、高端網(wǎng)站制作、響應(yīng)式網(wǎng)頁(yè)設(shè)計(jì)等建站業(yè)務(wù),價(jià)格優(yōu)惠性價(jià)比高,為銅仁等各大城市提供網(wǎng)站開(kāi)發(fā)制作服務(wù)。
異常處理四要素包括:一個(gè)表示異常詳細(xì)信息的類類型;一個(gè)向調(diào)用者引發(fā)異常類實(shí)例的成員;調(diào)用者的一段調(diào)用異常成員的代碼塊;調(diào)用者的一段處理將要發(fā)生異常的代碼塊。異常類類型包括:基類:System.Exception;系統(tǒng)級(jí)異常:System.SystemException;應(yīng)用程序級(jí)異常:System.ApplicationException。
(一).在.NET中有如下的異常類:
(1).由System.SystemException派生的異常類型:
System.AccessViolationException | 在試圖讀寫(xiě)受保護(hù)內(nèi)存時(shí)引發(fā)的異常。 |
System.ArgumentException | 在向方法提供的其中一個(gè)參數(shù)無(wú)效時(shí)引發(fā)的異常。 |
System.Collections.Generic.KeyNotFoundException | 指定用于訪問(wèn)集合中元素的鍵與集合中的任何鍵都不匹配時(shí)所引發(fā)的異常。 |
System.IndexOutOfRangeException | 訪問(wèn)數(shù)組時(shí),因元素索引超出數(shù)組邊界而引發(fā)的異常。 |
System.InvalidCastException | 因無(wú)效類型轉(zhuǎn)換或顯示轉(zhuǎn)換引發(fā)的異常。 |
System.InvalidOperationException | 當(dāng)方法調(diào)用對(duì)于對(duì)象的當(dāng)前狀態(tài)無(wú)效時(shí)引發(fā)的異常。 |
System.InvalidProgramException | 當(dāng)程序包含無(wú)效Microsoft中間語(yǔ)言(MSIL)或元數(shù)據(jù)時(shí)引發(fā)的異常,這通常表示生成程序的編譯器中有bug。 |
System.IO.IOException | 發(fā)生I/O錯(cuò)誤時(shí)引發(fā)的異常。 |
System.NotImplementedException | 在無(wú)法實(shí)現(xiàn)請(qǐng)求的方法或操作時(shí)引發(fā)的異常。 |
System.NullReferenceException | 嘗試對(duì)空對(duì)象引用進(jìn)行操作時(shí)引發(fā)的異常。 |
System.OutOfMemoryException | 沒(méi)有足夠的內(nèi)存繼續(xù)執(zhí)行程序時(shí)引發(fā)的異常。 |
System.StackOverflowException | 掛起的方法調(diào)用過(guò)多而導(dǎo)致執(zhí)行堆棧溢出時(shí)引發(fā)的異常。 |
(2).由System.ArgumentException派生的異常類型:
System.ArgumentNullException | 當(dāng)將空引用傳遞給不接受它作為有效參數(shù)的方法時(shí)引發(fā)的異常。 |
System.ArgumentOutOfRangeException | 當(dāng)參數(shù)值超出調(diào)用的方法所定義的允許取值范圍時(shí)引發(fā)的異常。 |
(3).由System.ArithmeticException派生的異常類型:
System.DivideByZeroException | 試圖用零除整數(shù)值或十進(jìn)制數(shù)值時(shí)引發(fā)的異常。 |
System.NotFiniteNumberException | 當(dāng)浮點(diǎn)值為正無(wú)窮大、負(fù)無(wú)窮大或非數(shù)字(NaN)時(shí)引發(fā)的異常。 |
System.OverflowException | 在選中的上下文中所進(jìn)行的算數(shù)運(yùn)算、類型轉(zhuǎn)換或轉(zhuǎn)換操作導(dǎo)致溢出時(shí)引發(fā)的異常。 |
(4).由System.IOException派生的異常類型:
System.IO.DirectoryNotFoundException | 當(dāng)找不到文件或目錄的一部分時(shí)所引發(fā)的異常。 |
System.IO.DriveNotFoundException | 當(dāng)嘗試訪問(wèn)的驅(qū)動(dòng)器或共享不可用時(shí)引發(fā)的異常。 |
System.IO.EndOfStreamException | 讀操作試圖超出流的末尾時(shí)引發(fā)的異常。 |
System.IO.FileLoadException | 當(dāng)找到托管程序卻不能加載它時(shí)引發(fā)的異常。 |
System.IO.FileNotFoundException | 試圖訪問(wèn)磁盤上不存在的文件失敗時(shí)引發(fā)的異常。 |
System.IO.PathTooLongException | 當(dāng)路徑名或文件名超過(guò)系統(tǒng)定義的最大長(zhǎng)度時(shí)引發(fā)的異常。 |
(5).其他常用異常類型:
ArrayTypeMismatchException | 試圖在數(shù)組中存儲(chǔ)錯(cuò)誤類型的對(duì)象。 |
BadImageFormatException | 圖形的格式錯(cuò)誤。 |
DivideByZeroException | 除零異常。 |
DllNotFoundException | 找不到引用的dll。 |
FormatException | 參數(shù)格式錯(cuò)誤。 |
MethodAccessException | 試圖訪問(wèn)私有或者受保護(hù)的方法。 |
MissingMemberException | 訪問(wèn)一個(gè)無(wú)效版本的dll。 |
NotSupportedException | 調(diào)用的方法在類中沒(méi)有實(shí)現(xiàn)。 |
PlatformNotSupportedException | 平臺(tái)不支持某個(gè)特定屬性時(shí)拋出該錯(cuò)誤。 |
(二)..NET的異常處理方式:
發(fā)生異常時(shí),系統(tǒng)將搜索可以處理該異常的最近的 catch 子句(根據(jù)該異常的運(yùn)行時(shí)類型來(lái)確定)。首先,搜索當(dāng)前的方法以查找一個(gè)詞法上包含著它的 try 語(yǔ)句,并按順序考察與該 try 語(yǔ)句相關(guān)聯(lián)的各個(gè) catch 子句。如果上述操作失敗,則在調(diào)用了當(dāng)前方法的方法中,搜索在詞法上包含著當(dāng)前方法調(diào)用代碼位置的 try 語(yǔ)句。此搜索將一直進(jìn)行下去,直到找到可以處理當(dāng)前異常的 catch 子句(該子句指定一個(gè)異常類,它與當(dāng)前引發(fā)該異常的運(yùn)行時(shí)類型屬于同一個(gè)類或是該運(yùn)行時(shí)類型所屬類的一個(gè)基類)。注意,沒(méi)有指定異常類的 catch 子句可以處理任何異常。
找到匹配的 catch 子句后,系統(tǒng)將把控制轉(zhuǎn)移到該 catch 子句的第一條語(yǔ)句。在 catch 子句的執(zhí)行開(kāi)始前,系統(tǒng)將首先按順序執(zhí)行嵌套在捕捉到該異常的 try 語(yǔ)句里面的所有 try 語(yǔ)句所對(duì)應(yīng)的全部 finally 子句。
(1).try塊:包含的代碼通常需要執(zhí)行一些通用的資源清理操作,或者需要從異常中恢復(fù),或者兩者都需要。try塊還可以包含也許會(huì)拋出異常的代碼。
(2).catch塊:包含的是響應(yīng)一個(gè)異常需要執(zhí)行的代碼。如果沒(méi)有任何捕捉類型與拋出的異常匹配,CLR會(huì)去調(diào)用棧的更高一層搜索一個(gè)與異常匹配的捕捉類型。
(3).finally塊:包含的代碼是保證會(huì)執(zhí)行的代碼。finally塊所有代碼執(zhí)行完畢后,線程退出finally塊,執(zhí)行緊跟在finally塊之后的語(yǔ)句。
(三).Exception的常用屬性的源碼解析:
(1).Message:包含輔助性文字說(shuō)明,指出拋出異常的原因。
public virtual String Message { get { if (_message == null) { if (_className==null) { _className = GetClassName(); } return Environment.GetRuntimeResourceString("Exception_WasThrown", _className); } else { return _message; } } }
(2).Data:對(duì)一個(gè)“鍵/值對(duì)”集合的引用。
public virtual IDictionary Data { [System.Security.SecuritySafeCritical] // auto-generated get { if (_data == null) if (IsImmutableAgileException(this)) _data = new EmptyReadOnlyDictionaryInternal(); else _data = new ListDictionaryInternal(); return _data; } }
(3).Source:包含生成異常的程序集名稱。
public virtual String Source { #if FEATURE_CORECLR [System.Security.SecurityCritical] // auto-generated #endif get { if (_source == null) { StackTrace st = new StackTrace(this,true); if (st.FrameCount>0) { StackFrame sf = st.GetFrame(0); MethodBase method = sf.GetMethod(); Module module = method.Module; RuntimeModule rtModule = module as RuntimeModule; if (rtModule == null) { System.Reflection.Emit.ModuleBuilder moduleBuilder = module as System.Reflection.Emit.ModuleBuilder; if (moduleBuilder != null) rtModule = moduleBuilder.InternalModule; else throw new ArgumentException(Environment.GetResourceString("Argument_MustBeRuntimeReflectionObject")); } _source = rtModule.GetRuntimeAssembly().GetSimpleName(); } } return _source; } #if FEATURE_CORECLR [System.Security.SecurityCritical] // auto-generated #endif set { _source = value; } }
(四).異常處理的常用方法:
(1).提取異常及其內(nèi)部異常堆棧跟蹤
////// 提取異常及其內(nèi)部異常堆棧跟蹤 /// /// 提取的例外 /// 最后提取的堆棧跟蹤(對(duì)于遞歸), String.Empty or null /// 提取的堆棧數(shù)(對(duì)于遞歸) ///Syste.String public static string ExtractAllStackTrace(this Exception exception, string lastStackTrace = null, int exCount = 1) { var ex = exception; const string entryFormat = "#{0}: {1}\r\n{2}"; //修復(fù)最后一個(gè)堆棧跟蹤參數(shù) lastStackTrace = lastStackTrace ?? string.Empty; //添加異常的堆棧跟蹤 lastStackTrace += string.Format(entryFormat, exCount, ex.Message, ex.StackTrace); if (exception.Data.Count > 0) { lastStackTrace += "\r\n Data: "; foreach (var item in exception.Data) { var entry = (DictionaryEntry)item; lastStackTrace += string.Format("\r\n\t{0}: {1}", entry.Key, exception.Data[entry.Key]); } } //遞歸添加內(nèi)部異常 if ((ex = ex.InnerException) != null) return ex.ExtractAllStackTrace(string.Format("{0}\r\n\r\n", lastStackTrace), ++exCount); return lastStackTrace; }
(2).異常處理常用方法:
////// 檢查字符串是空的或空的,并拋出一個(gè)異常 /// /// 值測(cè)試 /// 參數(shù)檢查名稱 public static void CheckNullOrEmpty(string val, string paramName) { if (string.IsNullOrEmpty(val)) throw new ArgumentNullException(paramName, "Value can't be null or empty"); } ////// 請(qǐng)檢查參數(shù)1不同于參數(shù)2 /// /// 值1測(cè)試 /// name of value 1 /// value 2 to test /// name of vlaue 2 public static void CheckDifferentsParams(object param1, string param1Name, object param2, string param2Name) { if (param1 == param2) { throw new ArgumentException(param1Name + " can't be the same as " + param2Name, param1Name + " and " + param2Name); } } ////// 檢查一個(gè)整數(shù)值是正的(0或更大) /// /// 整數(shù)測(cè)試 public static void PositiveValue(int val) { if (val < 0) throw new ArgumentException("The value must be greater than or equal to 0."); }
異常處理器(程序):對(duì)于程序中出現(xiàn)的異常,在C#中是使用一種被稱為“異常處理器(程序)”的錯(cuò)誤捕獲機(jī)制來(lái)進(jìn)行處理的, 你可以認(rèn)為異常處理器(程序)就是發(fā)生錯(cuò)誤時(shí),能夠接受并處理錯(cuò)誤的接受者和處理。