C# 我应该什么时候创建析构函数?

C# 我应该什么时候创建析构函数?,c#,destructor,C#,Destructor,例如: public class Person { public Person() { } ~Person() { } } 我应该在什么时候手动创建析构函数? 什么时候需要创建析构函数 它被称为析构函数/终结器,通常在实现Disposed模式时创建 当您的类的用户忘记调用Dispose以确保(最终)您的资源得到释放时,这是一种回退解决方案,但您无法保证何时调用析构函数 在这里,接受的答案正确地显示了如何实现dispose模式。只有当您的类包含垃

例如:

public class Person
{
    public Person()
    {
    }

    ~Person()
    {
    }
}
我应该在什么时候手动创建析构函数?
什么时候需要创建析构函数

它被称为析构函数/终结器,通常在实现Disposed模式时创建

当您的类的用户忘记调用Dispose以确保(最终)您的资源得到释放时,这是一种回退解决方案,但您无法保证何时调用析构函数

在这里,接受的答案正确地显示了如何实现dispose模式。只有当您的类包含垃圾收集器无法自行清理的任何未处理资源时,才需要这样做


一个很好的实践是,如果不允许类的用户手动处理对象以立即释放资源,就不要实现终结器。

除非类维护非托管资源(如Windows文件句柄),否则不需要终结器。

如果您有非托管资源,并且需要确保它们当你的物体离开时会被清理干净。COM对象或文件处理程序就是一个很好的例子。

它被称为“终结器”,通常应该只为其状态(即:字段)包括非托管资源(即:通过p/invoke调用检索的句柄指针)的类创建一个终结器。但是,在.NET 2.0及更高版本中,实际上有一种更好的方法来处理非托管资源的清理:。有鉴于此,您应该再也不需要编写终结器了。

析构函数提供了一种隐式方式来释放封装在类中的非托管资源,当GC找到它们时,它们会被调用,并隐式调用基类的Finalize方法。如果您正在使用大量非托管资源,最好提供一种通过IDisposable接口释放这些资源的显式方法。请参阅《C#编程指南》:

更新:此问题已解决。谢谢你的提问!在博客上可以看到一长串人们通常认为的关于定稿的谬误

我应该在什么时候手动创建析构函数

几乎从来没有

通常,只有当您的类保留一些昂贵的非托管资源时,才会创建析构函数,而这些资源必须在对象离开时清理。最好使用一次性模式来确保资源被清理干净。析构函数本质上是一种保证,如果对象的使用者忘记处理它,资源最终仍然会被清除。(也许吧。)

如果使用析构函数,请非常小心,并了解垃圾收集器的工作原理。析构函数真的很奇怪:

  • 它们不会在你的线程上运行;他们用自己的思路运行。不要造成僵局
  • 从析构函数引发的未处理异常是个坏消息。它在它自己的线程上;谁来接住它
  • 可以在构造函数启动之后但在构造函数完成之前对对象调用析构函数。正确编写的析构函数不会依赖于构造函数中建立的不变量
  • 析构函数可以“复活”一个对象,使一个死去的对象再次复活。真奇怪。不要这样做
  • 析构函数可能永远不会运行;您不能依赖于计划完成的对象。可能会,但这不是保证
在析构函数中,通常为真的几乎没有什么是真的。要非常非常小心。编写正确的析构函数非常困难

什么时候需要创建析构函数


测试编译器中处理析构函数的部分时。我从未在生产代码中这样做过。我很少编写操作非托管资源的对象。

我使用析构函数(仅用于调试目的)查看是否正在从WPF应用程序范围内的内存中清除对象。我不确定垃圾收集是否真的从内存中清除了对象,这是一种很好的验证方法。

实际上,它在C#中并没有被称为析构函数,这是有充分理由的。事实上是这样。谢谢你给我投了反对票,因为你错了。关于这个特定问题,请参阅MSDN库:@TomTom它的正式名称是destructorIts实际上不是一个回退方法,它只允许GC在对象释放非托管资源时进行管理,实现IDisposable允许您自己管理。实际上,它被称为destructorNow我很困惑。它是终结器还是析构函数?C#规范实际上称它为析构函数。有些人认为这是一个错误@托马塞丁-。C#使用析构函数语法,但实际上它创建了一个。我喜欢这里的注释,real panto:)@configurator:Nope。假设对象的第三个字段初始值设定项带有一个名为静态方法的终结器,该方法导致引发异常。第四个字段初始值设定项何时运行?从未。但该对象仍在分配中,必须最终确定。见鬼,您甚至不能保证dtor运行时double类型的字段已完全初始化。在编写double的过程中可能会有一个线程中止,现在终结器必须处理一个半初始化的半零double。非常好的帖子,但是应该说“应该在您的类持有一些昂贵的非托管对象或导致大量非托管对象存在时创建”——例如,我在C语言中使用了一个矩阵类,它利用一个基本的本地C++矩阵类来做很多繁重的操作——我制作了很多矩阵-在这个特定的情况下,一个“析构函数”远远优于IDISPOLISTABLE。因为它可以更好地同步房子的托管和非托管部分,pythonnet使用析构函数在非托管CPythonAwesome文章中释放GIL。这方面的道具-->“额外的额外乐趣:在调试器中运行程序时,运行时使用更少的攻击性代码生成和更少的攻击性垃圾收集,因为这是一种糟糕的调试体验