ASP.NET开发 笔试题目详解(5)——override与overload,DataReader和DataSet,C#的异常处理机制

问题十一:  override与overload的区别。

override(重写)修饰符,覆写一个基类中的方法。

overload(重载)则是将同名方法重新写过,达到同名的函数实现不同的功能。从而实现了一个方法有不同的版本。

 

问题十二:  DataReader和DataSet的异同。
DataReader和DataSet最大的区别在于,DataReader使用时始终占用SqlConnection,在线操作数据库。任何对SqlConnection的操作都会引发DataReader的异常。因为DataReader每次只在内存中加载一条数据,所以占用的内存是很小的。因为DataReader的特殊性和高性能,所以DataReader是只进的,你读了第一条后就不能再去读取第一条了。

DataSet则是将数据一次性加载在内存中,抛弃数据库连接,是离线操作数据库。读取完毕即放弃数据库连接。因为DataSet将数据全部加载在内存中,所以比较消耗内存,但是确比DataReader要灵活,可以动态的添加行、列、数据,对数据库进行回传更新操作。
 

问题十三:  C#的异常处理机制。

Try...Catch...Finally 异常处理程序的 Try 块包含希望错误处理程序监视的代码节。如果该代码节中的任何代码在执行期间发生错误, 将检查 Try...Catch...Finally 内的每个 Catch 语句,直到找到条件与该错误匹配的语句。如果找到了这样的语句,则控制转移到 Catch 块内的第一个代码行。如果没有找到匹配的 Catch 语句,则继续搜索包含发生异常的块的外部 Try...Catch...Finally 块的 Catch 语句。此过程在整个堆栈中继续,直到在当前过程中找到匹配的 Catch 块。如果没有找到,将产生错误。

Finally 节中的代码总是最后执行,并且刚好在错误处理块失去范围之前执行,不论 Catch 块内的代码是否已执行。将清理代码(如用于关闭文件和释放对象的代码)放在 Finally 节中。

详细解释如下:
(1)Throw
在发生引发异常的条件时,可以用 throw 语句来对发出信号。例如,如果例程要求非空字符串作为参数,则它可能包含下列代码:

public void Process(string location){
   if (location == null)
   throw new ArgumentNullException("null value", "location");
}

在该示例中,ArgumentNullException 的新实例是用特定的消息和参数名称来创建的,throw 语句用于引发它。

(2)Try-Catch
用于编写错误处理的最基本的构造是 try-catch。考虑下列代码:

   try{
      Process(currentLocation);
      Console.WriteLine("Done processing");
   }
   catch (ArgumentNullException e)
   {
      // handle the exception here
   }

在该示例中,如果 ArgumentNullException 被 try 块中的代码引发(在此情况下,是 Process() 函数),控制将被立即转到 catch 块,而不会执行 Console.WriteLine() 调用。

(3)更通用的捕捉:
在上一个示例中,catch 子句捕捉到了 ArgumentNullException,它完全与 Process() 所引发的异常匹配。

不过,这不是一项要求。Catch 子句将捕捉指定的异常或者任何从该类派生的异常。例如:

   try
   {
      Process(currentLocation);
      Console.WriteLine("Done processing");
   }
   catch (ArgumentException e)
   {
      // handle the exception here
   }

由于 ArgumentNullException 是从 ArgumentException 派生的,因此该 catch 子句将捕捉任何一种异常。此外,它还将捕捉其他的派生异常:ArgumentOutOfRangeException、InvalidEnumArgumentException 和 DuplicateWaitObjectException。

由于所有的异常归根到底都是从 Exception 类派生的,因此捕捉 Exception 将捕捉任何异常。对了,不是捕捉任何异常;这是因为 C++ 不会将用户限制为只引发从 Exception 派生的类,C# 提供了捕捉所有异常的语法:

   catch
   {
      // handle the exception here
   }

尽管这个语法是为了完整性而提供的,但是实际上很少使用它。大部分的 C++ 程序都将选择引发从 Exception 派生的异常,并且即使它们不这样做,此 catch 语法也不会让您超出引发了什么。

(4)Catch 排序:
对于给定的 try 子句,可以有一个以上的 catch 子句,每个 catch 捕捉不同的异常类型。在上一个示例中,对 ArgumentException 进行特殊处理,然后对所有其他异常进行别的处理可能很合适。选择最具体的(即,派生程度最大的)catch 子句。

那么示例将是这样的:

   try
   {
      Process(currentLocation);
      Console.WriteLine("Done processing");
   }
   catch (ArgumentException e)
   {
      // handle the exception here
   }
   catch (Exception e)
   {
      // handle the more general exception here
   }

当使用多个 catch 子句时,导出类型必须始终列在任何基类型之前(或者,以从比较合适到不太合适的顺序列出)。这是为了提高可读性。通过阅读较早的 catch 子句,您可以确定运行时行为将是什么。

(5)Catch 操作::
既然我们已经捕捉到了异常,我们可能希望对它来做一些有意义的事情。我们可能想做的第一件事是用一些附加的上下文信息包装异常。

这是以下面的方式来实现的:

   try
   {
      Process(currentLocation);
      Console.WriteLine("Done processing");
   }
   catch (ArgumentException e)
   {
      throw new ArgumentException("Error while processing", e);
   }

它为 ArgumentException 使用获取一个消息和另一个异常的构造函数。该构造函数将把传递的异常包装在新的异常中,而那个新的将被引发。

此过程为开发人员带来了巨大的好处。不是只获得单个一条有关所发生的事情的信息,包装异常还提供了一种类似堆栈跟踪的东西:

Exception occurred:

System.Exception: Exception in Test1

---> System.Exception: Exception in Test2

---> System.DivideByZeroException: Attempted to divide by zero.

这样的输出使调试变得容易得多。如果用 /debug 编译,在各个等级上还将获得文件名和行号。

包装有助于为调试提供附加的信息。另一种方案是针对需要根据异常采取一些操作的情况。将输出发送到文件的代码看起来可能是这样的:

   try
   {
        FileStream f = new FileStream(filename, FileMode.Create);
        StreamWriter s = new StreamWriter(f);
        s.WriteLine("{0} {1}", "test", 55);
        s.Close();
        f.Close();     
   }
   catch (IOException e)
   {
      Console.WriteLine("Error opening file {0}", filename);
      Console.WriteLine(e);
   }

如果文件不能打开,则引发异常,激发 catch,出现错误,而程序可以继续执行。在许多情况下,这没问题。

不过,在这种情况下就存在问题。如果异常在文件打开之后发生,则文件将无法关闭。这很糟糕。

所需要的是确保即使发生了异常也可以关闭文件的方法。

(6)Try-Finally
finally 构造用于指定即使发生异常也始终会运行的代码。finally 通常用于清理发生异常时所产生的内容。修订上一个示例:

   try
   {
        FileStream f = new FileStream(filename, FileMode.Create);
        StreamWriter s = new StreamWriter(f);
        s.WriteLine("{0} {1}", "test", 55);
        s.Close();
        f.Close();     
   }
   catch (IOException e)
   {
      Console.WriteLine("Error opening file {0}", filename);
      Console.WriteLine(e);
   }
   finally
   {
      if (f != null)
         f.Close();
   }

使用修订后的代码,即使发生了异常 finally 子句也将被运行。

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值