using关键字和IDisposable接口有啥关系?

Posted

技术标签:

【中文标题】using关键字和IDisposable接口有啥关系?【英文标题】:What is the relationship between the using keyword and the IDisposable interface?using关键字和IDisposable接口有什么关系? 【发布时间】:2011-04-02 11:11:14 【问题描述】:

如果我使用using关键字,我还需要实现IDisposable吗?

【问题讨论】:

也许你的意思是,“如果我使用'using'关键字,我还需要调用Dispose()吗? @Chris Farmer...很好的编辑。我开始认为这是@Apple 的新垃圾压实机!!! 正如其他人所指出的,using 语句的控制变量必须是实现IDisposable 的类型。然而,某些方法包含using 语句的事实并不意味着包含这些方法的类必须实现IDisposable。类实现IDisposable 的最常见原因是它们包含生命周期无法封装在using 语句中的资源。 【参考方案1】:

你不能没有另一个。

当你写的时候:

using(MyClass myObj = new MyClass())

    myObj.SomeMthod(...);

编译器会生成类似这样的东西:

MyClass myObj = null;
try

    myObj = new MyClass();
    myObj.SomeMthod(...);

finally

    if(myObj != null)
    
        ((IDisposable)myObj).Dispose();
    
 

因此,您可以看到,在使用 using 关键字时,假定/要求实现 IDisposable。

【讨论】:

+1,但不假定 - 必需。如果类型未实现 IDisposable,则您在此处显示的编译器代码将出现无效强制转换异常。这就是为什么编译器通过给出编译时错误来防止这种情况发生,使得 IDisposable 需要,而不是假定,用于使用。 @Jimmy 是的,你是对的,假设我是这个意思。答案已更新。【参考方案2】:

如果你使用using statement,封闭的类型必须已经实现IDisposable,否则编译器会报错。因此,将 IDisposable 实现视为使用的先决条件。

如果你想在你的自定义类上使用using 语句,那么你必须为它实现IDisposable。然而,这样做有点落后,因为为了它而这样做是没有意义的。只有当你有一些东西需要处理,比如非托管资源时,你才应该实现它。

// To implement it in C#:
class MyClass : IDisposable 

    // other members in you class 

    public void Dispose() 
        // in its simplest form, but see MSDN documentation linked above
    

这使您能够:

using (MyClass mc = new MyClass()) 

    // do some stuff with the instance...
    mc.DoThis();  //all fake method calls for example
    mc.DoThat();

  // Here the .Dispose method will be automatically called.

实际上这与写作相同:

MyClass mc = new MyClass();
try  
    // do some stuff with the instance...
    mc.DoThis();  //all fake method calls for example
    mc.DoThat();

finally  // always runs
    mc.Dispose();  // Manual call. 

【讨论】:

@Troy:添加示例以突出显示说明。 实际上,当您有“三明治”代码必须/应该在 finally 部分执行某些内容时,它是一种非常有用的模式。例如,一个常见的场景是一个忙碌的光标,步骤是... 1./复制现有的光标 2./将光标设置为您的等待光标 3./在最后部分复制回原始光标。使用 using 和 IDisposable,您可以编写类似 using(Busy.WaitCursor) //WaitCursor 是一个静态属性,它返回 Busy 的实例,构造函数复制和设置,并且 dispose() 重新设置。 @Tim - 另一个很好的例子是更改控制台应用程序的颜色(我想我在 Wes Dyer 的博客上看到了这一点)。对于这样的任务,实现一个 Disposable 类有时很有用,该类简单地包装了一个在 Dispose() 上执行的 Action。但是,有时我不禁觉得它有点反模式。我想知道其他人对通用 Disposable 类的主题有何看法。【参考方案3】:

你把事情弄糊涂了。您只能在实现 IDisposable 的东西上使用“using”关键字。

编辑:如果使用 using 关键字,则不必显式调用 Dispose,它将在 using 块的末尾自动调用。其他人已经发布了如何将 using 语句转换为 try - finally 语句的示例,并在 finally 块中调用 Dispose。

【讨论】:

从记录集中读取数据时可以使用“using”关键字,对吗? @Troy,是的,那是因为 IDataReader 实现了 IDisposable。 只有当包装你的记录集的任何东西都实现了 IDisposable 时。如果它编译然后它实现 IDisposable....【参考方案4】:

是的,using 关键字是这种模式的语法糖......(来自 msdn)

  Font font1 = new Font("Arial", 10.0f);
  try
  
    byte charset = font1.GdiCharSet;
  
  finally
  
    if (font1 != null)
      ((IDisposable)font1).Dispose();
  

编辑:一个有用的例子。

当您发现您在 finally 部分中始终如一地执行操作时,例如在将光标设置为等待光标后将其重置为默认值时,这是此模式的候选者...

  public class Busy : IDisposable
  

    private Cursor _oldCursor;

    private Busy()
    
      _oldCursor = Cursor.Current;
    

    public static Busy WaitCursor
    
      get
      
        Cursor.Current = Cursors.WaitCursor;
        return new Busy();
      
    

    #region IDisposable Members

    public void Dispose()
    
      Cursor.Current = _oldCursor;
    

    #endregion
  

叫...

using(Busy.WaitCursor)

  // some operation that needs a wait cursor.

【讨论】:

【参考方案5】:

Using 只会处理 disposable 对象。因此,在没有实现 IDisposable 相当无用的对象周围包装 using 块实际上会导致编译器错误。

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

通常,当您使用 IDisposable 反对,你应该声明和 在 using 语句中实例化它。 using 语句调用 Dispose 正确的对象上的方法 方式,它也会导致对象 自己尽快超出范围 调用处置。使用范围内 块,该对象是只读的,并且 无法修改或重新分配。

using 语句确保 即使出现异常也会调用 Dispose 在您调用方法时发生 物体上。你可以实现 通过放置对象获得相同的结果 在 try 块内,然后调用 在 finally 块中处理;实际上, 这就是 using 语句的方式 由编译器翻译。

【讨论】:

【参考方案6】:

您必须实现 IDisposable 才能使用 using。如果您尝试在未实现 IDisposable 的类型上使用 using(),则会收到以下编译时错误:

error CS1674: 'SomeType': type used in a using statement must be implicitly convertible to 'System.IDisposable'

【讨论】:

【参考方案7】:

using 关键字已经实现,所以如果使用 using 关键字,则不必调用 IDisposable

【讨论】:

以上是关于using关键字和IDisposable接口有啥关系?的主要内容,如果未能解决你的问题,请参考以下文章

iDisposable

IDisposable的另类用法

C#关键字总结

c# 中using 关键字有哪些用法?

01.里氏准换与using关键字

在 C# 中实现 IDisposable [重复]