C#如何捕获异常并检查它是否包含字符串?

5 c# exception

当用户权限足够时,我收到一个说"拒绝访问"的异常,如何捕获异常并检查"拒绝访问",以便我可以向用户显示更友好的"拒绝访问被拒绝"消息?

谢谢初学者:-)

Ed *_*rty 15

你真的不想检查消息的字符串,你想检查消息的类型,这可以通过只捕获你正在检查的异常类型来轻松完成.以下示例将捕获两种不同类型的异常,并根据发生的错误执行不同的操作.(注意:组成例外的名称)

try {
    ...
} catch (SomeKindOfException ex) {
    MessageBox.Show(ex.Message);
} catch (AccessDeniedException ex) {
    //Do something else
}
Run Code Online (Sandbox Code Playgroud)


Jef*_*ood 12

我认为这里最安全的事情(而且令人惊讶的是没有一个答案表明这一点)是

  • 尽可能捕获特定的异常类型.真的试图避免捕获所有异常.
  • 测试string.ToLowerInvariant()包含目标字符串的异常消息.
  • 重新 -throw如果它不是你所期望的!

像这样:

try
{
    int result = DoStuff(param);
}
catch (System.IO.IOException ioex)
{
    if (ioex.Message.ToLowerInvariant().Contains("find me"))
    {
        .. do whatever ..
    }
    else
    {
        // no idea what just happened; we gotta crash
        throw;
    }
}
Run Code Online (Sandbox Code Playgroud)


Tom*_*bes 8

在 C# 6.0 中使用异常过滤器甚至更容易:

try
{
    int result = DoStuff(param);
}
catch (IOException ex) 
when (ex.Message.ToLowerInvariant().Contains("find me")) 
{
    //.. do whatever ..
}
Run Code Online (Sandbox Code Playgroud)

旧式 C# 解决方案是

try
{
    int result = DoStuff(param);
}
catch (System.IO.IOException ex)
{
    if (ex.Message.ToLowerInvariant().Contains("find me"))
    {
        //.. do whatever ..
    }
    else
    {
        throw;
    }
}
Run Code Online (Sandbox Code Playgroud)

对于这两种变体,您将获得相同的堆栈跟踪。在第一个变体中,根本没有捕获异常,在第二个变体中,异常被重新捕获。但有一个重要的区别:

对于异常过滤器的情况:

  • 堆栈跟踪被保留。
  • 堆栈被保留。

如果出现 catch-if- throw 情况:

  • 堆栈跟踪被保留。
  • 堆栈不被保留

堆栈和堆栈跟踪有什么区别?

Stacktrace 是堆栈的快照。

实际上,您在这些变体中可以看到的唯一区别是您可以拥有不同的内存转储(如果您组合 C# 和 C++)。

本土化

如果您捕获一些已本地化为多种语言的第三方异常,并且您无法按类型或代码检查异常,请注意该消息可能已本地化。有一个解决方法。您可以找到异常的英文信息。捕获异常,启动一个具有英语文化的新线程,并读取具有英语文化的线程上的消息属性,然后返回到当前线程并返回结果。

结论

您应该使用异常过滤器,它不仅是语法糖,而且您还将拥有正确的内存转储。


Ed *_* S. 6

如果您正在使用try catch块...

try
{
    //error occurs
}
catch (Exception ex)
{
    MessageBox.show(ex.Message);
}
Run Code Online (Sandbox Code Playgroud)

显然,这是非常糟糕的错误处理,但它显示Exception对象包含错误字符串.您可以通过捕获不同的异常类型来缩小对不同异常的处理范围.

Try
{
    //error occurs
}
catch (AccessDeniedException ex)
{
    MessageBox.show(ex.Message);
}
catch (FieldAccessException)
{

}
// etc...
Run Code Online (Sandbox Code Playgroud)