Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/330.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 盲目地调用函数、捕获和处理异常或编写代码以防止执行可能引发异常的函数_C#_Exception - Fatal编程技术网

C# 盲目地调用函数、捕获和处理异常或编写代码以防止执行可能引发异常的函数

C# 盲目地调用函数、捕获和处理异常或编写代码以防止执行可能引发异常的函数,c#,exception,C#,Exception,所以我想知道在处理代码中可能抛出的异常时,更好的做法是什么 比如说,我有一个项目列表。在尝试访问“I”处的元素之前,是否应检查该元素是否存在?(如果list.Count>i),还是应该让代码执行,并在抛出异常时捕获异常 我总是做前者,在那里我会写检查,以确保函数不会被调用,如果我知道它会抛出异常。(边界检查、空检查等)。但现在我真的想了想,我不就是在代码上加倍努力吗?List类已经为我进行了边界检查,并抛出了相应的异常。我为什么还要做边界检查?我可以省去自己的工作,盲目地调用函数,捕捉异常并采取

所以我想知道在处理代码中可能抛出的异常时,更好的做法是什么

比如说,我有一个项目列表。在尝试访问“I”处的元素之前,是否应检查该元素是否存在?(如果list.Count>i),还是应该让代码执行,并在抛出异常时捕获异常

我总是做前者,在那里我会写检查,以确保函数不会被调用,如果我知道它会抛出异常。(边界检查、空检查等)。但现在我真的想了想,我不就是在代码上加倍努力吗?List类已经为我进行了边界检查,并抛出了相应的异常。我为什么还要做边界检查?我可以省去自己的工作,盲目地调用函数,捕捉异常并采取相应的行动


哪种方式更正确

这取决于您是否有处理不存在元素
i
情况的好方法

如果您没有一种对您的案例有意义的好的处理方法,或者如果您真的不希望案例发生,那么不要在其周围编写额外的代码,就让它失败吧。如果您编写了良好的测试,这些测试将为您需要处理和不需要处理的情况指明方向

处理的一些例子 您可能希望使用默认值,因为如果没有,这可能无关紧要,这是一种常见的、预期的和已处理的情况:

public Item GetItem(int i)
{
  if(list.Count>i)
    return list[i];
  else
    return null; //default value, could be an Item if that makes sense, see Null Object Pattern
}
或者,如果需要在某个地方捕获异常,您可能希望抛出更有意义的自定义异常(但不要将异常用于正常程序流,这应该是一种例外情况):

或者,您可能只想为您或用户/支持人员设置一条更有意义的异常消息:

public Item GetItem(int i)
{
  if(list.Count>i)
    return list[i];
  else
    throw new Exception("There was no element found in the list of X at " + i);
}
我的观点是,只有在异常情况下才应该抛出异常,其他情况应该通过本地错误检查来处理

如何确定案例是否属于例外情况?这实际上取决于代码的假设(应该记录在案)

如果您的代码假设当有人在索引
i
中明确请求元素时,他必须确保该索引中存在元素(顺便说一下,这是一个非常合理的假设),那么如果索引
i
不存在,它应该抛出异常,因为这真的不应该发生,而且被认为是例外

将其与有人要求您的代码返回值为“Foo”的元素进行比较。在这里,您的代码假设这样的元素必须存在是不合理的(因为调用方实际上是在查询,而不知道您的内部实现细节,即索引),并且如果找不到该元素,则根本不认为该元素是异常的,所以您不抛出异常,而是返回null

如果有疑问,最好是在错误检查方面出错,而不是抛出异常,因为异常处理成本相对较高,需要花费数百美元 它们破坏了程序控制流,增加了程序的复杂性

我应该让代码执行,并在异常发生时捕获它吗 扔

不,一点也不,这就是所谓的滥用异常处理。当你已经知道某件事情可能会出错,并且可以修复或检查时;那么,为什么不先进行验证,而将其包装成一个
try。。捕获
构造

例如,您可以执行以下操作

Console.WriteLine("Please enter a number");
try
{
int num = Convert.ToInt32(Console.ReadLine());
}
//if someone enter a `string` in place of Integer, it will cause
catch(InvalidFormatException ix) 
{
}
catch(Exception ex)
{
}
通过执行检查并使用
TryParse()
类似的方法,可以很容易地避免这种情况

Console.WriteLine("Please enter a number");
int num;
if (int.TryParse(Console.ReadLine(), out num))
 {

 }
else
 {
   Console.WriteLine("Not a valid integer number");
 }

异常处理总是代价高昂。因此,最好主动检查某些条件,避免调用/执行可能导致异常的任务。但是,如果你开始检查每一件事,你最终会看到一大块代码只进行各种检查,这可能很难维护/读取。如果有任何“正确”的方法来处理这种情况,即使我也想知道:-)在您的第一个示例中,只执行一个try-catch并在catch时返回null怎么样。List为您执行边界检查并抛出异常。您可以这样做,但我只能在万不得已的情况下这样做。主要是因为我必须查找要捕获的异常类型,因为我不想捕获所有异常。
Console.WriteLine("Please enter a number");
int num;
if (int.TryParse(Console.ReadLine(), out num))
 {

 }
else
 {
   Console.WriteLine("Not a valid integer number");
 }