C# 自定义异常
问题的提出,在开发应用程序的过程当中,.net 为我们提供了严密的异常捕获的方法,使应用程序能够健壮的运行
”如果自定义异常继承自Exception ,缺点在这里:如果异常直接继承自Exception ,我们的代码可能会跑出一个应用程序
根本吧知道的新异常类型。这很可能成为一个未处理异常而导致应用程序中断。这种行为很容易发生,以为我们违反了一个隐含的假设,而应用程序
有没有提供任何补救措施。如果我们捕获了这个新的异常,然后便忽略它并继续执行应用程序,同样可能产生不可预期的结果。“
以上摘自 Jeffrey Richter 的《Microsoft.NET.框架程序设计》
下面提供了代码的实现
//---------------------------------------------------------------------------
// File: DiskFullException.cs
//
// Description: 自子定义异常
// History:
// 06/24/2011
//
//---------------------------------------------------------------------------
using System;
using System.IO;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Soap;
//允许DiskFullExceptio 的实例可以实例化
[Serializable]
sealed class DiskFullException : Exception,ISerializable
{
//三个共有构造器
public DiskFullException():base()//调用基类的构造器
{
}
public DiskFullException(string message):base(message)//调用基类的构造器
{
}
public DiskFullException(string message,Exception innerException):base(message,innerException)//调用基类的构造器
{}
//定义了一个私有字段
private string diskpath;
//顶一个只读属性,改属性返回新定义的字段
public string DiskPath{get {return diskpath;}}
//重新共有属性Message,将新定义的字段包含在异常的信息文本中
public override string Message
{
get
{
string msg=base.Message;
if(diskpath!=null)
msg+=Environment.NewLine+"Disk Path:"+diskpath;
return msg;
}
}
//因为定义了至少新的字段,所以要定义一个特殊的构造器用于反序列化
//由于该类是密封类,所以该构造器的访问限制被定义为私有方式。否则,该构造器
//被定义为受保护方式
private DiskFullException(SerializationInfo info,StreamingContext context):base(info,context)//让基类反序列化其内定义的字段
{
diskpath=info.GetString("DiskPath");
}
//因为定义了至少一个字段,所以要定义序列化方法
void ISerializable.GetObjectData(SerializationInfo info,StreamingContext context)
{
//序列化新定义的每个字段
info.AddValue("DiskPath",diskpath);
//让基类序列化其内定义的字段
base.GetObjectData(info,context);
}
//定义额外的构造器设置新定义的字段
public DiskFullException(string message,string diskpath):this(message)//调用另外一个构造器
{
this.diskpath=diskpath;
}
public DiskFullException(string message,string diskpath,Exception innerException):this(message,innerException)
{
this.diskpath=diskpath;
}
}
//下面的代码测试异常的序列化
class App
{
static void Main()
{
//构造一个DiskFullException 对象,并对其序列化
DiskFullException e=new DiskFullException("The diks volume is full",@"c:\");
FileStream fs=new FileStream(@"Test",FileMode.Create);
IFormatter f=new SoapFormatter();
f.Serialize(fs,e);
fs.Close();
//反序列化DiskFullException 对象,并查看它的字段
fs=new FileStream(@"Test",FileMode.Open);
e=(DiskFullException)f.Deserialize(fs);
fs.Close();
Console.WriteLine("Type:{1}{0} DiskPath:{2}{0} Message:{3}",Environment.NewLine,e.GetType(),e.DiskPath,e.Message);
Console.Read();
}
}