概述
用惯了C#,VB.Net的人,可能很习惯用下面的格式来捕获所有的异常:
这条语句能捕获所有种类的异常吗?显然,这条语句捕获的是System.Exception,以及所有继承自它的类。
也就是说,如果你抛出了一个不是继承自System.Exception的对象,该语句就无法捕获。
抛出不是异常的异常……这种不兼容CLS的事情,可能吗?
答案是,在1.x当中是可能的。
在C++当中,我们可以用 throw "Error!" 这样的语句抛出一个字符串;
在IL当中,我们可以用下面的方式,抛出任意形式的异常:
所以,在.Net 1.x当中,经常使用下面这种最保险的方式:
但是,在.Net2.0当中,为了确保跨语言的兼容性,CLR会自动将不是继承自System.Exception的异常包裹在RuntimeWrappedException对象中;这样的结果就是,本文中第一个例子中的代码可以捕获所有类型的异常了。
同时,为了保证和1.x版本的兼容性,.Net 2.0提供了RuntimeCompatibilityAttribute类,指定CLR不要对异常进行包装:
附:测试用代码(运行于.Net 2.0)
1,抛出字符串异常的IL代码,用ilasm /DLL编译
2,测试用C#代码,要添加对上面的DLL的引用
执行结果是,第一个异常将被 catch(System.Exception ex){}捕获;第二个异常由于 catch(System.Exception ex){}无法捕获,将落到 catch{}中。
如果把第一行的属性去掉,编译时将出现下面的警告:
warning CS1058: A previous catch clause already catches all exceptions. All non-exceptions thrown will be wrapped in a System.Runtime.CompilerServices.RuntimeWrappedException
继续执行的话,两个异常都将被catch(System.Exception ex){}捕获,不会有任何异常落到catch{}当中
try
{
//Some code
}
catch (System.Exception ex) {
System.Console.Write("Error!" );
}
//Some code
}
catch (System.Exception ex) {
System.Console.Write("Error!" );
}
这条语句能捕获所有种类的异常吗?显然,这条语句捕获的是System.Exception,以及所有继承自它的类。
也就是说,如果你抛出了一个不是继承自System.Exception的对象,该语句就无法捕获。
抛出不是异常的异常……这种不兼容CLS的事情,可能吗?
答案是,在1.x当中是可能的。
在C++当中,我们可以用 throw "Error!" 这样的语句抛出一个字符串;
在IL当中,我们可以用下面的方式,抛出任意形式的异常:
.assembly ThrowerLib { }
.class public Thrower {
.method static public void Start( ) {
ldstr "Oops"
throw
ret
}
}
.class public Thrower {
.method static public void Start( ) {
ldstr "Oops"
throw
ret
}
}
所以,在.Net 1.x当中,经常使用下面这种最保险的方式:
try
{
//Some code
}
catch (System.Exception ex)
{
System.Console.WriteLine("System.Exception error: " + ex.Message);
}
catch
{
System.Console.WriteLine( "Non System.Exception based error. );
}
{
//Some code
}
catch (System.Exception ex)
{
System.Console.WriteLine("System.Exception error: " + ex.Message);
}
catch
{
System.Console.WriteLine( "Non System.Exception based error. );
}
但是,在.Net2.0当中,为了确保跨语言的兼容性,CLR会自动将不是继承自System.Exception的异常包裹在RuntimeWrappedException对象中;这样的结果就是,本文中第一个例子中的代码可以捕获所有类型的异常了。
同时,为了保证和1.x版本的兼容性,.Net 2.0提供了RuntimeCompatibilityAttribute类,指定CLR不要对异常进行包装:
[assembly:System.Runtime.CompilerServices.RuntimeCompatibility(WrapNonExceptionThrows = false)]
附:测试用代码(运行于.Net 2.0)
1,抛出字符串异常的IL代码,用ilasm /DLL编译
// ThrowerLib.il
.assembly ThrowerLib { }
.class public Thrower {
.method static public void ThrowException( ) {
ldstr "ThrowException exception from the IL world!"
newobj instance void [mscorlib]System.Exception::.ctor(string )
throw
ret
}
.method static public void ThrowString( ) {
ldstr "Weird exception!"
throw
ret
}
}
.assembly ThrowerLib { }
.class public Thrower {
.method static public void ThrowException( ) {
ldstr "ThrowException exception from the IL world!"
newobj instance void [mscorlib]System.Exception::.ctor(string )
throw
ret
}
.method static public void ThrowString( ) {
ldstr "Weird exception!"
throw
ret
}
}
2,测试用C#代码,要添加对上面的DLL的引用
[assembly: System.Runtime.CompilerServices.RuntimeCompatibility(WrapNonExceptionThrows = false
)]
namespace ThrowerExample
{
class ThrowerHarness
{
static void Main(string [] args)
{
try
{
Thrower.ThrowException();
}
catch (System.Exception ex)
{
System.Console.WriteLine("System.Exception error: " + ex.Message);
}
catch
{
System.Console.WriteLine("Non System.Exception based error." );
}
try
{
Thrower.ThrowString();
}
catch (System.Exception ex)
{
System.Console.WriteLine("System.Exception error: " + ex.Message);
}
catch
{
System.Console.WriteLine( "Non System.Exception based error." );
}
}
}
}
namespace ThrowerExample
{
class ThrowerHarness
{
static void Main(string [] args)
{
try
{
Thrower.ThrowException();
}
catch (System.Exception ex)
{
System.Console.WriteLine("System.Exception error: " + ex.Message);
}
catch
{
System.Console.WriteLine("Non System.Exception based error." );
}
try
{
Thrower.ThrowString();
}
catch (System.Exception ex)
{
System.Console.WriteLine("System.Exception error: " + ex.Message);
}
catch
{
System.Console.WriteLine( "Non System.Exception based error." );
}
}
}
}
执行结果是,第一个异常将被 catch(System.Exception ex){}捕获;第二个异常由于 catch(System.Exception ex){}无法捕获,将落到 catch{}中。
如果把第一行的属性去掉,编译时将出现下面的警告:
warning CS1058: A previous catch clause already catches all exceptions. All non-exceptions thrown will be wrapped in a System.Runtime.CompilerServices.RuntimeWrappedException
继续执行的话,两个异常都将被catch(System.Exception ex){}捕获,不会有任何异常落到catch{}当中
转载于:https://www.cnblogs.com/yoyiorlee/archive/2009/09/19/1569805.html
最后
以上就是愤怒秋天为你收集整理的除了Exception,还能throw什么的全部内容,希望文章能够帮你解决除了Exception,还能throw什么所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复