我应该在哪里使用"using"语句并加入try/catch块?

34

可能重复:
使用正确语法的try/catch

我想尝试使用以下代码进行try/catch

//write to file
using (StreamWriter sw = File.AppendText(filePath))
{
    sw.WriteLine(message);
}

using语句中,我是应该把try/catch块放在里面、外面还是两边都放?


2
你是否关心在 WriteLine 调用、AppendText 调用或两者中捕获异常? - jglouie
1
这取决于您是否可以在 using 块内处理异常,或者异常是否会使整个 using 块变得多余。 - PostMan
1
@jglouie 我想要同时捕获两个。 - Ryan R
6
我认为这个问题不应该被关闭,因为另一个问题中被接受的答案太糟糕了! - Jeffrey L Whitledge
@Jeffrey:同意其他被接受的答案。你应该在那个问题下重新发布你的回答。 - H H
3个回答

53

如果你的catch语句需要访问在using语句中声明的变量,那么内部是你唯一的选择。

如果您的catch语句需要在使用之前引用using中的对象,则内部是您唯一的选择。

如果您的catch语句需要执行未知持续时间的操作(例如向用户显示消息),并且希望在此操作发生之前处理资源,则外部是最佳选择。

通常情况下,当我遇到类似情形时,try-catch块通常在调用堆栈中更高层的不同方法中。一个方法不会典型地知道如何处理其中出现的异常。

因此,我的一般建议是将其放在外部——远离代码。

private void saveButton_Click(object sender, EventArgs args)
{
    try
    {
        SaveFile(myFile); // The using statement will appear somewhere in here.
    }
    catch (IOException ex)
    {
        MessageBox.Show(ex.Message);
    }
}

16

我认为这是首选的方式:

try
{
    using (StreamWriter sw = File.AppendText(filePath))
    {
        sw.WriteLine(message);
    }
}
catch(Exception ex)
{
   // Handle exception
}

11

如果您无论如何都需要 try/catch 块,那么使用 using 语句并没有什么优势。只需放弃它,改为执行以下操作:

StreamWriter sw = null;
try
{
    sw = File.AppendText(filePath);
    sw.WriteLine(message);
}
catch(Exception)
{
}
finally
{
    if (sw != null)
        sw.Dispose();
}

5
代码很糟糕。没有理由放弃使用块的便利性(可读性,简单性)。 - H H
17
@Henk: 你应该明白这是一种完全主观的看法吧?我个人认为finally块是易读、方便和简单的。当using语句有意义时,它是很好的语法糖,但在这种情况下,使用它并没有意义。 - hemp
10
更正:using语句并不会向垃圾回收器传达任何信息。它会被C#编译器展开成一个包含对对象的IDisposable.Dispose()方法实现的调用的try/finally块(在IL中)。它确实可以作为指示开发人员进行释放的指示符,类似于在finally块中明确调用Dispose表示应该进行释放的方式。 - hemp
9
在finally块中忘记调用dispose和在using块中忘记包装对象一样容易被忽视(许多开发者都会这样做)。从MSDN上来看,“finally块对于清理任何资源非常有用……”我认为我们已经充分地讨论过这个话题了。 - hemp
5
@hemp在此讨论中基本上是正确的。虽然我仍然鼓励在try/catch内部使用using,只是为了保持一致性,但如果程序员不知道他们应该处理对象,则这两种模式都无关紧要。这纯粹涉及个人偏好,根据定义是主观的。我确实喜欢在这里放置它在finally块中的想法,但我不会这样做,因为我担心可能会困惑其他不理解的程序员。 - crush
显示剩余6条评论

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