哪个更好,何时:使用语句或在C#中的IDisposable上调用Dispose()?

时间:2022-12-05 19:54:47

Suppose I have the following:

假设我有以下内容:

using(var ctx = DataContextFactory.Create(0))
{ ... Some code ... }

Why not just do the following and lose a couple of curly braces?:

为什么不做以下操作而失去几个花括号?:

var ctx = DataContextFactory.Create(0);
ctx.Dispose();

Thanks for the advice!

感谢您的建议!

5 个解决方案

#1


26  

The first is better. It ensures it is disposed even if an exception is thrown, and it correctly handles the case where Create(0) returns null (i.e. it doesn't attempt to call Dispose() on a null instance).

第一个更好。它确保即使抛出异常也会处理它,并且它正确处理Create(0)返回null的情况(即它不会尝试在null实例上调用Dispose())。

#2


7  

A using statement is always better because...

使用声明总是更好,因为......

  • you can't forget to call Dispose(), even as the code evolves into different code paths
  • 你不能忘记调用Dispose(),即使代码演变成不同的代码路径

  • Dispose() gets called even if there's an exception. It also checks for null before calling Dispose(), which may be useful (assuming you're not just calling new).
  • 即使存在异常,也会调用Dispose()。它还会在调用Dispose()之前检查null,这可能很有用(假设您不只是调用new)。

One non-obvious (to me, anyway) trick with using is how you can avoid excessive nesting when you have multiple disposable objects:

使用的一个非显而易见的(对我而言)技巧是当你有多个一次性对象时如何避免过度嵌套:

using (var input = new InputFile(inputName))
using (var output = new OutputFile(outputName))
{
    input.copyTo(output);
}

The VS code formatter will leave the two statements starting in the same column.

VS代码格式化程序将使两个语句从同一列开始。


In fact, in some situations you don't even have to repeat the using statement...

事实上,在某些情况下,你甚至不必重复使用声明......

using (InputFile input1 = new InputFile(inputName1), input2 = new InputFile(inputName2))

However, the restrictions for declaring multiple variables on the same line applies here so the types must be the same and you cannot use the implicit type var.

但是,在同一行上声明多个变量的限制适用于此类,因此类型必须相同,并且不能使用隐式类型var。

#3


3  

Where you can, use using for the reasons Marc cites. OTOH this isn't a brain dead solution as sometimes the lifetime of the object can't be defined as a lexical scope so use it reasonably.

尽可能使用Marc引用的原因。 OTOH这不是一个脑死亡的解决方案,因为有时候对象的生命周期不能被定义为词法范围,所以要合理地使用它。

#4


3  

The only place you don't want to use a using block is where the disposable object is scoped outside of the function. In this case, your class should implement IDisposable and dispose of the object in its Dispose().

您不想使用using块的唯一地方是一次性对象在功能之外的范围。在这种情况下,您的类应该实现IDisposable并在其Dispose()中处理该对象。

#5


2  

The using statement gives you nice syntax plus exception protection. You cannot leave the using statement without calling Dispose (it translates into a finally block with a call to dispose). In your second scenario, if you had an exception between the Create and the Dispose, you would not call dispose directly. Which is not a problem unless you are using unmanaged resources, but if you are, you will leak.

using语句为您提供了良好的语法和异常保护。您不能在不调用Dispose的情况下离开using语句(它会转换为带有dispose调用的finally块)。在第二个场景中,如果在Create和Dispose之间有异常,则不会直接调用dispose。除非您使用非托管资源,否则这不是问题,但如果您使用,则会泄漏。

#1


26  

The first is better. It ensures it is disposed even if an exception is thrown, and it correctly handles the case where Create(0) returns null (i.e. it doesn't attempt to call Dispose() on a null instance).

第一个更好。它确保即使抛出异常也会处理它,并且它正确处理Create(0)返回null的情况(即它不会尝试在null实例上调用Dispose())。

#2


7  

A using statement is always better because...

使用声明总是更好,因为......

  • you can't forget to call Dispose(), even as the code evolves into different code paths
  • 你不能忘记调用Dispose(),即使代码演变成不同的代码路径

  • Dispose() gets called even if there's an exception. It also checks for null before calling Dispose(), which may be useful (assuming you're not just calling new).
  • 即使存在异常,也会调用Dispose()。它还会在调用Dispose()之前检查null,这可能很有用(假设您不只是调用new)。

One non-obvious (to me, anyway) trick with using is how you can avoid excessive nesting when you have multiple disposable objects:

使用的一个非显而易见的(对我而言)技巧是当你有多个一次性对象时如何避免过度嵌套:

using (var input = new InputFile(inputName))
using (var output = new OutputFile(outputName))
{
    input.copyTo(output);
}

The VS code formatter will leave the two statements starting in the same column.

VS代码格式化程序将使两个语句从同一列开始。


In fact, in some situations you don't even have to repeat the using statement...

事实上,在某些情况下,你甚至不必重复使用声明......

using (InputFile input1 = new InputFile(inputName1), input2 = new InputFile(inputName2))

However, the restrictions for declaring multiple variables on the same line applies here so the types must be the same and you cannot use the implicit type var.

但是,在同一行上声明多个变量的限制适用于此类,因此类型必须相同,并且不能使用隐式类型var。

#3


3  

Where you can, use using for the reasons Marc cites. OTOH this isn't a brain dead solution as sometimes the lifetime of the object can't be defined as a lexical scope so use it reasonably.

尽可能使用Marc引用的原因。 OTOH这不是一个脑死亡的解决方案,因为有时候对象的生命周期不能被定义为词法范围,所以要合理地使用它。

#4


3  

The only place you don't want to use a using block is where the disposable object is scoped outside of the function. In this case, your class should implement IDisposable and dispose of the object in its Dispose().

您不想使用using块的唯一地方是一次性对象在功能之外的范围。在这种情况下,您的类应该实现IDisposable并在其Dispose()中处理该对象。

#5


2  

The using statement gives you nice syntax plus exception protection. You cannot leave the using statement without calling Dispose (it translates into a finally block with a call to dispose). In your second scenario, if you had an exception between the Create and the Dispose, you would not call dispose directly. Which is not a problem unless you are using unmanaged resources, but if you are, you will leak.

using语句为您提供了良好的语法和异常保护。您不能在不调用Dispose的情况下离开using语句(它会转换为带有dispose调用的finally块)。在第二个场景中,如果在Create和Dispose之间有异常,则不会直接调用dispose。除非您使用非托管资源,否则这不是问题,但如果您使用,则会泄漏。