异常学习
![ContractedBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![ExpandedBlockStart.gif](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
public
class
SomeClass
{
public void SomeMethod()
{
try
{
}
catch (InvalidCastException)
{
}
catch (NullReferenceException)
{
}
catch (Exception e)
{
}
catch
{
}
finally
{
}
}
}
{
public void SomeMethod()
{
try
{
}
catch (InvalidCastException)
{
}
catch (NullReferenceException)
{
}
catch (Exception e)
{
}
catch
{
}
finally
{
}
}
}
- try块:try块通常包含一些需要的操作,也可以抛出异常,一个try块至少有一个catch或者finally,单独的try没有意义;
- catch块:包含异常出现时需要执行的响应代码。一个try可以有0个或者多个catch块相关联,如果try块没有抛出异常,CLR永远不会执行该try块相关联的catch。出现在catch后的表达式被称作为异常筛选器(exception filter).代码执行后自上而下搜索catch块,应该将更具体的异常放在上面。如果更加具体的catch块出现在离代码底部更近的位置,C#编译器会爆出一个错误,因为这样子的catch不可能被执行到;在catch的末尾有三种选择:
A:重新抛出异常,向更高一层的调用堆栈中的代码通知该异常的发生;
B:抛出一个不同的异常,向更高一层的调用堆栈中的代码提供更多 的异常信息;
C:让线程从catch块的底部退出;
- finally块:finally块中包含带代码确保一定要执行,一般在finally中的代码执行的是一些资源清理造作,注意就算在finally之前返回了程序,finally也是会执行的;
![ContractedBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![ExpandedBlockStart.gif](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
namespace
ExceptionStudy
{
class Program
{
static void Main( string [] args)
{
try
{
SomeClass.SomeMethod();
}
catch
{
}
}
}
public class SomeClass
{
public static int SomeMethod()
{
try
{
throw new Exception();
}
catch (Exception)
{
return 0 ;
}
finally
{
Console.WriteLine( " finally " );
}
}
}
}
{
class Program
{
static void Main( string [] args)
{
try
{
SomeClass.SomeMethod();
}
catch
{
}
}
}
public class SomeClass
{
public static int SomeMethod()
{
try
{
throw new Exception();
}
catch (Exception)
{
return 0 ;
}
finally
{
Console.WriteLine( " finally " );
}
}
}
}
上面代码在catch中返回了方法,但是finally依然执行,当然就算在catch中throw也是会执行finally的;不要尝试在finally中返回值,下面代码编译不会通过:
![ContractedBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![ExpandedBlockStart.gif](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
public
class
SomeClass
{
public static int SomeMethod()
{
try
{
throw new Exception();
}
catch (Exception)
{
return 0 ;
}
finally
{
Console.WriteLine( " finally " );
return 0 ;
}
}
}
{
public static int SomeMethod()
{
try
{
throw new Exception();
}
catch (Exception)
{
return 0 ;
}
finally
{
Console.WriteLine( " finally " );
return 0 ;
}
}
}
finally中的return 0”会爆出错误 1 控制不能离开 finally 子句主体“,至于原因还没有好好想。
异常是对程序隐含接口隐含假设的一种违反。一个整数相加的函数,如果输入的值不符合隐含的假设将会产生异常。
几个另类的异常:
- OutOfMemeryException 该异常在我们试图新建一个对象、而垃圾收集器由找不到任何可用内存时被抛出。在这种情况下,应用程序代码可以成功地捕获到该异常,并且finally也会被执行。CLR需要某些内部内存、而又没有找到可用内存的时候也会抛出该异常。在这种情况下,CLR会向控制台显示一个信息,并且立即中断进程:应用程序不可能捕捉到该异常,并且finally也不会执行;
- StackOverflowException CLR在线程耗尽所有的堆栈空间时会抛出该异常。可以捕获到该异常,但是finally不会执行,因为他们需要额外的堆栈空间,而这时已经没有了;
- ExecutionEngineException CLR检测到它的内部数据结构毁坏,或者自身的一些bug时会抛出该异常。
嗨,这几个异常平日没有见过啊。