异常
在异常发生时,将自上而下地搜索匹配的catch快,因此,我们应将较具体的异常放在上面,即最常用的异常类型应首先出现,
接着是这些类型的基础类型(如果存在的话),最后是System.Exception异常。
例子:
private void SomeMethod()
{
try
{
//在try块中放入要求恢复或者要求公共资源清理操作的代码
}
catch(InvalidOperationException)
{
//在这个Catch块中放入能够从InvalidOperationException异常(或者任何派生自InvalidOperationException
//的异常类型)中恢复的代码
}
catch(IOException)
{
//IOException或者其派生类异常处理代码
}
catch //catch(Exception)
{
//处理代码
//重新抛出
}
finally
{
//最终操作,一般是释放资源
}
}
实例:
private void ReadData(String pathName)
{
FileStream fs = null;
try
{
fs = new FileStream(pathName, FileStream.Open);
//other operations
....
}
catch(IOException)
{
//IOException 处理代码
}
finally
{
//释放资源
if(fs != null)
{
fs.close();
}
}
}
2、定义自己的异常类
定义异常类是的注意事项:
1、定义一个派生自System.Exception的自己的异常类是,异常类的语义一定要精确匹配,包要抛出System.Exception的异常。
2、计划为异常类型的构造器传递什么样的字符串消息?字符串要包含为何无法完成任务
实例:假设我们顶一个方法,该方法接收对象的引用,而对象的类型必须实现IFormattable接口和IComparable接口:
internal sealed class SomeType
{
public void SomeMethod(Object o)
{
if(!((O is IFormattable) && (o is IComparable)))
{
throw new MissingInterfaceException(...)
}
//操作对象o...
}
}
MissingInterfaceEception是自定义的一个异常类,在定义异常类时,我们可以从Sytem.Exception继承,也可以从他具体的子类
继承,如果定义的异常类不作为其他类的父类,应该将该类型标记为sealed。
Exception基础类型定义了4个标准构造器:
1、一个公共的无参构造器(默认),它创建一个异常类型的实例,并将所有的字段和属性设为默认值。
2、一个公共的含有连个参数的构造器(参数的类型为String),他创建了一个异常类型的实力,并设置一个指定的消息。
3、一个公共的含有两个参数的构造器(其中一个参数的类型String,另一个参数为派生自Exception类型的实例),他创建了一个异常类型的实力,并设置一个指定的消息和一个内部异常。
4、一个受保护的含有两个参数的构造器(其中一个参数为SerializationInfo,另一个参数为StreamingContext),他反序列化派生自Exception对象的实例。注意,如果派生自Exception的类型是密封的,那么这个方法的可访问性应为private,并且确保该构造器在基类中条用相同的构造器,一边基类的字段被真正地反序列化。
要使一个新定义的异常序列化,需要练个步骤:首先,要对类型应用一个[Serializable]自定义属性;
接着,还要实现ISeriallizable接口及其GetObjiectData方法(该方法用哟一个SecurityPermission属性)
和一个构造器,两者都有连个参数,即SerializationInfo和StreamingContext.
实例代码:
using System;
using System.Text;
using System.Runtime.Serialization;
using System.Security.Permission;
//允许DiskFullException的实例被序列化
[Serialiable]
public sealed class DiskFullException : Exception, ISerializable
{
//定义一个私有字段
private String m_diskpath;
//定义一个只读属性,该属性返回字段
public String DiskPath
{
get{ return m_diskpath}
}
//为了包含字段,重写属性Message(如果已经设置的话)
public override String Message
{
get
{
if(m_diskpath == null)
{
return base.Message;
StringBuilder msg = new StringBuilder(base.Message);
msg.AppendFormat(" (DiskPath = {0}) {1}", m_diskpath, Environment.NewLine);
return msg.ToString;
}
}
}
//三个公共构造器方法
public DiskFullException() : base() {}
public DiskFullException(String message) : base(message) {}
public DiskFullException(String message, Exception innerException) : base(message, innerException) {}
//定义一个额外的构造器,设置新定义的字段
public DiskFullException(String message, String diskpath) : this(message)
{
m_diskpath = diskpath;
}
public DiskFullException(String message, String diskpath, Exception innerException)
: this (message, innerException)
{
m_diskpath = diskpath;
}
//定义一个反序列化的构造器,因为雷士密封的,所以该构造器是私有的;否则,该构造器可以是受保护的
private DiskFullException(SerializationInfo info, StreamingContext context) : base(into, context)
{
m_diskpath = info.GetString("DiskPath");
}
//定义序列化方法:SecurityPermission确保调用者后的对象的内部状态
[SecurityPermission(SecurityAction.Demand, SerializationFormatter = true)]
public override void GetObjectData(SerializationInfo info, StreamingContext context)
{
//让及类型序列化它的字段
base.GetObjectData(info, context);
//序列化类型的字段
info.AddValue("DiskPath", m_diakpath);
}
}
在异常发生时,将自上而下地搜索匹配的catch快,因此,我们应将较具体的异常放在上面,即最常用的异常类型应首先出现,
接着是这些类型的基础类型(如果存在的话),最后是System.Exception异常。
例子:
private void SomeMethod()
{
try
{
//在try块中放入要求恢复或者要求公共资源清理操作的代码
}
catch(InvalidOperationException)
{
//在这个Catch块中放入能够从InvalidOperationException异常(或者任何派生自InvalidOperationException
//的异常类型)中恢复的代码
}
catch(IOException)
{
//IOException或者其派生类异常处理代码
}
catch //catch(Exception)
{
//处理代码
//重新抛出
}
finally
{
//最终操作,一般是释放资源
}
}
实例:
private void ReadData(String pathName)
{
FileStream fs = null;
try
{
fs = new FileStream(pathName, FileStream.Open);
//other operations
....
}
catch(IOException)
{
//IOException 处理代码
}
finally
{
//释放资源
if(fs != null)
{
fs.close();
}
}
}
2、定义自己的异常类
定义异常类是的注意事项:
1、定义一个派生自System.Exception的自己的异常类是,异常类的语义一定要精确匹配,包要抛出System.Exception的异常。
2、计划为异常类型的构造器传递什么样的字符串消息?字符串要包含为何无法完成任务
实例:假设我们顶一个方法,该方法接收对象的引用,而对象的类型必须实现IFormattable接口和IComparable接口:
internal sealed class SomeType
{
public void SomeMethod(Object o)
{
if(!((O is IFormattable) && (o is IComparable)))
{
throw new MissingInterfaceException(...)
}
//操作对象o...
}
}
MissingInterfaceEception是自定义的一个异常类,在定义异常类时,我们可以从Sytem.Exception继承,也可以从他具体的子类
继承,如果定义的异常类不作为其他类的父类,应该将该类型标记为sealed。
Exception基础类型定义了4个标准构造器:
1、一个公共的无参构造器(默认),它创建一个异常类型的实例,并将所有的字段和属性设为默认值。
2、一个公共的含有连个参数的构造器(参数的类型为String),他创建了一个异常类型的实力,并设置一个指定的消息。
3、一个公共的含有两个参数的构造器(其中一个参数的类型String,另一个参数为派生自Exception类型的实例),他创建了一个异常类型的实力,并设置一个指定的消息和一个内部异常。
4、一个受保护的含有两个参数的构造器(其中一个参数为SerializationInfo,另一个参数为StreamingContext),他反序列化派生自Exception对象的实例。注意,如果派生自Exception的类型是密封的,那么这个方法的可访问性应为private,并且确保该构造器在基类中条用相同的构造器,一边基类的字段被真正地反序列化。
要使一个新定义的异常序列化,需要练个步骤:首先,要对类型应用一个[Serializable]自定义属性;
接着,还要实现ISeriallizable接口及其GetObjiectData方法(该方法用哟一个SecurityPermission属性)
和一个构造器,两者都有连个参数,即SerializationInfo和StreamingContext.
实例代码:
using System;
using System.Text;
using System.Runtime.Serialization;
using System.Security.Permission;
//允许DiskFullException的实例被序列化
[Serialiable]
public sealed class DiskFullException : Exception, ISerializable
{
//定义一个私有字段
private String m_diskpath;
//定义一个只读属性,该属性返回字段
public String DiskPath
{
get{ return m_diskpath}
}
//为了包含字段,重写属性Message(如果已经设置的话)
public override String Message
{
get
{
if(m_diskpath == null)
{
return base.Message;
StringBuilder msg = new StringBuilder(base.Message);
msg.AppendFormat(" (DiskPath = {0}) {1}", m_diskpath, Environment.NewLine);
return msg.ToString;
}
}
}
//三个公共构造器方法
public DiskFullException() : base() {}
public DiskFullException(String message) : base(message) {}
public DiskFullException(String message, Exception innerException) : base(message, innerException) {}
//定义一个额外的构造器,设置新定义的字段
public DiskFullException(String message, String diskpath) : this(message)
{
m_diskpath = diskpath;
}
public DiskFullException(String message, String diskpath, Exception innerException)
: this (message, innerException)
{
m_diskpath = diskpath;
}
//定义一个反序列化的构造器,因为雷士密封的,所以该构造器是私有的;否则,该构造器可以是受保护的
private DiskFullException(SerializationInfo info, StreamingContext context) : base(into, context)
{
m_diskpath = info.GetString("DiskPath");
}
//定义序列化方法:SecurityPermission确保调用者后的对象的内部状态
[SecurityPermission(SecurityAction.Demand, SerializationFormatter = true)]
public override void GetObjectData(SerializationInfo info, StreamingContext context)
{
//让及类型序列化它的字段
base.GetObjectData(info, context);
//序列化类型的字段
info.AddValue("DiskPath", m_diakpath);
}
}