try & catch structure in C#

3

我刚开始学习编程,想请问一下,在布尔方法中使用try和catch的代码是否正确?

这只是示例代码,但我的Presenter类中有许多方法,我想知道我将catch放在仅返回false的位置上是否可以,或者我应该如何改进这个方法。

public bool TestMethod()
{
    try
    {
       if(true)
       { 
         //some random code
         return true;
       }
       else{return false;}
    }
    catch{return false;}
}

我只是想确保这是一种好的实现方式,如果有任何改进意见,我将不胜感激。


1
try块内有什么代码?根据代码的内容,最好的做法可能是完全删除try/catch块,并让它失败。 - Merlyn Morgan-Graham
7个回答

4
不要这样使用通配符。在顶层异常处理程序中捕获所有异常是可以接受的,但不应该只是将其吞掉。应该记录下来并可能显示错误。
对于您的代码,应该仅捕获您预期的特定异常类型。而且我不确定在您的示例中是否使用异常是一个好主意。

3
以下是我对于这个问题代码的一些疑点:
代码中有多个return语句,这可能会使代码读者感到困惑。通常情况下,在一个函数中我们只使用一个return语句(尽管有些例外,比如某些错误条件下的早期返回)。
一般来说,你不应该向用户隐藏异常(或者有些人会说“永远不要吞咽异常”),你应该重新抛出它或者处理异常并展示给用户。
至少需要记录异常日志。
因此,针对上述问题代码的改进可以写为:
public bool TestMethod()
{
    bool returnValue = false;
    try
    {
       if(true)
       { 
         //some random code
         returnValue = true;
       }       
    }
    catch(Exception ex)
    {
         // log the exception here, or rethrow it
    }

    return returnValue;
}

1
我同意,除了你捕获基本的“Exception”类这一事实。你应该只捕获更具体、派生的异常,以确保你能够处理它们。捕获异常只是为了重新抛出它是没有意义的。 - Cody Gray
同意Cody。其中的代码是“随机代码”,所以使用基本的Exception类 :) - coder_bro
还有,感谢在座的每一个人,通过你们所有的概念,我现在对此有了更好的理解,谢谢!:D - WisperWordsOfwisdom_code_in_c_
是的 - 或许楼主可以考虑创建一个新的异常类型(这取决于您是否有意抛出异常),或者至少捕获您预期的特定异常类型。 - Dave
2
@Dave:在 //some random code 部分抛出异常,然后再在下面捕获异常是没有任何理由的。这是一种反模式,叫做使用异常来控制程序流程。有更好的方法来处理这种情况。异常应该仅用于真正的异常情况,而不仅仅是那些你想要 return false 的情况。 - Cody Gray
@Cody Gray - 你说得完全正确,我当时在想什么呢。干得好 :$ 我猜我们还需要明确随机代码的目的,以及异常抛出的来源。 - Dave

2

在我看来,catch块的目的不是返回值。我会这样使用:


public bool TestMethod()
{
    bool retVal = false;
    try
    {
        if (true)
        {
            //一些随机代码
            retVal = true;
        }
        else{}
    }
    catch{}
    return retVal;
}


是的,那就是我会做的。但是那个空的 catch 块仍然让我感到困扰。这是一种代码异味,我可以从这里闻到。 - Cody Gray
最后一件事情,请注意!我注意到你的catch{}是空的,这样做可以吗?我的很多布尔方法没有异常需要捕获,所以像那样留下来可以吗? - WisperWordsOfwisdom_code_in_c_
@WisperWordsOfwisdom_code_in_c_:不,这样做不行。它会悄悄地吞噬所有的异常。 - Timwi
1
@Wisper: 如果没有任何异常需要捕获,你根本不需要在代码中使用 try-catch 块。除非你有非常明确的理由,否则不应该将所有代码都包含在异常处理中。 - Cody Gray
示例的目的是展示基于所提供的示例代码的功能,而不是展示完整的try-catch示例。这里的重点在于变量。 - Alexander Schmidt

1

这并不是一个特别有帮助的回答。我相信提问者本可以自己参考文档。他们已经编写了代码,现在是在寻求风格方面的建议。 - Cody Gray

1

这取决于您在if语句块中的操作。如果在发生意外错误时返回false,您将永远无法知道出了什么问题。如果您的代码足够简单并且您知道出了什么问题,则是很好的使用方法。

例如,对于检查给定字符串是否为有效数字和5的倍数的方法,这是一个很好的方法。如果它不是数字,您将收到异常,并且您不需要记录或其他任何原因会导致异常。


1
这里的重点是可读性,每个人都有自己的风格(这不是对与错的问题)。我所做的是声明一个返回值(就像某些人在这里做的一样,比如 retVal,returnValue,...),我的最爱是 result,在您的情况下应该是bool
然后,在方法体内使用此 result 变量,即在 try/catch 内部,并且除非在方法结尾处返回 result,否则不要返回任何内容。个人使用 return 其余代码(在 return 之后)不应运行。
这样,读者就不会困惑于如此多的 return。您可以考虑提前 return 的性能好处,但我怀疑(如果编译器优化无法为您完成)它在框架的世界中具有很少的影响,其中我们每天都在为设计问题而牺牲性能。
最后,认真对待CodeInChaos所说的观点。如果您不知道异常原因并且无法以优雅的方式处理它,请让它被抛出。 异常不是坏事,就像药物中的疼痛一样。一个患有慢性糖尿病的人失去了脚部的疼痛感觉,将不会注意到脚部的小伤口,而谷歌搜索将向您展示忽略疼痛信号的结果图片。

嗯,这是一个很好的答案,直到最后一句。我认为你的比喻有点牵强。而且用图形描述/链接表述得有些过了。 - Cody Gray

0

如果你在问的是直接从catch子句中返回是否可以,那当然没有问题。否则编译器会禁止这样做;例如,你不能从finally子句中返回。

然而,在你的特定代码示例中,catch子句似乎毫无意义,因为try中的代码不会引发任何异常(除了系统级别的异常,如OutOfMemoryException,但那是异常情况)。如果其中有一个throw语句,或者你认为可能会抛出异常的方法调用(例如,File.Open可能会抛出FileNotFoundException),那就更有意义了。

关于代码风格,我建议你多使用一些缩进:

public bool TestMethod()
{
    try
    {
        if (some_condition)
        { 
            //some random code
            return true;
        }
        else
        {
            return false;
        }
    }
    catch
    {
        return false;
    }
}

非常感谢您的帮助,那么我想问一下,您的意思是如果我在try{}中使用这样的文件操作,那么我应该在catch中实现throw new exception,然后再返回false吗? - WisperWordsOfwisdom_code_in_c_
我只是想知道抛出新异常是放在try的else语句中还是在catch语句中 :) - WisperWordsOfwisdom_code_in_c_
@WisperWordsOfwisdom_code_in_c_:我认为有些地方存在混淆。如果您使用throw语句,则会抛出自己的异常。如果您调用File.Open,则可能会引发它自己的异常。两者都做没有意义。-当然,您可以在catch中使用throw(在这种情况下,将抛出一个新的异常并丢弃捕获的异常),但在大多数情况下,除非您实际上需要对其做出响应,否则应该不要首先捕获异常。 - Timwi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接