关于C#:try-catch正确的语法

try/catch + using, right syntax

哪一个:

1
2
3
4
5
6
7
8
9
10
11
using (var myObject = new MyClass())
{
   try
   {
      // something here...
   }
   catch(Exception ex)
   {
      // Handle exception
   }
}

1
2
3
4
5
6
7
8
9
10
11
try
{
   using (var myObject = new MyClass())
   {
      // something here...
   }
}
catch(Exception ex)
{
   // Handle exception
}


我更喜欢第二个。也可以捕获与对象创建相关的错误。


由于using块只是try/finally(msdn)的语法简化,因此我个人会使用以下方法,尽管我怀疑它与您的第二个选项明显不同:

1
2
3
4
5
6
7
8
9
MyClass myObject = null;
try {
  myObject = new MyClass();
  //important stuff
} catch (Exception ex) {
  //handle exception
} finally {
  if(myObject is IDisposable) myObject.Dispose();
}


这要看情况而定。如果您正在使用Windows通信基础(WCF),如果EDCOX1 OR 2语句中的代理处于异常状态,则EDCOX1 OR 1将不能正常工作,即处理此代理将导致另一个异常。

就个人而言,我相信最小处理方法,即只处理您在执行时知道的异常。换句话说,如果您知道using中变量的初始化可能会引发一个特定的异常,那么我用try-catch将其包装起来。同样地,如果在using体中可能发生一些与using中的变量没有直接关系的事情,那么我用另一个try来包装它,以解决这个特殊的例外情况。我很少在我的catch中使用Exception

但我确实喜欢IDisposableusing,尽管我可能有偏见。


如果catch语句需要访问using语句中声明的变量,那么只有inside选项。

如果catch语句在释放前需要在using中引用的对象,则只有inside选项。

如果catch语句执行的操作持续时间未知,例如向用户显示消息,并且您希望在执行该操作之前释放资源,那么outside是您的最佳选择。

每当我有一个与此类似的scenerio时,try-catch块通常位于调用堆栈上方的另一个方法中。对于一个方法来说,知道如何处理在它内部发生的异常是不典型的。

所以我一般的建议是在外面。

1
2
3
4
5
6
7
8
9
10
11
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);
    }
}

两者都是有效的语法。它实际上可以归结为您想要做的:如果您想要捕获与创建/处理对象相关的错误,请使用第二个。如果没有,请使用第一个。


这里有一件重要的事情我将在这里指出:第一件事情不会捕获调用MyClass构造函数所产生的任何异常。


如果您在using()块中初始化的对象可能引发任何异常,那么您应该使用第二种语法,否则这两种语法都同样有效。

在我的场景中,我必须打开一个文件,并在我在using()块中初始化的对象的构造函数中传递filepath,如果filepath错误/为空,它可能引发异常。所以在本例中,第二种语法是有意义的。

我的样本代码:

1
2
3
4
5
6
7
8
9
10
11
try
{
    using (var obj= new MyClass("fileName.extension"))
    {

    }
}
catch(Exception ex)
{
     //Take actions according to the exception.
}