这是一个示例方法
private static void outputDictionaryContentsByDescending(Dictionary<string, int> list)
{
try
{
//Outputs entire list in descending order
foreach (KeyValuePair<string, int> pair in list.OrderByDescending(key => key.Value))
{
Console.WriteLine("{0}, {1}", pair.Key, pair.Value);
}
}
catch (Exception e)
{
MessageBox.Show(e.Message, "Error detected", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
我想知道除Exception
之外使用什么异常子句以及使用更具体的catch子句是否有优势。
编辑:O.k感谢所有人
答案 0 :(得分:7)
在语句中捕获各种类型的异常将允许您以不同的方式处理每种异常。
Exception
的一揽子规则可能对记录和重新抛出异常非常有用,但对于实际处理您可以从中恢复的异常不是最好的。
try
{
// open a file specified by the user
}
catch(FileNotFoundException ex)
{
// notify user and re-prompt for file
}
catch(UnauthorizedAccessException ex)
{
// inform user they don't have access, either re-prompt or close dialog
}
catch(Exception ex)
{
Logger.LogException(ex);
throw;
}
答案 1 :(得分:4)
您应该只捕获您期望代码可能抛出的异常。这样,如果它抛出你没想到的东西,它可能是一些关键的东西; 应该冒泡调用堆栈并可能导致应用程序崩溃的东西;或者你没想过的东西。
例如,您可能希望处理由I / O代码引发的IOException
,以便您可以将问题转发回用户。但是,相同的操作可能会引发更为重要的操作,例如AccessViolationException
。在这种情况下,您可能希望程序终止,或以不同的方式处理问题。
通用异常处理应该只在真正用于您不关心发生了什么错误的情况,并且随后不希望它影响您的其余进程。
答案 2 :(得分:2)
我在示例中看到的唯一可能的异常原因是list
为空。 OrderByDescending()
应返回空IEnumerable<>
而不是空引用。
如果我读得正确,抓住NullReferenceException
可能更有意义:
try
{
...
} catch (NullReferenceException exception)
{
MessageBox.Show(...);
}
但是,这实际上取决于您的应用程序的需求。如果您的目的只是提醒用户或记录所有异常,那么捕获Exception
类就可以了。如果您需要针对不同类型的异常进行特殊处理 - 例如发送电子邮件警报而不是仅记录消息 - 那么使用特定的异常类型是有意义的:
try
{
}
catch(NullReferenceException e)
{
//...
}
catch(StackOverflowException e)
{
//...
}
catch(Exception e)
{
/// generic exception handler
}
答案 3 :(得分:2)
使用哪个例外实际上取决于try块中的代码。一般而言,您希望捕获可以执行某些操作的异常,并让您没有权限的异常移动到您的代码的高级别,您可以执行某些操作。我看到人们犯的最常见错误之一是试图捕捉他们无法处理的错误。
例如
Void ChoseFile()
{
try
{
string FileName = GetInputFile()
}
catch( InvalidFileSelectedException ex)
{
//In this case we have some application specific exception
//There may be a business logic failure we have some ability
//to infomr the user or do an action that makes sense
}
catch(FileNotFoundException exfilenot found)
{
//In this case we can do somthing different the the above
}
catch(Exception )
{
//Normal I would not use this case we have an error we don't know what to do
//with. We may not have a usefull action. At best we can log this exception
// and rethrow it to a higher level of the application that can inform the user
// fail the attempted action. Catching here would only suppress the failure.
}
}
答案 4 :(得分:1)
由于您正在处理字典..那么您想要查看这两个例外
keyValuePair的键是一个空引用(在Visual Basic中为Nothing)。
ArgumentException字典中已存在具有相同键的元素(TKey,TValue)。
KekValuePair Exception 这取自MSDN网站
答案 5 :(得分:1)
您应该始终使用特定类来捕获异常。
如果您知道如果文件被锁定该怎么办,但您认为所有其他错误都是意外且无法处理的,那么您应该抓住System.IO.IOException
并处理错误。您应该只抓住Exception
(或只是catch {
)才能正常退出。
答案 6 :(得分:0)
使用您可能期望但仍然无法阻止的异常类型,并且您可以充分处理。让任何其他东西冒泡到某个可能期望它或可以处理它的地方。
在这种情况下,如果字典为空,我可能会遇到NullReferenceException
。 但是我不会抓住它。这是我可以反而验证的东西
if (dictionary != null)
所以没有理由允许甚至发生异常。切勿使用控制流的异常,并根据已知原因进行验证。
答案 7 :(得分:0)
某些类/方法会抛出不同的异常,具体取决于错误。例如,您可能正在使用File类将数据写入文件。您可以为可以从中恢复的异常类型编写多个Catch语句,并使用一般的异常捕获来记录和冒泡任何无法从中恢复的内容。
答案 8 :(得分:0)
通过使用Exception,您可以捕获所有异常。在使用IOException或StackOverflowException时,您只会捕获该类型的错误。
由异常捕获的StackOverflowException仍然保持相同的消息,堆栈跟踪等。
答案 9 :(得分:0)
异常处理理念 我相信你可以找到许多其他的哲学
防守代码。捕获异常比首先防止错误更加昂贵。
不要抓住异常并通过不处理来掩埋它。您可能需要花费很多时间来查找已被抑制的错误。
记录您捕获的错误。 这有助于分析问题。您可以检查是否有多个用户遇到同样的问题 我更喜欢用于记录的数据库,但是平面文件或事件日志也是合适的。 数据库解决方案最容易分析,但可能会引入其他错误。
如果错误是由用户输入的错误数据引起的,请告知用户问题并允许他们重试。 如果他们无法解决问题,请始终允许逃生路线。
尽可能靠近源捕获错误 这可以是数据库过程,数据访问层(DAL)中的方法或其他位置。
处理异常与捕获异常不同。您可能需要重新抛出异常,以便可以在堆栈或UI中更高的位置处理它。
至少可以通过两种方式重新处理异常。 throw本身并不会改变堆栈。 throw ex确实会改变或添加到堆栈中而没有任何好处。
有时最好不要捕捉异常,而是让它冒出来。
如果您正在编写没有用户界面(UI)的服务(Web或Windows),则应始终记录错误。 同样,这是因为有人可以分析日志或数据库文件以确定发生了什么。
您总是希望有人知道发生了错误。
对try块有很多catch语句可能会使代码更难维护,尤其是当catch块中的逻辑很复杂时。 相反,代码是防御性的。
请记住,您可以在catch块中尝试catch块。
另外,不要忘记在适当的地方使用finally块。 例如,关闭数据库连接或文件句柄等
HTH HARV