c#如果异常被捕获,它会到达我的返回语句吗?
本文关键字:我的 返回 语句 异常 如果 | 更新日期: 2023-09-27 18:15:22
在系统中。IO有一个函数:字符串文件。ReadAllText(string path);
我正试图写一个函数,将调用文件。ReadAllText,处理所有可能的异常,返回true/false并存储错误信息。
我有这个:
public static class FileNoBS
{
public static bool ReadAllText( string path, out string text, out string errorMessage )
{
errorMessage = null;
text = null;
bool operationSuccessful = false;
try
{
text = System.IO.File.ReadAllText( path );
operationSuccessful = true;
}
catch ( ArgumentNullException e )
{
errorMessage = "Internal software error - argument null exception in FileNoBs.ReadAllText'nMessage: " + e.Message;
}
catch ( ArgumentException e )
{
errorMessage = "Internal software error - path is a zero-length string, contains only white space, or contains one or more invalid characters as defined by InvalidPathChars in FileNoBs.ReadAllText.'nMessage: " + e.Message;
}
catch ( PathTooLongException e )
{
errorMessage = "The specified path was too long.'nMessage: " + e.Message;
}
catch ( DirectoryNotFoundException e )
{
errorMessage = "The specified directory was not found.'nMessage: " + e.Message;
}
catch ( FileNotFoundException e )
{
errorMessage = "The file specified in path was not found.'nMessage: " + e.Message;
}
catch ( IOException e )
{
errorMessage = "An I/O error occurred while opening the file.'nMessage: " + e.Message;
}
catch ( UnauthorizedAccessException e )
{
errorMessage = @"UnauthorizedAccessException
path specified a file that is read-only.
-or-
This operation is not supported on the current platform.
-or-
path specified a directory.
-or-
The caller does not have the required permission.'nMessage: " + e.Message;
}
catch ( NotSupportedException e )
{
errorMessage = "path is in an invalid format.'nMessage: " + e.Message;
}
catch ( SecurityException e )
{
errorMessage = "You do not have the required permission.'nMessage: " + e.Message;
}
return operationSuccessful;
}
}
我不明白控制流如何与返回值的函数一起运行。比如UnauthorizedAccessException被捕获,errorMessage被设置为
errorMessage = "You do not have the required permission..."
我知道finally每次都会被执行,但是编译器不会让我在finally块内执行return。我还能不能回来?
另一个问题是如何简化这一点,同时仍然遵循官方指导方针:"一般来说,你应该只捕捉那些你知道如何恢复的异常。"
我害怕从File类(Move, Copy, Delete, ReadAllText, WriteAllText)和Directory类中遍历所有我需要的函数,然后做所有这些长代码块,只是为了捕获所有我不关心的异常,而不是捕获太多异常,因为微软说这很糟糕。
谢谢。
编辑:我得到这样的评论,这不是处理异常,这是"别的东西"。
我是客户端为我的代码,我想做这样的事情:
if ( !FileNoBS.ReadAllText( path, text, errorMessage ) ) {
MessageBox.Show( errorMessage );
return;
}
// continue working with all errors taken care of - don't care for whatever reason file wasn't opened and read, user is notified and I am moving on with my life
由于在try块或catch块中没有返回,因此将到达您的返回。
一般来说,您只想捕获您预期可能发生的异常,并有处理它们的方法。例如,您可能希望处理从给定路径中找不到的文件,并返回一个默认文件。您应该允许其他异常不被捕获,这样您就知道发生了意想不到的事情,而不是通过捕获所有异常来隐藏它。
正如我在评论中所说的,您最好在更高的级别处理异常并简单地显示异常消息,而不是手动设置每个消息。我认为在这种情况下,来自异常的消息将具有足够的描述性。
public static class FileNoBS
{
public static string ReadAllText(string path)
{
return System.IO.File.ReadAllText( path );
}
}
,然后在应用程序的更高级别像这样使用它。我通常有一个通用处理程序来处理所有应用程序异常,并记录它们,并在必要时显示一个消息框。
try
{
var text = FileNoBS.ReadAllText("file.ext");
}
catch(Exception e)
{
Console.WriteLine(e.Message);
}
与其捕捉异常,不如尝试避免导致这些异常被抛出的情况。在您的情况下,您应该在调用ReadAllText
- 永远不要接受null路径——你知道这会导致异常,所以在它发生之前处理它
- 永远不接受指向不存在的文件的路径-在调用 之前使用
- 永远不接受格式错误的路径,例如空字符串或无效字符-这将导致异常
File.Exists(path)
这些测试应在输入源处进行。也就是说,如果用户键入它们,则在使用它们之前对它们进行验证。如果它们来自数据库或其他地方,请在使用前进行验证。如果不是用户输入,它们都是系统错误的迹象,应该被视为系统错误,而不是用户应该担心的事情。
安全异常可能在某种程度上难以预先测试,并且在许多情况下,获得违规是异常,因此获得异常是完全可以的。当然,它不应该使程序崩溃,而是通过向用户发送错误消息来处理(如果它是基于用户输入的,如果是系统生成的数据导致的,则它是应该在代码级别修复的系统错误的标识)。在调用发生的地方执行此操作通常比在某些库方法中执行更合适。
对于IOExceptions
,它们可以放入两个桶中。一次可恢复(通常是重试),一次不可恢复。至少要给用户关于异常的反馈,这样用户就可以选择重试。
如果你做了所有的输入验证,仍然有例如ArgumentNullException
,那么这就指出了程序逻辑中的错误,这是你希望能够在测试中轻松找到并在发布bug之前纠正的错误。你不应该试图掩盖这个错误。
如果没有其他错误发生,则是。
我想在结尾加上:
catch (Exception e)
{
errormessage = "An unexpected error has occured.";
}
return operationSuccessful;
虽然,这将始终返回成功,即使你得到一个错误。我不确定这是否是您想要的,或者您的变量是否命名不当。
return语句将在代码中出现任何异常的情况下被调用,在它被放置在程序结束之前退出。
我建议将一个异常处理程序与高级异常类型(如' exception '类型本身)放在一起,并打印或记录异常消息。在每个方法中指定如此多的异常处理程序将花费大量的精力,这些精力实际上应该放在方法本身中。
try
{
return ReadAllText("path", "text", "error");
}
catch (Exception exception)
{
Console.WriteLine(exception);
}
return false;
如果方法被调用,它将立即返回,否则异常将被打印/记录,方法将返回false。
但是,在某些情况下,您可以在您认为有益的情况下提及几个显式异常处理程序。是将返回值
但是,最好在finally语句中处理return
的值。
如果在任何情况下都希望返回operationsuccess值,那么在catch块之后写入finally块,如下所示,
finally
{
return operationSuccessful;
}