c#异常处理机制 unity 问题十一:override和DataSet的区别

c#异常处理机制 unity 问题十一:override和DataSet的区别

问题11:超控和过载的区别。

override 修饰符重写基类中的方法。

重载就是重写同名的方法,使得同名的函数实现不同的功能。 这使得方法可以有不同的版本。

问题12:DataReader 和DataSet 的异同。

DataReader和DataSet最大的区别是DataReader在使用时总是占用SqlConnection,在线操作数据库。 对 SqlConnection 的任何操作都会导致 DataReader 异常。 由于DataReader每次只加载内存中的一条数据,所以占用的内存很小。 由于DataReader的特殊性和高性能,DataReader是高级的。 阅读第一项后,您将无法再次阅读第一项。

DataSet一次性将数据加载到内存中,放弃数据库连接,离线操作数据库。 读取完成后放弃数据库连接。 由于DataSet将所有数据加载到内存中,因此消耗更多内存,但比DataReader更灵活。 它可以动态添加行、列和数据,并对数据库执行回发更新操作。

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

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

c#异常处理机制 unity_异常机制处理_异常机制处理流程表

无论 Catch 块中的代码是否已执行,Finally 部分中的代码始终在错误处理块失去作用域之前最后执行。 将清理代码(例如用于关闭文件和释放对象的代码)放置在Finally 部分中。

详细解释如下:

(1)投掷

当导致异常的条件发生时2d游戏素材,您可以使用 throw 语句发出信号。 例如,如果例程需要非空字符串作为参数,则它可能包含以下代码:

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

在此示例中,使用特定消息和参数名称创建 ArgumentNullException 的新实例,并使用 throw 语句抛出它。

(2)尝试捕捉

编写错误处理的最基本的结构是 try-catch。 考虑以下代码:

异常机制处理_异常机制处理流程表_c#异常处理机制 unity

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

在此示例中,如果 try 块(在本例中为 Process() 函数)中的代码引发 ArgumentNullException,则控制权将立即转移到 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# 提供了捕获所有异常的语法:

异常机制处理流程表_异常机制处理_c#异常处理机制 unity

   catch
   {
      // handle the exception here
   }

尽管提供此语法是为了完整性,但实际上很少使用。 大多数 C++ 程序都会选择抛出从 Exception 派生的异常,即使它们不这样做,此 catch 语法也不会让您超出所抛出的范围。

(4) 渔获排序:

对于给定的 try 子句,可以有多个 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) 捕获操作::

异常机制处理流程表_c#异常处理机制 unity_异常机制处理

现在我们已经捕获了异常,我们可能想用它做一些有意义的事情。 我们可能想做的第一件事是用一些附加的上下文信息包装异常。

这是通过以下方式实现的:

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

它使用 ArgumentException 的构造函数来获取消息和另一个异常。 构造函数会将传递的异常包装在一个新的异常中c#异常处理机制 unity,并且将引发该新的异常。

这个过程给开发者带来了巨大的好处。 包装的异常不只是获取有关所发生事件的一条信息技能特效,而是提供类似于堆栈跟踪的内容:

Exception occurred:
System.Exception: Exception in Test1
---> System.Exception: Exception in Test2
---> System.DivideByZeroException: Attempted to divide by zero.

这样的输出使调试变得更加容易。 如果使用 /debug 进行编译,您还将获得每个级别的文件名和行号。

包装有助于为调试提供附加信息。 另一种选择是针对需要根据异常采取某些操作的情况。 将输出发送到文件的代码可能如下所示:

异常机制处理_异常机制处理流程表_c#异常处理机制 unity

   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,发生错误,程序可以继续执行。 在许多情况下,这没有问题。

然而,这种情况有一个问题。 如果在打开文件后发生异常c#异常处理机制 unity,则无法关闭该文件。 这不好。

我们需要的是一种方法来确保即使发生异常也可以关闭文件。

(6)最后尝试

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 子句也会运行。

文章来源:https://blog.csdn.net/qq_34573534/article/details/97776964