C#对异常的处理(转)

异常的概念:
在C#中,异常就是发生错误的带名词,即一旦有错误,我们就认为程序发生了异常。
     比较专业的解释:  异常实际上是程序中错误导致中断了正常的指令流的一种事件.(你可以认为异常是任何中断正常程序流程的错误条件)。
     产生异常的条件:
     1:想打开的文件不存在
     2:网络连接中断
     3:代码错误
     。。。。

由于C#是面向对象,所有所有的错误被封装在异常对象中
一旦错误发生,将接收到一个特定的异常对象。
异常和普通问题的区别:
1:在编译上,还是在执行发生。
2:语法错误,还是逻辑错误。
普通问题:编译上,语法错误。
异常:执行,逻辑错误,会产生异常对象。
基本异常
    “异常情形”(异常条件)是指引发阻止当前方法或作用域继续执行的问题。
     对异常情形和普通问题进行区分是很重要的:
     1。所谓的普通问题是指:在当前环境下不能得到足够的信息,比如语法错误,此时错误将会向外传递,而且系统也总能处理这样的错误。
     2。而对于异常情形:表示是让程序不能继续执行下去的错误,因为在当前环境下无法获得必要的信息来解决问题。你所能做的是从当前环境跳出,并且把问题提交给处理他的程序,这就是抛出异常时所发生的事情。 

当异常发生时,如何处理:
使用:异常处理器(程序):对于程序中出现的异常,在C#中是使用一种被称为“异常处理器(程序)”的错误捕获机制来进行处理的, 你可以认为异常处理器(程序)就是发生错误时,能够接受并处理错误的接受者和处理地!

异常类的分支。
  所有的异常类都是Exception的子类
异常类的分类:
1.c#自带的异常类.  --->使用SystemException类下的子类
    2. 人工创建异常类。-->创建的类一定要继承ApplicationException类,net.2.0技术中,人工创建异常类可以直接继承Exception

SystemException:由.net FrameWork提供并由系统抛出的异常,不过这些异常也可以从你的方法体中抛出。常见的子异常类有:
    除数为0时的: DivideByZeroException
   在向方法提供的其中一个参数无效时引发的异常:ArgumentException
   当试图在数组中存储类型不正确的元素时引发的异常:ArrayTypeMismatchException
      。。。。。
        属于运行时异常的类型有很多,一般通用的识别他们的规则是:由编程导致的错误。他们会自动被.net 抛出,尽管可以不写,但有时为了在错误后,可以更准确的确定错误的原因,还是应该在程序中显示的抛出此类型的异常,记住:如果出现此类型的异常,则一定是你的程序错误了。

范例:
using System;
using System.Reflection;
using System.Collections;
public class Test3
{
    public static void Main(String[] args)
        {
            DevideTest t = new DevideTest();
            t.First = -1;
        }
}
public class DevideTest
{
    private double first;

    public double First
    {
        get { return first; }
        set
        {
            try
            {//try中放置可能发生错误的代码,一旦发生,程序将停止执行,根据错误信息产生异常对象,并且将异常对象传递给类型匹配的catch(),
                if (value < 0)
                {
                    throw new Exception("不能给出0一下的数字");
                }
                else
                {

                    first = value;
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
                //Message返回异常对象中包含的错误信息
            }
        }
    }
    private double second;

    public double Second
    {
        get { return second; }
        set { second = value; }
    }

}

System.Exception类的结构和成员。
构建器:
public Exception():初始化Exception类的新实例。
public Exception(string message):使用指定的错误信息初始化 Exception类的新实例。
public Exception(string message, Exception innerException):使用指定错误信息和对作为此异常原因的内部异常的引用来初始化 Exception类的新实例。
属性以及索引器:
public virtual string HelpLink{ get; set; }:获取或设置指向此异常所关联帮助文件的链接的url地址(可以是统一资源名称 (URN) 或统一资源定位器 (URL)),或包含一个解释该异常的网页的引用。
public virtual string Message{ get; }:获取描述当前异常的消息,这个属性是只读的,并且只能调用接收字符串作为参数的构建器来初始化他。
public virtual string Source{get; set;}:获取或设置导致错误的应用程序或对象的名称。
public virtual string StackTrace{get;}:获取当前异常发生时调用堆栈上的帧的字符串表示形式。
范例:
using System;
using System.IO;
public class Test3
{
    public static void Main(String[] args)
    {
        try
        {
            Exception e = new Exception("发生的错误");
            e.Source = "Main()方法发生";
            throw e;  //将异常对象抛出
            Console.WriteLine("ok");
        }
        catch (Exception e)
        {
            Console.WriteLine(e.Message);
            Console.WriteLine(e.Source);
            Console.WriteLine(e.StackTrace);
        }
    }
}

如何一段代码中可能抛出异常的类型有很多,如何精确的捕获对应异常?
范例:
using System;
using System.IO;
public class Test3
{
    public static void Main(String[] args)
    {
        try
        {
            //IndexOutOfRangeException
            ArrayTypeMismatchException e = new ArrayTypeMismatchException("发生的错误");
            e.Source = "Main()方法发生";
            throw e;  //将异常对象抛出
            //Console.WriteLine("ok");
        }
        catch(ArrayTypeMismatchException e)
        {//一旦匹配,就不再继续向下做匹配的工作,程序会退出整个try{}catch{}语句
            Console.WriteLine(e.GetType().ToString());
            Console.WriteLine(e.Message);
            Console.WriteLine(e.Source);
            Console.WriteLine(e.StackTrace);
            }
        catch(IndexOutOfRangeException e)
        {
            Console.WriteLine(e.GetType().ToString());
            Console.WriteLine(e.Message);
            Console.WriteLine(e.Source);
            Console.WriteLine(e.StackTrace);
        }
        catch (Exception e)
        {//1.起到最终捕获异常类对象的效果。
         //2. 为前面的精确捕获打下铺垫。
            Console.WriteLine(e.GetType().ToString());
            Console.WriteLine(e.Message);
            Console.WriteLine(e.Source);
            Console.WriteLine(e.StackTrace);
        }
        //
    }
}

注意:异常处理程序必须紧跟在try块之后,当异常被抛出时,异常处理机制将负责搜寻参数与异常类型类型相匹配的第一处理程序,然后进入catch子句执行,此时认为异常得到了处理,一旦catch子句结束,则处理程序的查找过程结束。注意,只有匹配的catch子句才能得到执行。这与switch语句不同(case语句都有break,以避免执行后续的case子句)。

凡是返回抽象类或接口类型的方法或属性,注意:真实返回的是实现接口或继承乐抽象类子类对象
获取产生异常的方法
public MethodBase TargetSite { get; } :获取引发当前异常的方法,C#将一个方法的所有信息封装在MethodBase类中, 返回是MethodBase的子类的对象。

MethodBase类位于System.Reflection命名空间中。
public abstract class MethodBase : MemberInfo:提供有关方法和构造函数的信息,
范例:
using System;
using System.Reflection;
public class Test3
{
    public static void TestException()
    {
        throw new Exception("报错异常");
        //当抛出异常时,先查看当前方法是否有try..catch(),如果有,就就地解决,如果没有,程序将自动将异常带回到方法的调用处,查看是否有try..catch,没有没有,程序将异常对象交给Main()方法,查看Main()是否有try..catch,没有,直接终止程序的运行,将异常抛向控制台
    }
    public static void Main(string[] args)
    {
        try
        {
            TestException();
        }
        catch (Exception e)
        {//接收抛出的所有类型的异常。
            MethodBase m = e.TargetSite;
            Console.WriteLine("报出异常的方法为:" + m.Name);
            Console.WriteLine("方法所属于的类为:" + m.DeclaringType.ToString());
            Console.WriteLine("方法是否为static:" + m.IsStatic);
            Console.WriteLine("方法是否为公有的:" + m.IsPublic);
            Console.WriteLine("方法是否是抽象的:" + m.IsAbstract);
        }
    }
}

Exception:
  SystemException :C#自带的异常类
  ApplicationException :用户自定义的异常类的根类。
  C#2.0中,自定义的类可以直接继承Exception
注意:
  一旦继承乐Exception:
  1. 在自定义的异常类中定义三个构建器。
  2.覆盖父类的Message属性,在原始的Message属性数值的前面或后面加上一些重要的注释代码

问题:
  需要设置一种方式:
   不管是否抛出异常,都需要执行某段代码。
使用finally进行清理。
      1。对于一些代码,可能会希望无论try块中是否有异常抛出, 最终都能得到执行,比如变量的回收,此时,可以使用finally子句.
      2。Finally子句既可和try关键字单独搭配使用,也可以与try..catch语句共同使用。
      3。有异常时,在执行了匹配的catch()包含的语句后执行,没有异常时,在try中包含的所有语句执行完后执行)。
      4。为了让内存中的变量不管是否发生异常都能达到收回的效果,可以在异常处理程序后加上finally子句。
范例:
using System;
public class Test4
{
    public static void Main(string[] args)
    {
        string name = Console.ReadLine();
        try
        {
            if (name.Trim() == "")
            {
                TeamCustomException te = new TeamCustomException("员工的姓名不能为null");
                te.TeamName = "团队1";
                throw te;
            }
            else
            {
                Console.WriteLine(name);
            }
        }
        catch (Exception e)
        {
            Console.WriteLine(e.Message);
        }
        finally
        {//无论try中是否有异常抛出,在抛出异常前,执行的代码。
            name = null;
            Console.WriteLine("ff");
        }
    }
}
public class TeamCustomException : Exception
{
    private string teamName;

    public string TeamName
    {
        get { return teamName; }
        set { teamName = value; }
    }
    public override string Message
    {
        get
        {
            return teamName+":"+base.Message;
        }
    }
    public TeamCustomException()
        : base()
    {//让父类的构建器帮我们初始化父类中定义的所有变量。
        logException();
    }
    public TeamCustomException(string info)
        : base("发生的错误信息:" + info)
    {
        logException();
    }
    //public CustomException(string info, Exception innerException)
    //    : base("发生的错误信息:" + info, innerException)
    //{
    //    logException();
    //}
    private void logException()
    {//日志的记录
        Console.WriteLine("记录当前发生的错误信息到日志中");
    }
}

问题:finally语句中是否可以放置任何的语句呢?
在finally子句中,不能放置break,return等跳出当前控制程序的关键字,否则系统将抛出:控制不能离开 finally 子句主体的错误。

如何在程序中,设计:所有的异常在统一的地方进行捕获?
Main()方法中捕获所有的异常。
解决:异常的嵌套。--异常中包含异常对象。
范例:
using System;
public class Test4
{
    public static void Main(string[] args)
    {
        string name = Console.ReadLine();
        try
        {
            if (name.Trim() == "")
            {
                TeamCustomException te = new TeamCustomException("员工的姓名不能为null");
                te.TeamName = "团队1";
                throw new Exception("TeamCustomException", te);
            }
            else
            {
                Console.WriteLine(name);
            }
        }
        catch (Exception e)
        {
            Console.WriteLine(e.Message);
            Exception yuan = e.InnerException; //返回异常对象中包含的原始异常类对象。
            Console.WriteLine(yuan.Message);
        }
        finally
        {//无论try中是否有异常抛出,在抛出异常前,执行的代码。
            name = null;
            Console.WriteLine("ff");
        }
    }
}
public class TeamCustomException : Exception
{
    private string teamName;

    public string TeamName
    {
        get { return teamName; }
        set { teamName = value; }
    }
    public override string Message
    {
        get
        {
            return teamName+":"+base.Message;
        }
    }
    public TeamCustomException()
        : base()
    {//让父类的构建器帮我们初始化父类中定义的所有变量。
        logException();
    }
    public TeamCustomException(string info)
        : base("发生的错误信息:" + info)
    {
        logException();
    }
    //public CustomException(string info, Exception innerException)
    //    : base("发生的错误信息:" + info, innerException)
    //{
    //    logException();
    //}
    private void logException()
    {//日志的记录
        Console.WriteLine("记录当前发生的错误信息到日志中");
    }
}

问题:为了统一整个项目中所有的异常类型,要求程序员必须抛出自定义的异常类(CustomException),这样的优势是为了让程序整洁和简化,因为每个try后面都只有一个catch()即可,但这样做会造成一个问题:不能获取程序中原始发生的异常对象。
怎么才能两全奇美呢?解决思路:
1. 使用父类Exception的特定构建器:
      public Exception ( string message, Exception innerException ):使用指定错误信息(可以通过Message属性获取)和对作为此异常原因的内部异常的引用来初始化 Exception类的新实例,目的是将程序原发生的异常封装在Exception类对象中。
2. 在捕获异常后,使用Exception的属性提取包含在内部的异常。
public Exception InnerException { get; } :获取导致当前异常的 Exception实例。
范例:
using System;
using System.IO;
public class Test3
{
    public static void ReadArticle(string n)
    {
        if (n == null || n.Trim() == "")
        {
           FileNotFoundException e = new FileNotFoundException("文件名为空");
           e.HelpLink = "error.aspx"; //指定错误的页面
           e.Source = "文件读取程序块中(ReadArticle)";
           CustomException c = new CustomException("文件读取", e); //包含原始异常类(因由类)
           throw c;
        }
        else
        {
            //读取文件内容。
        }

    }
    public static void Main(string[] args)
    {
        try
        {
            ReadArticle(null);
        }
        catch (CustomException e)
        {//接收抛出的所有类型的异常。
            Exception inn = e.InnerException;
            Console.WriteLine("错误的信息:"+e.Message);
            Console.WriteLine("错误的源头信息:" + e.Source);
            Console.WriteLine("错误的堆栈信息:" + e.StackTrace);
            Console.WriteLine("错误的指向页面:" + e.HelpLink);
        }
    }
}
public class CustomException : Exception
{

    public CustomException(string n, Exception e):base(n,e)
    {

    }
}

异常的概念:
在C#中,异常就是发生错误的带名词,即一旦有错误,我们就认为程序发生了异常。
     比较专业的解释:  异常实际上是程序中错误导致中断了正常的指令流的一种事件.(你可以认为异常是任何中断正常程序流程的错误条件)。
     产生异常的条件:
     1:想打开的文件不存在
     2:网络连接中断
     3:代码错误
     。。。。

由于C#是面向对象,所有所有的错误被封装在异常对象中
一旦错误发生,将接收到一个特定的异常对象。
异常和普通问题的区别:
1:在编译上,还是在执行发生。
2:语法错误,还是逻辑错误。
普通问题:编译上,语法错误。
异常:执行,逻辑错误,会产生异常对象。
基本异常
    “异常情形”(异常条件)是指引发阻止当前方法或作用域继续执行的问题。
     对异常情形和普通问题进行区分是很重要的:
     1。所谓的普通问题是指:在当前环境下不能得到足够的信息,比如语法错误,此时错误将会向外传递,而且系统也总能处理这样的错误。
     2。而对于异常情形:表示是让程序不能继续执行下去的错误,因为在当前环境下无法获得必要的信息来解决问题。你所能做的是从当前环境跳出,并且把问题提交给处理他的程序,这就是抛出异常时所发生的事情。 

当异常发生时,如何处理:
使用:异常处理器(程序):对于程序中出现的异常,在C#中是使用一种被称为“异常处理器(程序)”的错误捕获机制来进行处理的, 你可以认为异常处理器(程序)就是发生错误时,能够接受并处理错误的接受者和处理地!

异常类的分支。
  所有的异常类都是Exception的子类
异常类的分类:
1.c#自带的异常类.  --->使用SystemException类下的子类
    2. 人工创建异常类。-->创建的类一定要继承ApplicationException类,net.2.0技术中,人工创建异常类可以直接继承Exception

SystemException:由.net FrameWork提供并由系统抛出的异常,不过这些异常也可以从你的方法体中抛出。常见的子异常类有:
    除数为0时的: DivideByZeroException
   在向方法提供的其中一个参数无效时引发的异常:ArgumentException
   当试图在数组中存储类型不正确的元素时引发的异常:ArrayTypeMismatchException
      。。。。。
        属于运行时异常的类型有很多,一般通用的识别他们的规则是:由编程导致的错误。他们会自动被.net 抛出,尽管可以不写,但有时为了在错误后,可以更准确的确定错误的原因,还是应该在程序中显示的抛出此类型的异常,记住:如果出现此类型的异常,则一定是你的程序错误了。

范例:
using System;
using System.Reflection;
using System.Collections;
public class Test3
{
    public static void Main(String[] args)
        {
            DevideTest t = new DevideTest();
            t.First = -1;
        }
}
public class DevideTest
{
    private double first;

    public double First
    {
        get { return first; }
        set
        {
            try
            {//try中放置可能发生错误的代码,一旦发生,程序将停止执行,根据错误信息产生异常对象,并且将异常对象传递给类型匹配的catch(),
                if (value < 0)
                {
                    throw new Exception("不能给出0一下的数字");
                }
                else
                {

                    first = value;
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
                //Message返回异常对象中包含的错误信息
            }
        }
    }
    private double second;

    public double Second
    {
        get { return second; }
        set { second = value; }
    }

}

System.Exception类的结构和成员。
构建器:
public Exception():初始化Exception类的新实例。
public Exception(string message):使用指定的错误信息初始化 Exception类的新实例。
public Exception(string message, Exception innerException):使用指定错误信息和对作为此异常原因的内部异常的引用来初始化 Exception类的新实例。
属性以及索引器:
public virtual string HelpLink{ get; set; }:获取或设置指向此异常所关联帮助文件的链接的url地址(可以是统一资源名称 (URN) 或统一资源定位器 (URL)),或包含一个解释该异常的网页的引用。
public virtual string Message{ get; }:获取描述当前异常的消息,这个属性是只读的,并且只能调用接收字符串作为参数的构建器来初始化他。
public virtual string Source{get; set;}:获取或设置导致错误的应用程序或对象的名称。
public virtual string StackTrace{get;}:获取当前异常发生时调用堆栈上的帧的字符串表示形式。
范例:
using System;
using System.IO;
public class Test3
{
    public static void Main(String[] args)
    {
        try
        {
            Exception e = new Exception("发生的错误");
            e.Source = "Main()方法发生";
            throw e;  //将异常对象抛出
            Console.WriteLine("ok");
        }
        catch (Exception e)
        {
            Console.WriteLine(e.Message);
            Console.WriteLine(e.Source);
            Console.WriteLine(e.StackTrace);
        }
    }
}

如何一段代码中可能抛出异常的类型有很多,如何精确的捕获对应异常?
范例:
using System;
using System.IO;
public class Test3
{
    public static void Main(String[] args)
    {
        try
        {
            //IndexOutOfRangeException
            ArrayTypeMismatchException e = new ArrayTypeMismatchException("发生的错误");
            e.Source = "Main()方法发生";
            throw e;  //将异常对象抛出
            //Console.WriteLine("ok");
        }
        catch(ArrayTypeMismatchException e)
        {//一旦匹配,就不再继续向下做匹配的工作,程序会退出整个try{}catch{}语句
            Console.WriteLine(e.GetType().ToString());
            Console.WriteLine(e.Message);
            Console.WriteLine(e.Source);
            Console.WriteLine(e.StackTrace);
            }
        catch(IndexOutOfRangeException e)
        {
            Console.WriteLine(e.GetType().ToString());
            Console.WriteLine(e.Message);
            Console.WriteLine(e.Source);
            Console.WriteLine(e.StackTrace);
        }
        catch (Exception e)
        {//1.起到最终捕获异常类对象的效果。
         //2. 为前面的精确捕获打下铺垫。
            Console.WriteLine(e.GetType().ToString());
            Console.WriteLine(e.Message);
            Console.WriteLine(e.Source);
            Console.WriteLine(e.StackTrace);
        }
        //
    }
}

注意:异常处理程序必须紧跟在try块之后,当异常被抛出时,异常处理机制将负责搜寻参数与异常类型类型相匹配的第一处理程序,然后进入catch子句执行,此时认为异常得到了处理,一旦catch子句结束,则处理程序的查找过程结束。注意,只有匹配的catch子句才能得到执行。这与switch语句不同(case语句都有break,以避免执行后续的case子句)。

凡是返回抽象类或接口类型的方法或属性,注意:真实返回的是实现接口或继承乐抽象类子类对象
获取产生异常的方法
public MethodBase TargetSite { get; } :获取引发当前异常的方法,C#将一个方法的所有信息封装在MethodBase类中, 返回是MethodBase的子类的对象。

MethodBase类位于System.Reflection命名空间中。
public abstract class MethodBase : MemberInfo:提供有关方法和构造函数的信息,
范例:
using System;
using System.Reflection;
public class Test3
{
    public static void TestException()
    {
        throw new Exception("报错异常");
        //当抛出异常时,先查看当前方法是否有try..catch(),如果有,就就地解决,如果没有,程序将自动将异常带回到方法的调用处,查看是否有try..catch,没有没有,程序将异常对象交给Main()方法,查看Main()是否有try..catch,没有,直接终止程序的运行,将异常抛向控制台
    }
    public static void Main(string[] args)
    {
        try
        {
            TestException();
        }
        catch (Exception e)
        {//接收抛出的所有类型的异常。
            MethodBase m = e.TargetSite;
            Console.WriteLine("报出异常的方法为:" + m.Name);
            Console.WriteLine("方法所属于的类为:" + m.DeclaringType.ToString());
            Console.WriteLine("方法是否为static:" + m.IsStatic);
            Console.WriteLine("方法是否为公有的:" + m.IsPublic);
            Console.WriteLine("方法是否是抽象的:" + m.IsAbstract);
        }
    }
}

Exception:
  SystemException :C#自带的异常类
  ApplicationException :用户自定义的异常类的根类。
  C#2.0中,自定义的类可以直接继承Exception
注意:
  一旦继承乐Exception:
  1. 在自定义的异常类中定义三个构建器。
  2.覆盖父类的Message属性,在原始的Message属性数值的前面或后面加上一些重要的注释代码

问题:
  需要设置一种方式:
   不管是否抛出异常,都需要执行某段代码。
使用finally进行清理。
      1。对于一些代码,可能会希望无论try块中是否有异常抛出, 最终都能得到执行,比如变量的回收,此时,可以使用finally子句.
      2。Finally子句既可和try关键字单独搭配使用,也可以与try..catch语句共同使用。
      3。有异常时,在执行了匹配的catch()包含的语句后执行,没有异常时,在try中包含的所有语句执行完后执行)。
      4。为了让内存中的变量不管是否发生异常都能达到收回的效果,可以在异常处理程序后加上finally子句。
范例:
using System;
public class Test4
{
    public static void Main(string[] args)
    {
        string name = Console.ReadLine();
        try
        {
            if (name.Trim() == "")
            {
                TeamCustomException te = new TeamCustomException("员工的姓名不能为null");
                te.TeamName = "团队1";
                throw te;
            }
            else
            {
                Console.WriteLine(name);
            }
        }
        catch (Exception e)
        {
            Console.WriteLine(e.Message);
        }
        finally
        {//无论try中是否有异常抛出,在抛出异常前,执行的代码。
            name = null;
            Console.WriteLine("ff");
        }
    }
}
public class TeamCustomException : Exception
{
    private string teamName;

    public string TeamName
    {
        get { return teamName; }
        set { teamName = value; }
    }
    public override string Message
    {
        get
        {
            return teamName+":"+base.Message;
        }
    }
    public TeamCustomException()
        : base()
    {//让父类的构建器帮我们初始化父类中定义的所有变量。
        logException();
    }
    public TeamCustomException(string info)
        : base("发生的错误信息:" + info)
    {
        logException();
    }
    //public CustomException(string info, Exception innerException)
    //    : base("发生的错误信息:" + info, innerException)
    //{
    //    logException();
    //}
    private void logException()
    {//日志的记录
        Console.WriteLine("记录当前发生的错误信息到日志中");
    }
}

问题:finally语句中是否可以放置任何的语句呢?
在finally子句中,不能放置break,return等跳出当前控制程序的关键字,否则系统将抛出:控制不能离开 finally 子句主体的错误。

如何在程序中,设计:所有的异常在统一的地方进行捕获?
Main()方法中捕获所有的异常。
解决:异常的嵌套。--异常中包含异常对象。
范例:
using System;
public class Test4
{
    public static void Main(string[] args)
    {
        string name = Console.ReadLine();
        try
        {
            if (name.Trim() == "")
            {
                TeamCustomException te = new TeamCustomException("员工的姓名不能为null");
                te.TeamName = "团队1";
                throw new Exception("TeamCustomException", te);
            }
            else
            {
                Console.WriteLine(name);
            }
        }
        catch (Exception e)
        {
            Console.WriteLine(e.Message);
            Exception yuan = e.InnerException; //返回异常对象中包含的原始异常类对象。
            Console.WriteLine(yuan.Message);
        }
        finally
        {//无论try中是否有异常抛出,在抛出异常前,执行的代码。
            name = null;
            Console.WriteLine("ff");
        }
    }
}
public class TeamCustomException : Exception
{
    private string teamName;

    public string TeamName
    {
        get { return teamName; }
        set { teamName = value; }
    }
    public override string Message
    {
        get
        {
            return teamName+":"+base.Message;
        }
    }
    public TeamCustomException()
        : base()
    {//让父类的构建器帮我们初始化父类中定义的所有变量。
        logException();
    }
    public TeamCustomException(string info)
        : base("发生的错误信息:" + info)
    {
        logException();
    }
    //public CustomException(string info, Exception innerException)
    //    : base("发生的错误信息:" + info, innerException)
    //{
    //    logException();
    //}
    private void logException()
    {//日志的记录
        Console.WriteLine("记录当前发生的错误信息到日志中");
    }
}

问题:为了统一整个项目中所有的异常类型,要求程序员必须抛出自定义的异常类(CustomException),这样的优势是为了让程序整洁和简化,因为每个try后面都只有一个catch()即可,但这样做会造成一个问题:不能获取程序中原始发生的异常对象。
怎么才能两全奇美呢?解决思路:
1. 使用父类Exception的特定构建器:
      public Exception ( string message, Exception innerException ):使用指定错误信息(可以通过Message属性获取)和对作为此异常原因的内部异常的引用来初始化 Exception类的新实例,目的是将程序原发生的异常封装在Exception类对象中。
2. 在捕获异常后,使用Exception的属性提取包含在内部的异常。
public Exception InnerException { get; } :获取导致当前异常的 Exception实例。
范例:
using System;
using System.IO;
public class Test3
{
    public static void ReadArticle(string n)
    {
        if (n == null || n.Trim() == "")
        {
           FileNotFoundException e = new FileNotFoundException("文件名为空");
           e.HelpLink = "error.aspx"; //指定错误的页面
           e.Source = "文件读取程序块中(ReadArticle)";
           CustomException c = new CustomException("文件读取", e); //包含原始异常类(因由类)
           throw c;
        }
        else
        {
            //读取文件内容。
        }

    }
    public static void Main(string[] args)
    {
        try
        {
            ReadArticle(null);
        }
        catch (CustomException e)
        {//接收抛出的所有类型的异常。
            Exception inn = e.InnerException;
            Console.WriteLine("错误的信息:"+e.Message);
            Console.WriteLine("错误的源头信息:" + e.Source);
            Console.WriteLine("错误的堆栈信息:" + e.StackTrace);
            Console.WriteLine("错误的指向页面:" + e.HelpLink);
        }
    }
}
public class CustomException : Exception
{

    public CustomException(string n, Exception e):base(n,e)
    {

    }
}

异常的概念:
在C#中,异常就是发生错误的带名词,即一旦有错误,我们就认为程序发生了异常。
     比较专业的解释:  异常实际上是程序中错误导致中断了正常的指令流的一种事件.(你可以认为异常是任何中断正常程序流程的错误条件)。
     产生异常的条件:
     1:想打开的文件不存在
     2:网络连接中断
     3:代码错误
     。。。。

由于C#是面向对象,所有所有的错误被封装在异常对象中
一旦错误发生,将接收到一个特定的异常对象。
异常和普通问题的区别:
1:在编译上,还是在执行发生。
2:语法错误,还是逻辑错误。
普通问题:编译上,语法错误。
异常:执行,逻辑错误,会产生异常对象。
基本异常
    “异常情形”(异常条件)是指引发阻止当前方法或作用域继续执行的问题。
     对异常情形和普通问题进行区分是很重要的:
     1。所谓的普通问题是指:在当前环境下不能得到足够的信息,比如语法错误,此时错误将会向外传递,而且系统也总能处理这样的错误。
     2。而对于异常情形:表示是让程序不能继续执行下去的错误,因为在当前环境下无法获得必要的信息来解决问题。你所能做的是从当前环境跳出,并且把问题提交给处理他的程序,这就是抛出异常时所发生的事情。 

当异常发生时,如何处理:
使用:异常处理器(程序):对于程序中出现的异常,在C#中是使用一种被称为“异常处理器(程序)”的错误捕获机制来进行处理的, 你可以认为异常处理器(程序)就是发生错误时,能够接受并处理错误的接受者和处理地!

异常类的分支。
  所有的异常类都是Exception的子类
异常类的分类:
1.c#自带的异常类.  --->使用SystemException类下的子类
    2. 人工创建异常类。-->创建的类一定要继承ApplicationException类,net.2.0技术中,人工创建异常类可以直接继承Exception

SystemException:由.net FrameWork提供并由系统抛出的异常,不过这些异常也可以从你的方法体中抛出。常见的子异常类有:
    除数为0时的: DivideByZeroException
   在向方法提供的其中一个参数无效时引发的异常:ArgumentException
   当试图在数组中存储类型不正确的元素时引发的异常:ArrayTypeMismatchException
      。。。。。
        属于运行时异常的类型有很多,一般通用的识别他们的规则是:由编程导致的错误。他们会自动被.net 抛出,尽管可以不写,但有时为了在错误后,可以更准确的确定错误的原因,还是应该在程序中显示的抛出此类型的异常,记住:如果出现此类型的异常,则一定是你的程序错误了。

范例:
using System;
using System.Reflection;
using System.Collections;
public class Test3
{
    public static void Main(String[] args)
        {
            DevideTest t = new DevideTest();
            t.First = -1;
        }
}
public class DevideTest
{
    private double first;

    public double First
    {
        get { return first; }
        set
        {
            try
            {//try中放置可能发生错误的代码,一旦发生,程序将停止执行,根据错误信息产生异常对象,并且将异常对象传递给类型匹配的catch(),
                if (value < 0)
                {
                    throw new Exception("不能给出0一下的数字");
                }
                else
                {

                    first = value;
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
                //Message返回异常对象中包含的错误信息
            }
        }
    }
    private double second;

    public double Second
    {
        get { return second; }
        set { second = value; }
    }

}

System.Exception类的结构和成员。
构建器:
public Exception():初始化Exception类的新实例。
public Exception(string message):使用指定的错误信息初始化 Exception类的新实例。
public Exception(string message, Exception innerException):使用指定错误信息和对作为此异常原因的内部异常的引用来初始化 Exception类的新实例。
属性以及索引器:
public virtual string HelpLink{ get; set; }:获取或设置指向此异常所关联帮助文件的链接的url地址(可以是统一资源名称 (URN) 或统一资源定位器 (URL)),或包含一个解释该异常的网页的引用。
public virtual string Message{ get; }:获取描述当前异常的消息,这个属性是只读的,并且只能调用接收字符串作为参数的构建器来初始化他。
public virtual string Source{get; set;}:获取或设置导致错误的应用程序或对象的名称。
public virtual string StackTrace{get;}:获取当前异常发生时调用堆栈上的帧的字符串表示形式。
范例:
using System;
using System.IO;
public class Test3
{
    public static void Main(String[] args)
    {
        try
        {
            Exception e = new Exception("发生的错误");
            e.Source = "Main()方法发生";
            throw e;  //将异常对象抛出
            Console.WriteLine("ok");
        }
        catch (Exception e)
        {
            Console.WriteLine(e.Message);
            Console.WriteLine(e.Source);
            Console.WriteLine(e.StackTrace);
        }
    }
}

如何一段代码中可能抛出异常的类型有很多,如何精确的捕获对应异常?
范例:
using System;
using System.IO;
public class Test3
{
    public static void Main(String[] args)
    {
        try
        {
            //IndexOutOfRangeException
            ArrayTypeMismatchException e = new ArrayTypeMismatchException("发生的错误");
            e.Source = "Main()方法发生";
            throw e;  //将异常对象抛出
            //Console.WriteLine("ok");
        }
        catch(ArrayTypeMismatchException e)
        {//一旦匹配,就不再继续向下做匹配的工作,程序会退出整个try{}catch{}语句
            Console.WriteLine(e.GetType().ToString());
            Console.WriteLine(e.Message);
            Console.WriteLine(e.Source);
            Console.WriteLine(e.StackTrace);
            }
        catch(IndexOutOfRangeException e)
        {
            Console.WriteLine(e.GetType().ToString());
            Console.WriteLine(e.Message);
            Console.WriteLine(e.Source);
            Console.WriteLine(e.StackTrace);
        }
        catch (Exception e)
        {//1.起到最终捕获异常类对象的效果。
         //2. 为前面的精确捕获打下铺垫。
            Console.WriteLine(e.GetType().ToString());
            Console.WriteLine(e.Message);
            Console.WriteLine(e.Source);
            Console.WriteLine(e.StackTrace);
        }
        //
    }
}

注意:异常处理程序必须紧跟在try块之后,当异常被抛出时,异常处理机制将负责搜寻参数与异常类型类型相匹配的第一处理程序,然后进入catch子句执行,此时认为异常得到了处理,一旦catch子句结束,则处理程序的查找过程结束。注意,只有匹配的catch子句才能得到执行。这与switch语句不同(case语句都有break,以避免执行后续的case子句)。

凡是返回抽象类或接口类型的方法或属性,注意:真实返回的是实现接口或继承乐抽象类子类对象
获取产生异常的方法
public MethodBase TargetSite { get; } :获取引发当前异常的方法,C#将一个方法的所有信息封装在MethodBase类中, 返回是MethodBase的子类的对象。

MethodBase类位于System.Reflection命名空间中。
public abstract class MethodBase : MemberInfo:提供有关方法和构造函数的信息,
范例:
using System;
using System.Reflection;
public class Test3
{
    public static void TestException()
    {
        throw new Exception("报错异常");
        //当抛出异常时,先查看当前方法是否有try..catch(),如果有,就就地解决,如果没有,程序将自动将异常带回到方法的调用处,查看是否有try..catch,没有没有,程序将异常对象交给Main()方法,查看Main()是否有try..catch,没有,直接终止程序的运行,将异常抛向控制台
    }
    public static void Main(string[] args)
    {
        try
        {
            TestException();
        }
        catch (Exception e)
        {//接收抛出的所有类型的异常。
            MethodBase m = e.TargetSite;
            Console.WriteLine("报出异常的方法为:" + m.Name);
            Console.WriteLine("方法所属于的类为:" + m.DeclaringType.ToString());
            Console.WriteLine("方法是否为static:" + m.IsStatic);
            Console.WriteLine("方法是否为公有的:" + m.IsPublic);
            Console.WriteLine("方法是否是抽象的:" + m.IsAbstract);
        }
    }
}

Exception:
  SystemException :C#自带的异常类
  ApplicationException :用户自定义的异常类的根类。
  C#2.0中,自定义的类可以直接继承Exception
注意:
  一旦继承乐Exception:
  1. 在自定义的异常类中定义三个构建器。
  2.覆盖父类的Message属性,在原始的Message属性数值的前面或后面加上一些重要的注释代码

问题:
  需要设置一种方式:
   不管是否抛出异常,都需要执行某段代码。
使用finally进行清理。
      1。对于一些代码,可能会希望无论try块中是否有异常抛出, 最终都能得到执行,比如变量的回收,此时,可以使用finally子句.
      2。Finally子句既可和try关键字单独搭配使用,也可以与try..catch语句共同使用。
      3。有异常时,在执行了匹配的catch()包含的语句后执行,没有异常时,在try中包含的所有语句执行完后执行)。
      4。为了让内存中的变量不管是否发生异常都能达到收回的效果,可以在异常处理程序后加上finally子句。
范例:
using System;
public class Test4
{
    public static void Main(string[] args)
    {
        string name = Console.ReadLine();
        try
        {
            if (name.Trim() == "")
            {
                TeamCustomException te = new TeamCustomException("员工的姓名不能为null");
                te.TeamName = "团队1";
                throw te;
            }
            else
            {
                Console.WriteLine(name);
            }
        }
        catch (Exception e)
        {
            Console.WriteLine(e.Message);
        }
        finally
        {//无论try中是否有异常抛出,在抛出异常前,执行的代码。
            name = null;
            Console.WriteLine("ff");
        }
    }
}
public class TeamCustomException : Exception
{
    private string teamName;

    public string TeamName
    {
        get { return teamName; }
        set { teamName = value; }
    }
    public override string Message
    {
        get
        {
            return teamName+":"+base.Message;
        }
    }
    public TeamCustomException()
        : base()
    {//让父类的构建器帮我们初始化父类中定义的所有变量。
        logException();
    }
    public TeamCustomException(string info)
        : base("发生的错误信息:" + info)
    {
        logException();
    }
    //public CustomException(string info, Exception innerException)
    //    : base("发生的错误信息:" + info, innerException)
    //{
    //    logException();
    //}
    private void logException()
    {//日志的记录
        Console.WriteLine("记录当前发生的错误信息到日志中");
    }
}

问题:finally语句中是否可以放置任何的语句呢?
在finally子句中,不能放置break,return等跳出当前控制程序的关键字,否则系统将抛出:控制不能离开 finally 子句主体的错误。

如何在程序中,设计:所有的异常在统一的地方进行捕获?
Main()方法中捕获所有的异常。
解决:异常的嵌套。--异常中包含异常对象。
范例:
using System;
public class Test4
{
    public static void Main(string[] args)
    {
        string name = Console.ReadLine();
        try
        {
            if (name.Trim() == "")
            {
                TeamCustomException te = new TeamCustomException("员工的姓名不能为null");
                te.TeamName = "团队1";
                throw new Exception("TeamCustomException", te);
            }
            else
            {
                Console.WriteLine(name);
            }
        }
        catch (Exception e)
        {
            Console.WriteLine(e.Message);
            Exception yuan = e.InnerException; //返回异常对象中包含的原始异常类对象。
            Console.WriteLine(yuan.Message);
        }
        finally
        {//无论try中是否有异常抛出,在抛出异常前,执行的代码。
            name = null;
            Console.WriteLine("ff");
        }
    }
}
public class TeamCustomException : Exception
{
    private string teamName;

    public string TeamName
    {
        get { return teamName; }
        set { teamName = value; }
    }
    public override string Message
    {
        get
        {
            return teamName+":"+base.Message;
        }
    }
    public TeamCustomException()
        : base()
    {//让父类的构建器帮我们初始化父类中定义的所有变量。
        logException();
    }
    public TeamCustomException(string info)
        : base("发生的错误信息:" + info)
    {
        logException();
    }
    //public CustomException(string info, Exception innerException)
    //    : base("发生的错误信息:" + info, innerException)
    //{
    //    logException();
    //}
    private void logException()
    {//日志的记录
        Console.WriteLine("记录当前发生的错误信息到日志中");
    }
}

问题:为了统一整个项目中所有的异常类型,要求程序员必须抛出自定义的异常类(CustomException),这样的优势是为了让程序整洁和简化,因为每个try后面都只有一个catch()即可,但这样做会造成一个问题:不能获取程序中原始发生的异常对象。
怎么才能两全奇美呢?解决思路:
1. 使用父类Exception的特定构建器:
      public Exception ( string message, Exception innerException ):使用指定错误信息(可以通过Message属性获取)和对作为此异常原因的内部异常的引用来初始化 Exception类的新实例,目的是将程序原发生的异常封装在Exception类对象中。
2. 在捕获异常后,使用Exception的属性提取包含在内部的异常。
public Exception InnerException { get; } :获取导致当前异常的 Exception实例。
范例:
using System;
using System.IO;
public class Test3
{
    public static void ReadArticle(string n)
    {
        if (n == null || n.Trim() == "")
        {
           FileNotFoundException e = new FileNotFoundException("文件名为空");
           e.HelpLink = "error.aspx"; //指定错误的页面
           e.Source = "文件读取程序块中(ReadArticle)";
           CustomException c = new CustomException("文件读取", e); //包含原始异常类(因由类)
           throw c;
        }
        else
        {
            //读取文件内容。
        }

    }
    public static void Main(string[] args)
    {
        try
        {
            ReadArticle(null);
        }
        catch (CustomException e)
        {//接收抛出的所有类型的异常。
            Exception inn = e.InnerException;
            Console.WriteLine("错误的信息:"+e.Message);
            Console.WriteLine("错误的源头信息:" + e.Source);
            Console.WriteLine("错误的堆栈信息:" + e.StackTrace);
            Console.WriteLine("错误的指向页面:" + e.HelpLink);
        }
    }
}
public class CustomException : Exception
{

    public CustomException(string n, Exception e):base(n,e)
    {

    }
}

异常的概念:
在C#中,异常就是发生错误的带名词,即一旦有错误,我们就认为程序发生了异常。
     比较专业的解释:  异常实际上是程序中错误导致中断了正常的指令流的一种事件.(你可以认为异常是任何中断正常程序流程的错误条件)。
     产生异常的条件:
     1:想打开的文件不存在
     2:网络连接中断
     3:代码错误
     。。。。

由于C#是面向对象,所有所有的错误被封装在异常对象中
一旦错误发生,将接收到一个特定的异常对象。
异常和普通问题的区别:
1:在编译上,还是在执行发生。
2:语法错误,还是逻辑错误。
普通问题:编译上,语法错误。
异常:执行,逻辑错误,会产生异常对象。
基本异常
    “异常情形”(异常条件)是指引发阻止当前方法或作用域继续执行的问题。
     对异常情形和普通问题进行区分是很重要的:
     1。所谓的普通问题是指:在当前环境下不能得到足够的信息,比如语法错误,此时错误将会向外传递,而且系统也总能处理这样的错误。
     2。而对于异常情形:表示是让程序不能继续执行下去的错误,因为在当前环境下无法获得必要的信息来解决问题。你所能做的是从当前环境跳出,并且把问题提交给处理他的程序,这就是抛出异常时所发生的事情。

当异常发生时,如何处理:
使用:异常处理器(程序):对于程序中出现的异常,在C#中是使用一种被称为“异常处理器(程序)”的错误捕获机制来进行处理的, 你可以认为异常处理器(程序)就是发生错误时,能够接受并处理错误的接受者和处理地!

异常类的分支。
  所有的异常类都是Exception的子类
异常类的分类:
1.c#自带的异常类.  --->使用SystemException类下的子类
    2. 人工创建异常类。-->创建的类一定要继承ApplicationException类,net.2.0技术中,人工创建异常类可以直接继承Exception

SystemException:由.net FrameWork提供并由系统抛出的异常,不过这些异常也可以从你的方法体中抛出。常见的子异常类有:
    除数为0时的: DivideByZeroException
   在向方法提供的其中一个参数无效时引发的异常:ArgumentException
   当试图在数组中存储类型不正确的元素时引发的异常:ArrayTypeMismatchException
      。。。。。
        属于运行时异常的类型有很多,一般通用的识别他们的规则是:由编程导致的错误。他们会自动被.net 抛出,尽管可以不写,但有时为了在错误后,可以更准确的确定错误的原因,还是应该在程序中显示的抛出此类型的异常,记住:如果出现此类型的异常,则一定是你的程序错误了。

范例:
using System;
using System.Reflection;
using System.Collections;
public class Test3
{
    public static void Main(String[] args)
        {
            DevideTest t = new DevideTest();
            t.First = -1;
        }
}
public class DevideTest
{
    private double first;

    public double First
    {
        get { return first; }
        set
        {
            try
            {//try中放置可能发生错误的代码,一旦发生,程序将停止执行,根据错误信息产生异常对象,并且将异常对象传递给类型匹配的catch(),
                if (value < 0)
                {
                    throw new Exception("不能给出0一下的数字");
                }
                else
                {

                    first = value;
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
                //Message返回异常对象中包含的错误信息
            }
        }
    }
    private double second;

    public double Second
    {
        get { return second; }
        set { second = value; }
    }

}

System.Exception类的结构和成员。
构建器:
public Exception():初始化Exception类的新实例。
public Exception(string message):使用指定的错误信息初始化 Exception类的新实例。
public Exception(string message, Exception innerException):使用指定错误信息和对作为此异常原因的内部异常的引用来初始化 Exception类的新实例。
属性以及索引器:
public virtual string HelpLink{ get; set; }:获取或设置指向此异常所关联帮助文件的链接的url地址(可以是统一资源名称 (URN) 或统一资源定位器 (URL)),或包含一个解释该异常的网页的引用。
public virtual string Message{ get; }:获取描述当前异常的消息,这个属性是只读的,并且只能调用接收字符串作为参数的构建器来初始化他。
public virtual string Source{get; set;}:获取或设置导致错误的应用程序或对象的名称。
public virtual string StackTrace{get;}:获取当前异常发生时调用堆栈上的帧的字符串表示形式。
范例:
using System;
using System.IO;
public class Test3
{
    public static void Main(String[] args)
    {
        try
        {
            Exception e = new Exception("发生的错误");
            e.Source = "Main()方法发生";
            throw e;  //将异常对象抛出
            Console.WriteLine("ok");
        }
        catch (Exception e)
        {
            Console.WriteLine(e.Message);
            Console.WriteLine(e.Source);
            Console.WriteLine(e.StackTrace);
        }
    }
}

如何一段代码中可能抛出异常的类型有很多,如何精确的捕获对应异常?
范例:
using System;
using System.IO;
public class Test3
{
    public static void Main(String[] args)
    {
        try
        {
            //IndexOutOfRangeException
            ArrayTypeMismatchException e = new ArrayTypeMismatchException("发生的错误");
            e.Source = "Main()方法发生";
            throw e;  //将异常对象抛出
            //Console.WriteLine("ok");
        }
        catch(ArrayTypeMismatchException e)
        {//一旦匹配,就不再继续向下做匹配的工作,程序会退出整个try{}catch{}语句
            Console.WriteLine(e.GetType().ToString());
            Console.WriteLine(e.Message);
            Console.WriteLine(e.Source);
            Console.WriteLine(e.StackTrace);
            }
        catch(IndexOutOfRangeException e)
        {
            Console.WriteLine(e.GetType().ToString());
            Console.WriteLine(e.Message);
            Console.WriteLine(e.Source);
            Console.WriteLine(e.StackTrace);
        }
        catch (Exception e)
        {//1.起到最终捕获异常类对象的效果。
         //2. 为前面的精确捕获打下铺垫。
            Console.WriteLine(e.GetType().ToString());
            Console.WriteLine(e.Message);
            Console.WriteLine(e.Source);
            Console.WriteLine(e.StackTrace);
        }
        //
    }
}

注意:异常处理程序必须紧跟在try块之后,当异常被抛出时,异常处理机制将负责搜寻参数与异常类型类型相匹配的第一处理程序,然后进入catch子句执行,此时认为异常得到了处理,一旦catch子句结束,则处理程序的查找过程结束。注意,只有匹配的catch子句才能得到执行。这与switch语句不同(case语句都有break,以避免执行后续的case子句)。

凡是返回抽象类或接口类型的方法或属性,注意:真实返回的是实现接口或继承乐抽象类子类对象
获取产生异常的方法
public MethodBase TargetSite { get; } :获取引发当前异常的方法,C#将一个方法的所有信息封装在MethodBase类中, 返回是MethodBase的子类的对象。

MethodBase类位于System.Reflection命名空间中。
public abstract class MethodBase : MemberInfo:提供有关方法和构造函数的信息,
范例:
using System;
using System.Reflection;
public class Test3
{
    public static void TestException()
    {
        throw new Exception("报错异常");
        //当抛出异常时,先查看当前方法是否有try..catch(),如果有,就就地解决,如果没有,程序将自动将异常带回到方法的调用处,查看是否有try..catch,没有没有,程序将异常对象交给Main()方法,查看Main()是否有try..catch,没有,直接终止程序的运行,将异常抛向控制台
    }
    public static void Main(string[] args)
    {
        try
        {
            TestException();
        }
        catch (Exception e)
        {//接收抛出的所有类型的异常。
            MethodBase m = e.TargetSite;
            Console.WriteLine("报出异常的方法为:" + m.Name);
            Console.WriteLine("方法所属于的类为:" + m.DeclaringType.ToString());
            Console.WriteLine("方法是否为static:" + m.IsStatic);
            Console.WriteLine("方法是否为公有的:" + m.IsPublic);
            Console.WriteLine("方法是否是抽象的:" + m.IsAbstract);
        }
    }
}

Exception:
  SystemException :C#自带的异常类
  ApplicationException :用户自定义的异常类的根类。
  C#2.0中,自定义的类可以直接继承Exception
注意:
  一旦继承乐Exception:
  1. 在自定义的异常类中定义三个构建器。
  2.覆盖父类的Message属性,在原始的Message属性数值的前面或后面加上一些重要的注释代码

问题:
  需要设置一种方式:
   不管是否抛出异常,都需要执行某段代码。
使用finally进行清理。
      1。对于一些代码,可能会希望无论try块中是否有异常抛出, 最终都能得到执行,比如变量的回收,此时,可以使用finally子句.
      2。Finally子句既可和try关键字单独搭配使用,也可以与try..catch语句共同使用。
      3。有异常时,在执行了匹配的catch()包含的语句后执行,没有异常时,在try中包含的所有语句执行完后执行)。
      4。为了让内存中的变量不管是否发生异常都能达到收回的效果,可以在异常处理程序后加上finally子句。
范例:
using System;
public class Test4
{
    public static void Main(string[] args)
    {
        string name = Console.ReadLine();
        try
        {
            if (name.Trim() == "")
            {
                TeamCustomException te = new TeamCustomException("员工的姓名不能为null");
                te.TeamName = "团队1";
                throw te;
            }
            else
            {
                Console.WriteLine(name);
            }
        }
        catch (Exception e)
        {
            Console.WriteLine(e.Message);
        }
        finally
        {//无论try中是否有异常抛出,在抛出异常前,执行的代码。
            name = null;
            Console.WriteLine("ff");
        }
    }
}
public class TeamCustomException : Exception
{
    private string teamName;

    public string TeamName
    {
        get { return teamName; }
        set { teamName = value; }
    }
    public override string Message
    {
        get
        {
            return teamName+":"+base.Message;
        }
    }
    public TeamCustomException()
        : base()
    {//让父类的构建器帮我们初始化父类中定义的所有变量。
        logException();
    }
    public TeamCustomException(string info)
        : base("发生的错误信息:" + info)
    {
        logException();
    }
    //public CustomException(string info, Exception innerException)
    //    : base("发生的错误信息:" + info, innerException)
    //{
    //    logException();
    //}
    private void logException()
    {//日志的记录
        Console.WriteLine("记录当前发生的错误信息到日志中");
    }
}

问题:finally语句中是否可以放置任何的语句呢?
在finally子句中,不能放置break,return等跳出当前控制程序的关键字,否则系统将抛出:控制不能离开 finally 子句主体的错误。

如何在程序中,设计:所有的异常在统一的地方进行捕获?
Main()方法中捕获所有的异常。
解决:异常的嵌套。--异常中包含异常对象。
范例:
using System;
public class Test4
{
    public static void Main(string[] args)
    {
        string name = Console.ReadLine();
        try
        {
            if (name.Trim() == "")
            {
                TeamCustomException te = new TeamCustomException("员工的姓名不能为null");
                te.TeamName = "团队1";
                throw new Exception("TeamCustomException", te);
            }
            else
            {
                Console.WriteLine(name);
            }
        }
        catch (Exception e)
        {
            Console.WriteLine(e.Message);
            Exception yuan = e.InnerException; //返回异常对象中包含的原始异常类对象。
            Console.WriteLine(yuan.Message);
        }
        finally
        {//无论try中是否有异常抛出,在抛出异常前,执行的代码。
            name = null;
            Console.WriteLine("ff");
        }
    }
}
public class TeamCustomException : Exception
{
    private string teamName;

    public string TeamName
    {
        get { return teamName; }
        set { teamName = value; }
    }
    public override string Message
    {
        get
        {
            return teamName+":"+base.Message;
        }
    }
    public TeamCustomException()
        : base()
    {//让父类的构建器帮我们初始化父类中定义的所有变量。
        logException();
    }
    public TeamCustomException(string info)
        : base("发生的错误信息:" + info)
    {
        logException();
    }
    //public CustomException(string info, Exception innerException)
    //    : base("发生的错误信息:" + info, innerException)
    //{
    //    logException();
    //}
    private void logException()
    {//日志的记录
        Console.WriteLine("记录当前发生的错误信息到日志中");
    }
}

问题:为了统一整个项目中所有的异常类型,要求程序员必须抛出自定义的异常类(CustomException),这样的优势是为了让程序整洁和简化,因为每个try后面都只有一个catch()即可,但这样做会造成一个问题:不能获取程序中原始发生的异常对象。
怎么才能两全奇美呢?解决思路:
1. 使用父类Exception的特定构建器:
      public Exception ( string message, Exception innerException ):使用指定错误信息(可以通过Message属性获取)和对作为此异常原因的内部异常的引用来初始化 Exception类的新实例,目的是将程序原发生的异常封装在Exception类对象中。
2. 在捕获异常后,使用Exception的属性提取包含在内部的异常。
public Exception InnerException { get; } :获取导致当前异常的 Exception实例。
范例:
using System;
using System.IO;
public class Test3
{
    public static void ReadArticle(string n)
    {
        if (n == null || n.Trim() == "")
        {
           FileNotFoundException e = new FileNotFoundException("文件名为空");
           e.HelpLink = "error.aspx"; //指定错误的页面
           e.Source = "文件读取程序块中(ReadArticle)";
           CustomException c = new CustomException("文件读取", e); //包含原始异常类(因由类)
           throw c;
        }
        else
        {
            //读取文件内容。
        }

    }
    public static void Main(string[] args)
    {
        try
        {
            ReadArticle(null);
        }
        catch (CustomException e)
        {//接收抛出的所有类型的异常。
            Exception inn = e.InnerException;
            Console.WriteLine("错误的信息:"+e.Message);
            Console.WriteLine("错误的源头信息:" + e.Source);
            Console.WriteLine("错误的堆栈信息:" + e.StackTrace);
            Console.WriteLine("错误的指向页面:" + e.HelpLink);
        }
    }
}
public class CustomException : Exception
{

    public CustomException(string n, Exception e):base(n,e)
    {

    }
}
原文地址:http://www.ffxun.com/Article/3/214.html

转载于:https://www.cnblogs.com/bear-sky/archive/2011/11/07/2239278.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值