简单的一些异常的处理
一些简单的异常处理基础知识总结(仅供参考)
(一).NET的异常处理方式:
发生异常时,系统将搜索可以处理该异常的最近的 catch 子句(根据该异常的运行时类型来确定)。首先,搜索当前的方法以查找一个词法上包含着它的 try 语句,并按顺序考察与该 try 语句相关联的各个 catch 子句。如果上述操作失败,则在调用了当前方法的方法中,搜索在词法上包含着当前方法调用代码位置的 try 语句。此搜索将一直进行下去,直到找到可以处理当前异常的 catch 子句(该子句指定一个异常类,它与当前引发该异常的运行时类型属于同一个类或是该运行时类型所属类的一个基类)。注意,没有指定异常类的 catch 子句可以处理任何异常。
找到匹配的 catch 子句后,系统将把控制转移到该 catch 子句的第一条语句。在 catch 子句的执行开始前,系统将首先按顺序执行嵌套在捕捉到该异常的 try 语句里面的所有 try 语句所对应的全部 finally 子句。
(1).try块:包含的代码通常需要执行一些通用的资源清理操作,或者需要从异常中恢复,或者两者都需要。try块还可以包含也许会抛出异常的代码。
(2).catch块:包含的是响应一个异常需要执行的代码。如果没有任何捕捉类型与抛出的异常匹配,CLR会去调用栈的更高一层搜索一个与异常匹配的捕捉类型。
(3).finally块:包含的代码是保证会执行的代码。finally块所有代码执行完毕后,线程退出finally块,执行紧跟在finally块之后的语句。
语法
假设一个块将出现异常,一个方法使用 try 和 catch 关键字捕获异常。try/catch 块内的代码为受保护的代码,使用 try/catch 语法如下所示:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
try { // 引起异常的语句 } catch (ExceptionName e1) { // 错误处理代码 } catch (ExceptionName e2) { // 错误处理代码 } catch (ExceptionName eN) { // 错误处理代码 } finally { // 要执行的语句 } |
(二).Exception的常用属性的源码解析:
(1).Message:包含辅助性文字说明,指出抛出异常的原因。
public virtual String Message { get { if (_message == null) { if (_className==null) { _className = GetClassName(); } return Environment.GetRuntimeResourceString("Exception_WasThrown", _className); } else { return _message; } } }
(2).Data:对一个“键/值对”集合的引用。
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).提取异常及其内部异常堆栈跟踪
/// <summary> /// 提取异常及其内部异常堆栈跟踪 /// </summary> /// <param name="exception">提取的例外</param> /// <param name="lastStackTrace">最后提取的堆栈跟踪(对于递归), String.Empty or null</param> /// <param name="exCount">提取的堆栈数(对于递归)</param> /// <returns>Syste.String</returns> public static string ExtractAllStackTrace(this Exception exception, string lastStackTrace = null, int exCount = 1) { var ex = exception; const string entryFormat = "#{0}: {1}\r\n{2}"; //修复最后一个堆栈跟踪参数 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]); } } //递归添加内部异常 if ((ex = ex.InnerException) != null) return ex.ExtractAllStackTrace(string.Format("{0}\r\n\r\n", lastStackTrace), ++exCount); return lastStackTrace; }
(2).检查字符串是空的或空的,并抛出一个异常
/// <summary> /// 检查字符串是空的或空的,并抛出一个异常 /// </summary> /// <param name="val">值测试</param> /// <param name="paramName">参数检查名称</param> public static void CheckNullOrEmpty(string val, string paramName) { if (string.IsNullOrEmpty(val)) throw new ArgumentNullException(paramName, "Value can't be null or empty"); }
(3).检查参数不是无效,并抛出一个异常
/// <summary> /// 检查参数不是无效,并抛出一个异常 /// </summary> /// <param name="param">检查值</param> /// <param name="paramName">参数名称</param> public static void CheckNullParam(object param, string paramName) { if (param == null) throw new ArgumentNullException(paramName, paramName + " can't be null"); }
(4).请检查参数1不同于参数2
/// <summary> /// 请检查参数1不同于参数2 /// </summary> /// <param name="param1">值1测试</param> /// <param name="param1Name">name of value 1</param> /// <param name="param2">value 2 to test</param> /// <param name="param2Name">name of vlaue 2</param> 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); } }
(5).检查一个整数值是正的(0或更大)
/// <summary> /// 检查一个整数值是正的(0或更大) /// </summary> /// <param name="val">整数测试</param> public static void PositiveValue(int val) { if (val < 0) throw new ArgumentException("The value must be greater than or equal to 0."); }
异常处理器(程序):对于程序中出现的异常,在C#中是使用一种被称为“异常处理器(程序)”的错误捕获机制来进行处理的, 你可以认为异常处理器(程序)就是发生错误时,能够接受并处理错误的接受者和处理。
(三)C#常见的一些相关异常仅做参考
1、常见异常类
SystemException | 该类是System命名空间中所有其他异常类的基类。(建议:公共语言运行时引发的异常通常用此类) |
ApplicationException | 该类表示应用程序发生非致命错误时所引发的异常(建议:应用程序自身引发的异常通常用此类) |
2、与参数有关的异常类
ArgumentException | 该类用于处理参数无效的异常,除了继承来的属性名,此类还提供了string类型的属性ParamName表示引发异常的参数名称。 |
FormatException | 该类用于处理参数格式错误的异常。 |
3、与成员访问有关的异常
MemberAccessException | 该类用于处理访问类的成员失败时所引发的异常。失败的原因可能的原因是没有足够的访问权限,也可能是要访问的成员根本不存在(类与类之间调用时常用) |
FileAccessException | 该类用于处理访问字段成员失败所引发的异常 |
MethodAccessException | 该类用于处理访问方法成员失败所引发的异常 |
MissingMemberException | 该类用于处理成员不存在时所引发的异常 |
4、与数组有关的异常
IndexOutOfException | 该类用于处理下标超出了数组长度所引发的异常 |
ArrayTypeMismatchException | 该类用于处理在数组中存储数据类型不正确的元素所引发的异常 |
RankException | 该类用于处理维数错误所引发的异常 |
5、与IO有关的异常
IOException | 该类用于处理进行文件输入输出操作时所引发的异常。 |
DirectionNotFoundException | 该类用于处理没有找到指定的目录而引发的异常。 |
FileNotFoundException | 该类用于处理没有找到文件而引发的异常。 |
EndOfStreamException | 该类用于处理已经到达流的末尾而还要继续读数据而引发的异常。 |
FileLoadException | 该类用于处理无法加载文件而引发的异常。 |
PathTooLongException | 该类用于处理由于文件名太长而引发的异常。 |
6、算数相关异常
ArithmeticException | 该类用于处理与算术有关的异常。 |
DivideByZeroException | 表示整数货十进制运算中试图除以零而引发的异常。 |
NotFiniteNumberException | 表示浮点数运算中出现无穷打或者非负值时所引发的异常。 |
笔者原文地址:http://www.cnblogs.com/tranw/p/5980490.html
版权声明:本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
作者:黯淡の青春 博客地址:http://www.cnblogs.com/wuwangqianxun/