【问题标题】:Am I using the "using" statement correctly?我是否正确使用“使用”语句?
【发布时间】:2011-02-11 08:23:20
【问题描述】:

我想知道我对using 的使用是否正确。在using 声明中,我决定是否应该在游戏中使用该图像。

Image imageOfEnemy;
using(imageOfEnemy=Bitmap.FromFile(path))
{
   // some stuff with the imageOfEnemy variable

}

据我了解,我现在不需要打电话给Dispose

【问题讨论】:

  • 很好奇,using 块中发生了什么?
  • 只是一些检查图像是否合适。如果是这样,我正在克隆它(因为在这种情况下我将需要该对象)。
  • 提示:如果一个对象实现了IDisposable,你应该几乎总是使用using

标签: c# .net using-statement


【解决方案1】:

是的,您使用正确。您不需要显式处理位图,因为它将由using 语句处理。您可以通过在内部声明 image 变量来进一步简化:

using(var imageOfEnemy = Bitmap.FromFile(path))
{
    // some stuff with the imageOfEnemy variable
}

大致相当于:

{
    var imageOfEnemy = Bitmap.FromFile(path);
    try 
    {
        // some stuff with the imageOfEnemy variable
    }
    finally 
    {
        ((IDisposable)imageOfEnemy).Dispose();
    }
}

【讨论】:

  • 这不仅更简单,而且更安全:您确定在 using 块之后不使用已处置的对象。
  • Bitmap没有Dispose方法怎么办?
  • @Tray:那么你不能在using 语句中使用它。不仅没有意义,编译器也不会让你这样做。
  • 'roughly' 表示 null check in finally 块?
【解决方案2】:

using 是 IDisposable 对象的简写语句,用于简化 try-finally 块,在 finally 块中使用 Dispose。

http://msdn.microsoft.com/en-us/library/yh598w02.aspx

所以是的,在这种情况下,您不必“手动”调用 Dispose。

using System;
namespace ConsoleApplication3
{
    class Program
    {
        static void Main(string[] args)
        {
            using (var example = new Example())
            {
                //do something
            }
        }
    }

    class Example : IDisposable
    {

        public void Dispose()
        {
            //Do something
        }
    }
}

在 MSIL 中 Main 方法是这样的:

.method private hidebysig static void Main(string[] args) cil managed
{
    .entrypoint
    .maxstack 2
    .locals init (
        [0] class ConsoleApplication3.Example example,
        [1] bool CS$4$0000)
    L_0000: nop 
    L_0001: newobj instance void ConsoleApplication3.Example::.ctor()
    L_0006: stloc.0 
    L_0007: nop 
    L_0008: nop 
    L_0009: leave.s L_001b
    L_000b: ldloc.0 
    L_000c: ldnull 
    L_000d: ceq 
    L_000f: stloc.1 
    L_0010: ldloc.1 
    L_0011: brtrue.s L_001a
    L_0013: ldloc.0 
    L_0014: callvirt instance void [mscorlib]System.IDisposable::Dispose()
    L_0019: nop 
    L_001a: endfinally 
    L_001b: nop 
    L_001c: ret 
    .try L_0007 to L_000b finally handler L_000b to L_001b
}

即使您是 MSIL 新手,也可以看到 try-finally 处理程序和 Dispose 调用。

【讨论】:

    【解决方案3】:

    如果 Image 实现了 IDisposable 接口,它是正确的。 using 语句允许程序员指定使用资源的对象何时应该释放它们。提供给 using 语句的对象必须实现 IDisposable 接口。该接口提供了 Dispose 方法,该方法应该释放对象的资源。

    【讨论】:

    • 如果没有实现IDisposable接口呢?
    • @Tray: 那样就编译不了了。
    【解决方案4】:

    是的,您确实以正确的方式使用它。请始终注意,当您实例化并在其上使用它的对象实现 IDisposable 时,它​​很有用。这真的是 CLR 为我们做的一件巧妙的小事,使代码更简洁。 VB.Net 现在也支持此声明。据我所知,使用 try catch 块的 closin 对象的 using 语句之间没有速度差异,但我建议使用 usins 语句而不是 try-catch,更简洁的代码,并且您不会冒忘记处置​​对象或失败的风险,因为您做了不捕获异常

    【讨论】:

      猜你喜欢
      • 2014-09-04
      • 2016-01-24
      • 2014-05-15
      • 2010-12-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多