c#框架笔记--异常

异常
    在异常发生时,将自上而下地搜索匹配的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);
        }
    }


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值