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