Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如果终结器不是';没有实施?_C#_.net_Memory Leaks_Garbage Collection_Dispose - Fatal编程技术网

C# 如果终结器不是';没有实施?

C# 如果终结器不是';没有实施?,c#,.net,memory-leaks,garbage-collection,dispose,C#,.net,Memory Leaks,Garbage Collection,Dispose,虽然Dispose模式在Internet和SOF上被广泛讨论,但我找不到任何资源来回答我的问题 因此,请在将本文件标记为副本之前通读到底。如果你能给我指出我之前遗漏的一个问题,我将很高兴地删除这个问题 我见过许多类(盲目地?)实现dispose模式而不实现终结器 报告说: 布尔参数disposing指示是从IDisposable.Dispose实现还是从终结器调用该方法。Dispose(bool)实现应该在访问其他引用对象(例如,前面示例中的resource字段)之前检查参数。仅当从IDisp

虽然Dispose模式在Internet和SOF上被广泛讨论,但我找不到任何资源来回答我的问题

因此,请在将本文件标记为副本之前通读到底。如果你能给我指出我之前遗漏的一个问题,我将很高兴地删除这个问题


我见过许多类(盲目地?)实现dispose模式而不实现终结器

报告说:

布尔参数disposing指示是从IDisposable.Dispose实现还是从终结器调用该方法。Dispose(bool)实现应该在访问其他引用对象(例如,前面示例中的resource字段)之前检查参数。仅当从IDisposable.Dispose实现调用该方法时(当disposing参数等于true时),才应访问此类对象如果从终结器调用该方法(disposing为false),则不应访问其他对象。原因是对象是以不可预测的顺序完成的,因此它们或它们的任何依赖项可能已经完成

据我所知,GC调用finalizer方法(如果实现的话),而finalizer方法反过来应该调用参数为false的Dispose(bool)方法

我的第一个问题是,如果一个类没有实现终结器,那么Dispose(bool)是否曾经被调用,参数为false?(例如,通过CLR中我没有遇到的某些内容)

我知道Dispose(bool)可以用来确保对象只被处理一次

因此,我的第二个问题是,如果一个类不需要实现终结器,那么它可以简单地实现如下所示的Dispose方法吗?

private bool objectDisposed;
public void Dispose()
{
    if (!objectDisposed)
    {
        // Release/dispose managed resources
        // ...
        // ...

        objectDisposed = true;
    }
}
我的第一个问题是,如果类没有实现终结器,那么 Dispose(bool)是否曾经被调用,参数为false?(例如。 通过CLR中我没有遇到的东西)

没有

因此,我的第二个问题是类是否不需要实现 然后,终结器可以简单地实现Dispose方法,如 下面

我不会,但你可以。如果您这样做了,您将重新发明IDisposable模式,如果这个类要扩展的话。正如HansPassant在评论中指出的,如果存在派生类,IDisposable模式非常方便。我宁愿一开始就遵循这种模式

基类

using System;

class BaseClass : IDisposable
{
   // Flag: Has Dispose already been called?
   bool disposed = false;

   // Public implementation of Dispose pattern callable by consumers.
   public void Dispose()
   { 
      Dispose(true);
      GC.SuppressFinalize(this);           
   }

   // Protected implementation of Dispose pattern.
   protected virtual void Dispose(bool disposing)
   {
      if (disposed)
         return; 

      if (disposing) {
         // Free any other managed objects here.
         //
      }

      // Free any unmanaged objects here.
      //
      disposed = true;
   }

   // Only if there are unmanaged resources.
   ~BaseClass()
   {
      Dispose(false);
   }
}
using System;

class DerivedClass : BaseClass
{
   // Flag: Has Dispose already been called?
   bool disposed = false;

   // Protected implementation of Dispose pattern.
   protected override void Dispose(bool disposing)
   {
      if (disposed)
         return; 

      if (disposing) {
         // Free any other managed objects here.
         //
      }

      // Free any unmanaged objects here.
      //
      disposed = true;

      // Call the base class implementation.
      base.Dispose(disposing);
   }

   // Only if there are unmanaged resources.
   ~DerivedClass()
   {
      Dispose(false);
   }
}
派生类

using System;

class BaseClass : IDisposable
{
   // Flag: Has Dispose already been called?
   bool disposed = false;

   // Public implementation of Dispose pattern callable by consumers.
   public void Dispose()
   { 
      Dispose(true);
      GC.SuppressFinalize(this);           
   }

   // Protected implementation of Dispose pattern.
   protected virtual void Dispose(bool disposing)
   {
      if (disposed)
         return; 

      if (disposing) {
         // Free any other managed objects here.
         //
      }

      // Free any unmanaged objects here.
      //
      disposed = true;
   }

   // Only if there are unmanaged resources.
   ~BaseClass()
   {
      Dispose(false);
   }
}
using System;

class DerivedClass : BaseClass
{
   // Flag: Has Dispose already been called?
   bool disposed = false;

   // Protected implementation of Dispose pattern.
   protected override void Dispose(bool disposing)
   {
      if (disposed)
         return; 

      if (disposing) {
         // Free any other managed objects here.
         //
      }

      // Free any unmanaged objects here.
      //
      disposed = true;

      // Call the base class implementation.
      base.Dispose(disposing);
   }

   // Only if there are unmanaged resources.
   ~DerivedClass()
   {
      Dispose(false);
   }
}
我的第一个问题是,如果类没有实现终结器,那么 Dispose(bool)是否曾经被调用,参数为false?(例如。 通过CLR中我没有遇到的东西)

没有

因此,我的第二个问题是类是否不需要实现 然后,终结器可以简单地实现Dispose方法,如 下面

我不会,但你可以。如果您这样做了,您将重新发明IDisposable模式,如果这个类要扩展的话。正如HansPassant在评论中指出的,如果存在派生类,IDisposable模式非常方便。我宁愿一开始就遵循这种模式

基类

using System;

class BaseClass : IDisposable
{
   // Flag: Has Dispose already been called?
   bool disposed = false;

   // Public implementation of Dispose pattern callable by consumers.
   public void Dispose()
   { 
      Dispose(true);
      GC.SuppressFinalize(this);           
   }

   // Protected implementation of Dispose pattern.
   protected virtual void Dispose(bool disposing)
   {
      if (disposed)
         return; 

      if (disposing) {
         // Free any other managed objects here.
         //
      }

      // Free any unmanaged objects here.
      //
      disposed = true;
   }

   // Only if there are unmanaged resources.
   ~BaseClass()
   {
      Dispose(false);
   }
}
using System;

class DerivedClass : BaseClass
{
   // Flag: Has Dispose already been called?
   bool disposed = false;

   // Protected implementation of Dispose pattern.
   protected override void Dispose(bool disposing)
   {
      if (disposed)
         return; 

      if (disposing) {
         // Free any other managed objects here.
         //
      }

      // Free any unmanaged objects here.
      //
      disposed = true;

      // Call the base class implementation.
      base.Dispose(disposing);
   }

   // Only if there are unmanaged resources.
   ~DerivedClass()
   {
      Dispose(false);
   }
}
派生类

using System;

class BaseClass : IDisposable
{
   // Flag: Has Dispose already been called?
   bool disposed = false;

   // Public implementation of Dispose pattern callable by consumers.
   public void Dispose()
   { 
      Dispose(true);
      GC.SuppressFinalize(this);           
   }

   // Protected implementation of Dispose pattern.
   protected virtual void Dispose(bool disposing)
   {
      if (disposed)
         return; 

      if (disposing) {
         // Free any other managed objects here.
         //
      }

      // Free any unmanaged objects here.
      //
      disposed = true;
   }

   // Only if there are unmanaged resources.
   ~BaseClass()
   {
      Dispose(false);
   }
}
using System;

class DerivedClass : BaseClass
{
   // Flag: Has Dispose already been called?
   bool disposed = false;

   // Protected implementation of Dispose pattern.
   protected override void Dispose(bool disposing)
   {
      if (disposed)
         return; 

      if (disposing) {
         // Free any other managed objects here.
         //
      }

      // Free any unmanaged objects here.
      //
      disposed = true;

      // Call the base class implementation.
      base.Dispose(disposing);
   }

   // Only if there are unmanaged resources.
   ~DerivedClass()
   {
      Dispose(false);
   }
}

将回答您的所有问题(编辑:链接到wayback版本,因为格式是正确的)谢谢各位,我已经阅读了第一个。简单的回答是“不!”模式的病毒功能可能会出现问题,如果一个基类实现了,并且您的派生类也有要处理的东西,那么您只能重写dispose(bool)方法,它们当然可以。问题的起因是Dispose()在基类中通常不声明为virtual。因此,如果客户机代码将派生类对象存储在基类引用中并调用Dispose(),则只执行基类的Dispose()方法。处置模式要求处置(bool)是虚拟的。将回答您的所有问题(编辑:链接到wayback版本,因为格式是正确的)谢谢各位,我已经阅读了第一个。简单的回答是“不!”模式的病毒功能可能会出现问题,如果一个基类实现了,并且您的派生类也有要处理的东西,那么您只能重写dispose(bool)方法,它们当然可以。问题的起因是Dispose()在基类中通常不声明为virtual。因此,如果客户机代码将派生类对象存储在基类引用中并调用Dispose(),则只执行基类的Dispose()方法。处置模式要求Dispose(bool)是虚拟的。要么这样,要么将类密封起来,使其无法扩展。我们真的必须摆脱这种处置模式的胡说八道,这个答案无助于我们达到目的。新规则:如果不密封该类,则始终将Dispose()方法设置为虚拟。C++中的标准规则,要么是使这个类被密封,要么使它不能扩展。我们真的必须摆脱这种处理模式的胡说,这个答案不能帮助我们到达那里。新规则:如果不密封该类,则始终将Dispose()方法设置为虚拟。C++ BTW中的标准规则