C# 捕获异常

C# 捕获异常,c#,.net,exception,exception-handling,try-catch,C#,.net,Exception,Exception Handling,Try Catch,在下面的代码块中,new构造函数被记录为抛出七种不同的异常类型,包括System.IO.PathTooLongException和System.ArgumentException,System.UnauthorizedAccessException和System.SecurityException: try { var fileInfo = new FileInfo(path); } catch ??? 我只是想确保路径实际上是一个可访问的路径,当我尝试使用此路径创建文件时,不会发生任

在下面的代码块中,
new
构造函数被记录为抛出七种不同的异常类型,包括
System.IO.PathTooLongException
System.ArgumentException
System.UnauthorizedAccessException
System.SecurityException

try
{
    var fileInfo = new FileInfo(path);
}
catch ???
我只是想确保
路径
实际上是一个可访问的路径,当我尝试使用此
路径
创建文件时,不会发生任何错误

因此,问题:

书籍和编码指南告诉我,我不应该使用
catch(Exception)
construct,
但我面临以下情况-我可以捕获和处理4种(共7种)异常类型,它们对每种异常类型的处理是完全相同的

如何做到这一点


我也可以想到以下解决方案,但看起来仍然很糟糕:

catch (Exception exception)
{
    Debug.Assert(exception is PathTooLongException || exception is ...);

    // (or maybe rethrow it further if there is a type mismatch)

    //... Handling code ...
}

你可以这样做:

try
{
    var fileInfo = new FileInfo(path);
}
catch (System.IO.PathTooLongException ex)
{
    handleError(ex);
}
catch (System.ArgumentException ex)
{
   handleError(ex);
}
catch (System.UnauthorizedAccessException ex)
{
}
catch (System.SecurityException ex)
{
   handleError(ex);
}

public void handleError(Exception ex)
{
    //do some stuff
}

您不必捕获每行代码周围的每一个可能的异常

取而代之的是,只有当您有了上下文,并且准备好处理并采取适当的行动时,才能捕获。否则,就让它冒泡吧

捕获异常(特别是在没有足够上下文处理的常见函数的堆栈深处)可能会有问题。有时会导致吞咽和处理不当。在有上下文时处理异常

对于FileInfo异常,这取决于它在堆栈中的深度。如果它在一个可以通过多个路径和场景访问的库中,您不应该处理它,那么此时您将做什么?如果情况也是这样,并且它通过一个深堆栈一直冒泡到一个GUI执行您想要处理它的操作,那么您将捕获什么?执行路径上每个代码路径的所有可能异常?而且,随着代码的更改,您要重新计算所有路径吗?在浅层代码路径(调用该方法的文件信息对话框)中,这是一个简单的调用,但即使这样,您也不会以不同的方式处理它—您将在面板中显示一个错误对话框或消息。异常类型提供了以不同方式处理的能力。在这两种情况下,您都要处理异常,所以我要说bah-hum-bug符合该准则

非常清楚的是,您不应该抛出类型异常。这会削弱以不同方式处理问题的能力

另一相关职位:


此外,您可以先使用File.Exists(path)或Directory.Exists(path)测试路径。

我想在这里添加,因为我所看到的几乎所有java代码中的异常处理都是不正确的。也就是说,对于忽略的异常,您最终会遇到非常难以调试的错误,或者,同样糟糕的是,您会得到一个模糊的异常,它什么也不告诉您,因为盲目地遵循“捕获(异常)是不好的”,而情况更糟

首先,了解异常是一种促进跨代码层返回错误信息的方法。现在,错误1:层不仅仅是堆栈框架,层是具有明确定义的职责的代码。如果你只是因为编写了接口和impl,那么你有更好的事情要解决

如果层设计得很好,并且有特定的责任,那么错误信息在冒泡时具有不同的含义

我有一个软件包,运行一些模拟。这些模拟采用文本脚本。有一个包可以编译这些脚本,还有一个通用的utils包,它只读取文本文件,当然还有基本的javartl。UML依赖项是->

模拟器->编译器->utilsTextLoader->Java文件

1) 如果在一个private中的utils加载程序中出现了一些问题,并且我得到了FileNotFound、Permissions或者其他什么,那么就让它过去吧。你别无选择

2) 在边界处,在最初调用的utilsTextLoader函数中,您将遵循上述规则并捕获所有内容。编译器不关心发生了什么,它只需要知道文件是否已加载。因此,在catch中,重新抛出一个新异常,并将FileNotFound或其他内容转换为“无法读取文件XXXX”

3) 编译器现在将知道源代码未加载。这就是它需要知道的全部。因此,如果我稍后将utilsTestLoader更改为从网络加载,编译器将不会更改。若您放弃FileNotFound并在以后进行更改,那个么将毫无意义地影响编译器

4) 循环重复:调用文件底层的实际函数在获得异常时将不执行任何操作。所以它让它上升

5) 当异常到达模拟器和编译器之间的层时,编译器再次捕获所有内容,隐藏任何细节,并抛出一个更具体的错误:“无法编译脚本XXX”

6) 最后再重复一次这个循环,调用编译器的模拟器函数就可以放手了

7) 最后一个边界是用户。用户是一个层,所有应用程序都适用。main有一个可以捕获所有内容的尝试,最后只是创建一个漂亮的对话框或页面,并向用户“抛出”一个翻译错误

因此,用户可以看到


模拟器:致命错误无法启动模拟器

-编译器:无法编译脚本FOO1

--TextLoader:无法读取文件foo1.scp

---trl:FileNotFound


与之相比:


a) 编译器:NullPointer异常避免流控制的异常总是一件很好的事情。请记住,无论多么不可能,这里有一个争用条件。文件或目录可能会在您检查它和实际尝试使用它之间消失。您能描述一下详细的使用场景吗?我读了很多这方面的想法,但我不太同意。考虑两种情况:(1)Studio.AgMuthEnter异常在试图在Load Debug方法开始时打开文件时发生,