在.net中,异常是跨语言的,意思就是在VB.NET中抛的异常是在C#中可以捕捉到的。这个是怎么作到的呢?如果要理解,还得从异常的基础说起,就从C#中异常处理开始吧。
1、Exception
Exception是所有异常类的父类,这个类没有什么特别的,唯一不同的就是在.net中指定了它是所有异常的基类。这个类从object派生,并且继承了ISerializable,_Exception两个接口,ISerializable是实现序列化的接口的,_Exception是一个异常的接口。
2、throw
throw是一个专门的关键字,他的唯一作用就在某些时候把Exception本身或子类的对象抛出来——也即为抛异常中(其实在这里是抛一个对象,这个对象封装了不符合逻辑规范或业务规范的信息),某些时候是什么时候呢?比如,在数据运算中,用0作为整数的被除数是不符合规范的,所以在c#中去表达这个算法的时候也是不可以的。比如在现实业务中,比如出现一个本月工资为负数的工资数,这也是不现实的,这些都是可以作为抛出异常的理由。
3、try…catch…finally
抛出了异常,谁来处理呢?肯定得有一些关键字来处理,即try…catch…finally。具体代码为:
try
{
}
catch
{
}
finally
{
}
在try语句块中,是书写语句的地方,所以也是引发异常的地方。如果整个语句块区域内没有发生异常,则不执行catch,如果try的语句块中发生异常,刚会执行catch语句块。finally语句块是无论异常是否发生,都会执行的。
Catch可以加上一个参数:
catch(Exception e)
{
}
这个参数就是捕获在try语句里的异常而抛出来的,其实Exception是throw传给catch的一个参数对象,这个对象中封装着异常信息。
对时catch语句块可以有多个,并且都得有参数,但是有一定的序顺,是先Excepation的子类,再到Exception。
以上就是基本的异常处理规则,下面来简单看一个这三者组合。
定义异常
class DataQueryException : Exception//异常类
{
string condition;//定义查询条件
public string Condition
{
get { return condition; }
set { condition = value; }
}
public DataQueryException(string message)
: base(message)
{
}
public DataQueryException(string message, string condition)
: base(message)
{
this.condition = condition;
}
}
按照业务逻辑来抛出异常
class BLL//业务类
{
public string QueryName(string condition)
{
if (condition == "" || condition == null)
{
throw new DataQueryException("输入的条件为null或\"\"");
}
if (condition.Length > 20)
{
throw new DataQueryException("条件的长度大于20",condition);
}
//查代码
return "查询结果";
}
}
应用业务类型,捕捉异常
class Program//应用业务类
{
static void Main(string[] args)
{
try
{
BLL bll = new BLL();
bll.QueryName("");
}
catch (DataQueryException dqe)
{
Console.WriteLine("异常信息:"+dqe.Message+" 查询条件:"+dqe.Condition );
}
catch (Exception dqe)
{
Console.WriteLine("异常信息:" + dqe.Message);
}
}
}
以上代码全用C#实现的,假设定义异常是用C++.net来实现,在另外的两个类中需要是引用一下。
业务类是用VB.NET来实现。应用业务类用c#实现,当然,如果要用业务定义的一些类,则必须引入业务类。这样的话,异常类,定义完后,根本不知道什么类要用自己。对于业务类来说,我只知道不满足我的业务逻辑时,就会throw出异常,但不知道抛给谁。调用业务类知道的最全面,调用那个类,引发何种异常,全了解才可以。
从上面可以看出,其实这个异常处理已经实现了跨语言了。当然,这个是从开发人员角度去认识的。如果从IL角度看,其实这些处理都是在IL级别来完成的。