如何创建一次性类

时间:2014-08-20 01:45:48

标签: c#

每次我实例化该类时,我都有这个类,我需要对它进行处理,包括该类中的字段有没有办法做到这一点?这是我的班级

    internal class PlayerClass 
    {
        public WindowsMediaPlayer _wplayer;
    }

使用后如何处理该课程? 试图在互联网上找到一种方法但是在测试之后它们都没有工作。

我试过这个

internal class PlayerClass : IDisposable
{
    public WindowsMediaPlayer _wplayer;
    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }

    /// <summary>
    /// Is this instance disposed?
    /// </summary>
    protected bool Disposed { get; private set; }

    /// <summary>
    /// Dispose worker method. See http://coding.abel.nu/2012/01/disposable
    /// </summary>
    /// <param name="disposing">Are we disposing? 
    /// Otherwise we're finalizing.</param>
    protected virtual void Dispose(bool disposing)
    {
        Disposed = true;
    }
}

AM我做错了吗?

3 个答案:

答案 0 :(得分:3)

与其他答案的建议相反,it is necessary and essential to Dispose of all created objects实现 Dispose()方法(即实现IDisposable)。这些对象是非托管资源,因此对GC不可见。不处理它们是保证内存泄漏。(注意,某些术语更喜欢 Close()方法到Dispose方法,在这种情况下 Close()方法应该是相同。)

以下是IDisposable接口的最佳实践实现。

#region IDisposable implementation with finalizer
private bool isDisposed = false;
public void Dispose() { Dispose(true); GC.SuppressFinalize(this); }
protected virtual void Dispose(bool disposing) {
  if (!isDisposed) {
    if (disposing) {
      if (_wplayer != null)     _wplayer.Dispose();
   }
  }
  isDisposed = true;
}
#endregion

以上是MSDN链接中的最佳做法 Dos Donts

  • DO 声明受保护的虚拟void Dispose(bool disposing)方法 集中所有与释放非托管资源相关的逻辑。
  • DO 只需调用Dispose(true),然后调用GC.SuppressFinalize(this)即可实现IDisposable接口。
  • 不要使无参数的Dispose方法成为虚拟。
  • 请勿声明除Dispose()和Dispose(bool)之外的Dispose方法的任何重载。
  • DO 允许多次调用Dispose(bool)方法。第一次调用后,该方法可能选择不执行任何操作。
  • AVOID 从Dispose(bool)中抛出异常,除非在包含进程已损坏的严重情况下(泄漏,不一致的共享状态等)。
  • CONSIDER 提供方法Close(),除Dispose()外,如果close是该区域的标准术语。

答案 1 :(得分:3)

看起来好像你正在实现IDisposable只是因为它对于托管代码是不必要的。垃圾收集器会自动清理你身后。

您可能需要在帖子 为什么 中澄清您正在实施IDisposable。

但是我相信你的错误是垃圾收集器不会自动调用Dispose()。如果你实现了IDisposable,你必须确保使用你的类的代码在using()语句中实例化或手动调用.Dispose。否则你的处置方法永远不会开火。

using(var player = new PlayerClass()){
    // Do something with player
    // player.Dispose() is called automatically when you exit this using statement.
}

由于您依赖调用者来确保调用Dispose,您可能还需要查看SafeHandle(首选)或Finalize。

  

因为IDisposable.Dispose实现被调用   当实例拥有的资源为no时,类型的使用者   需要更长时间,你应该将托管对象包装在一个   SafeHandle(推荐的替代方案),或者您应该覆盖   Object.Finalize在事件发生时释放非托管资源   消费者忘记调用Dispose。

来源:IDisposable Interface

使用Statement https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/using-statement

答案 2 :(得分:0)

来自MSDN documentation

  

提供释放非托管资源的机制。

您不需要处置托管对象。 .Net将为您带来这一点。当您创建一个将使用非托管资源引导的互操作类时,它是有用的,然后您可以处置所有对象。