定义自己的异常类
很多观点认为在自己的方法抛出异常时,永远都不要抛出一个System.Exception对象!比较好的方式的先从FCL里面找一个合适的异常类,而不是第一时间就想抛出自己定义的异常。FCL定义了大量的异常类,如System.OutOfMemoryException可以让你在发生内存溢出的情况下抛出,System.TimeOutException可以让你面对操作超时的问题时抛出。但FCL定义的异常显然不可能满足你所有的要求,这时候可考虑自定义的异常。自定义的异常必须从System.Exception或者其派生类作为自定义异常类派生,为了实现异常对象在跨越应用程序域时得到封送处理(marshaled),同时还能持久化至日志或数据库,这个异常类必须是可序列化的,所以定义这个类型的时候需要应用特性Serializable(关于特性的使用可阅读《你必须懂的.NET中Attribute》),如新增字段的话还有实现ISerializable接口中的用于序列化的GetObjectData方法。
下面我们来自定义一个异常类,这个异常类新增一个属性IsLog,用以表识是否将异常写入日志,如IsLog设置为true,则写入日志。因为自定义特性比较繁琐,所以VS里面有定义好的代码段可以供我们使用,我们在代码编写区键入ex的时候VS会提示我们exception的代码段可以选择,我们选择exception,然后单击“Tab”键,VS将自动为我们生成我们自定义异常类的部分关键代码。我们定义好这个异常后将之用在前面代码的DividedBy方法中,当代码判断分母为0的时候,就构建这个异常对象抛出,更高一层的代码捕捉到这个异常,判断异常IsLog属性为true时,将异常信息写入日志,代码如下:
namespace ExceptionDemo
{
class Program
{
static void Main(string[] args)
{
try
{
double result = Calculation.DividedBy(0, 0);
Console.WriteLine(result);
}
catch (MyException ex)
{
if (ex.IsLog)
{
Console.WriteLine("将异常信息:{0} 写入日志文件",ex.Message);
}
}
Console.ReadKey();
}
}
/// <summary>
/// 计算类
/// </summary>
public static class Calculation
{
/// <summary>
/// 除法
/// </summary>
public static double DividedBy(int a, int b)
{
double result = 0.0;
if (b == 0)
{
MyException ex = new MyException("除数不能为零",true);
throw ex;
}
result = a / b;
return result;
}
}
[Serializable]
public class MyException : Exception,ISerializable
{
/// <summary>
/// 新增字段,用以判断是否将异常写入日志文件
/// </summary>
private bool _isLog=false ;
public bool IsLog
{
get { return _isLog; }
}
public MyException():base() { }
//为新增字段实现构造函数
public MyException(string message, bool isLog)
: base(message)
{
_isLog = isLog;
}
//为新增字段实现构造函数
public MyException(string message, bool isLog, Exception inner) : base(message, inner) { _isLog = isLog; }
//用于序列化的构造函数,以支持跨应用程序域或远程边界的封送处理
protected MyException(
System.Runtime.Serialization.SerializationInfo info,
System.Runtime.Serialization.StreamingContext context)
: base(info, context) { }
//重写基类GetObjectData()方法,实现向SerializationInfo中添加自定义字段信息
public override void GetObjectData(SerializationInfo info, StreamingContext context)
{
// 序列化自定义数据成员
info.AddValue("IsLog",IsLog);
base.GetObjectData(info,context);
}
}
}
输出结果如下:
将异常信息:除数不能为零 写入日志文件
|