哪一个:
using (var myObject = new MyClass())
{
try
{
// something here...
}
catch(Exception ex)
{
// Handle exception
}
}
OR
try
{
using (var myObject = new MyClass())
{
// something here...
}
}
catch(Exception ex)
{
// Handle exception
}
答案 0 :(得分:88)
我更喜欢第二个。也可以捕获与创建对象有关的错误。
答案 1 :(得分:34)
由于使用块只是try / finally(MSDN)的语法简化,我个人认为,但我怀疑它与第二种选择有很大不同:
MyClass myObject = null;
try {
myObject = new MyClass();
//important stuff
} catch (Exception ex) {
//handle exception
} finally {
if(myObject is IDisposable) myObject.Dispose();
}
答案 2 :(得分:19)
这取决于。如果您使用的是Windows Communication Foundation(WCF),如果using(...) { try... }
语句中的代理处于异常状态,using
将无法正常工作,即处置此代理将导致另一个异常。
就个人而言,我相信最小的处理方法,即只处理你在执行时知道的异常。换句话说,如果你知道using
中变量的初始化可能抛出一个特定的异常,我用try-catch
包装它。类似地,如果在using
体内可能发生某种情况,这与using
中的变量没有直接关系,那么我将其与另一个try
包装在一起,用于该特定异常。我很少在Exception
es。
catch
但我确实喜欢IDisposable
和using
,所以我可能有偏见。
答案 3 :(得分:18)
如果你的catch语句需要访问using语句中声明的变量,那么inside是你唯一的选择。
如果你的catch语句在处理之前需要使用中引用的对象,那么inside是你唯一的选择。
如果您的catch语句采取持续时间不明的操作,例如向用户显示消息,并且您希望在此之前处置您的资源,那么外部是您的最佳选择。
每当我有一个与此类似的scenerio时,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);
}
}
答案 4 :(得分:9)
两者都是有效的语法。这真的取决于你想要做什么:如果你想捕获与创建/处理对象有关的错误,请使用第二个。如果没有,请使用第一个。
答案 5 :(得分:6)
我在这里有一件重要的事情:第一个将不捕获因调用MyClass
构造函数而产生的任何异常。
答案 6 :(得分:2)
在C# 8.0 on中,您可以在某些情况下简化using
语句以摆脱嵌套块,然后将其仅应用于封闭块。
因此,您的两个示例可以简化为:
using var myObject = new MyClass();
try
{
// something here...
}
catch(Exception ex)
{
// Handle exception
}
并且:
try
{
using var myObject = new MyClass();
// something here...
}
catch(Exception ex)
{
// Handle exception
}
两者都很清楚;然后将这两者之间的选择减少到您想要对象范围的大小,要处理实例化错误的位置以及何时处置它的问题。
答案 7 :(得分:1)
如果您在Using()块中初始化的对象可能会抛出任何异常,那么您应该使用第二种语法,否则两者同样有效。
在我的场景中,我必须打开一个文件,然后在我正在Using()块中初始化的对象的构造函数中传递filePath,如果filePath错误/为空,它可能会抛出异常。所以在这种情况下,第二种语法是有意义的。
我的示例代码: -
try
{
using (var obj= new MyClass("fileName.extension"))
{
}
}
catch(Exception ex)
{
//Take actions according to the exception.
}
答案 8 :(得分:1)
从C#8.0开始,我更喜欢像这样使用第二个
public class Person : IDisposable
{
public Person()
{
int a = 0;
int b = Id / a;
}
public int Id { get; set; }
public void Dispose()
{
}
}
然后
static void Main(string[] args)
{
try
{
using var person = new Person();
}
catch (Exception ex) when
(ex.TargetSite.DeclaringType.Name == nameof(Person) &&
ex.TargetSite.MemberType == System.Reflection.MemberTypes.Constructor)
{
Debug.Write("Error Constructor Person");
}
catch (Exception ex) when
(ex.TargetSite.DeclaringType.Name == nameof(Person) &&
ex.TargetSite.MemberType != System.Reflection.MemberTypes.Constructor)
{
Debug.Write("Error Person");
}
catch (Exception ex)
{
Debug.Write(ex.Message);
}
finally
{
Debug.Write("finally");
}
}