C#捕捉异常
异常是编程语言的一个强大特性,能减少复杂性代码,并且减少了的编写和维护的代码数量。
尽量用值的方式抛出异常,用引用来捕捉异常。
例如:
void Test(Item item) { try { if (/* some test failed */) { throw _com_error(E_FAIL); } } catch(_com_error& comError) { // Process comError // } }
大家对这个更眼熟了吧:
try { ... } catch(System.Exception e) { ... }
异常存在系统的每一刻,你不察觉或是没有抛出而已。你不应抓住错误用没有具体指定的异常,如
System.Exception, System.SystemException 等等的基类通用的异常,C#本身代码异常。
而你应该更多地去捕捉 最可能得到的异常 (有意义的异常),例如当可能会遇到空参数时抛出ArgumentNullException
而不是其基类的异常 ArgumentException。
或者你可以在最后的catch块中重新抛出通用的异常。
抛出 System.Exception 和捕捉 System.Exception 总是一件错误的事,你可以“ 偷懒” 地这样,一旦那个方法没有正确地运行,
你得花很多功夫去找那个错误。
例子:
// Good: try { ... } catch(System.NullReferenceException exc) { ... } catch(System.ArgumentOutOfRangeException exc) { ... } catch(System.InvalidCastException exc) { ... } //Bad: try { ... } catch (Exception ex) { ... }
当捕捉和重新抛出一个异常时,比较好的方法是抛出一个空 throw。这是很好的方法来保护异常调用堆栈信息。
例子:
//Good: try { ... // Do some reading with the file } catch { file.Position = position; // Unwind on failure throw; // Rethrow } //Bad: try { ... // Do some reading with the file } catch (Exception ex) { file.Position = position; // Unwind on failure throw ex; // Rethrow }
最后, 异常类 阅兵仪式:
Exception:所有异常对象的基类。
SystemException:运行时产生的所有错误的基类。
IndexOutOfRangeException:当一个数组的下标超出范围时运行时引发。
NullReferenceException:当一个空对象被引用时运行时引发。
InvalidOperationException:当对方法的调用对对象的当前状态无效时,由某些方法引发。
ArgumentException:所有参数异常的基类。
ArgumentNullException:在参数为空(不允许)的情况下,由方法引发。
ArgumentOutOfRangeException:当参数不在一个给定范围之内时,由方法引发。
InteropException:目标在或发生在CLR外面环境中的异常的基类。
ComException:包含COM类的HRESULT信息的异常。
SEHException:封装Win32结构异常处理信息的异常。
SqlException:封装了SQL操作异常。
常见具体的异常对象:
ArgumentNullException 一个空参数传递给方法,该方法不能接受该参数
ArgumentOutOfRangeException 参数值超出范围
ArithmeticException 出现算术上溢或者下溢
ArrayTypeMismatchException 试图在数组中存储错误类型的对象
BadImageFormatException 图形的格式错误
DivideByZeroException 除零异常
DllNotFoundException 找不到引用的DLL
FormatException 参数格式错误
IndexOutOfRangeException 数组索引超出范围
InvalidCastException 使用无效的类
InvalidOperationException 方法的调用时间错误
NotSupportedException 调用的方法在类中没有实现
NullReferenceException 试图使用一个未分配的引用
OutOfMemoryException 内存空间不够
StackOverflowException 堆栈溢出