1. 概述
本章包括.net4.5中异常处理相关的部分。
2. 主要内容
2.1 处理异常
① try、cahtch、finally 机制,无需多言。
② 使用 Environment.FailFast 方法,可以立即终止程序,并写入系统事件日志。会绕过finally的执行。
public static void Main() { string s = Console.ReadLine(); try { int i = int.Parse(s); if (i == 42) Environment.FailFast("Special number entered.."); } finally { Console.WriteLine("Program complete.."); } }
③ 如果finally中的代码发生异常,将会抛出到外层的处理程序,并且会丢失初始的异常信息。
2.2 抛出异常
① 不要试图重用异常对象,特别是在多线程环境中。因为异常的堆栈信息可能会被其他线程更改。
② C#5 中新加了ExceptionDispatchInfo.Throw, 它会保存原始的异常信息并向上抛出。主要用于在线程间传递异常信息。
ExceptionDispatchInfo possibleException = null; try { string s = Console.ReadLine(); int .Parse(s); } catch(FormatException ex) { possibleException = ExceptionDispatchInfo.Capture(ex); } if (possibleException != null) possibleException.Throw();
③ 异常处理会影响程序的流程和性能,降低可读性。
④ 一些只能被Runtime抛出的异常: AirthmaticException, ArrayTypeMisMatchException, DivideByZeroException,
IndexOutofRangeException, InvalidCastException, NullReferenceException, OutOfMemoryException,
OverFlowException, StackOverflowException, TypeInitializationException.
2.3 创建自定义异常
自定义异常应该按照规则,以Exception结尾。应该添加序列化属性。不要从System.ApplicationException继承。
[Serializable] public class OrderProcessingException : Exception, ISerializable { public OrderProcessingException(int orderId) { OrderId = orderId; this.HelpLink = "http://www.mydomain.com/infoExps"; } public OrderProcessingException(int orderId, string msg) : base (msg) { OrderId = orderId; this.HelpLink = "http://www.mydomain.com/infoExps"; } public OrderProcessingException(int orderId, string msg, Exception innerExp) : base (msg, innerExp) { OrderId = orderId; this.HelpLink = "http://www.mydomain.com/infoExps"; } protected OrderProcessingException(SerializationInfo info, StreamingContext context) { OrderId = (int) info.GetValue("OrderId", typeof(int)); } public int OrderId {get; private set;} public void GetObjectData(SerializationInfo info, StreamingContext context) { info.AddValue("OrderId", OrderId, typeof(int)); } }
3. 总结
① 在.net中,应该用提供的异常处理机制来处理异常。
② 应该使用一个try块配合一个或多个catch块来处理不同类型的异常。
③ 自定义异常,只有在确定代码使用者将会有逻辑的处理它的时候才应该使用。否则就应该用内建的异常类型。