gpt4 book ai didi

c# - Dispose、Finalize、SuppressFinalize 方法

转载 作者:行者123 更新时间:2023-11-30 14:09:38 27 4
gpt4 key购买 nike

我可以在同一个类中实现这两个方法吗?

public class MyClass : IDisposable
{
// some implementation
// if i missed to call Dispose() method;
~MyClass()
{
// it means, clear all does not mananage resources
// but dont use Dispose() method
}
public void Dispose()
{
// clear resources
// if i call this method will i can do this:
GC.SuppressFinalize()
// it means dont use Finalizw method for this object
}
}

我说的对吗?因为我无法理解这个 GC.SuppressFinalize() 方法?

最佳答案

是的,如您所见,您可以实现这两种方法。

通常,如果对象可以同时具有托管和非托管引用,则正确的模式是:

public class MyClass : IDisposable
{
~MyClass()
{
Dispose(false);
}
public void Dispose()
{
GC.SuppressFinalize(this);
Dispose(true);
}
public virtual void Dispose(bool disposing)
{
if(disposing)
{
// clear MANAGED references
}
// free UNMANAGED resources
}
}

但是您可以根据需要实现它。这只是一个模式。例如,如果您没有任何非托管资源并且您的类是密封的(因此您可以确保它永远不会使用任何非托管资源),您可以像这样实现它:

public sealed class MyClass : IDisposable
{
public void Dispose()
{
// release managed references
}
}

忘记终结器吧。

在第一个模式中,GC.SuppresFinalize(this) 正在做的是告诉垃圾收集器它不应该调用终结器(~MyClass()方法)释放对象时:如果您专门调用了 Dispose(),那么您已经调用了您的虚拟 Dispose(bool) 函数,所以为什么还要调用它?

问题是 C# 中的终结器本身是不确定的:你不知道它什么时候会被调用......你甚至不能保证它会被调用(尽管它会在正常清理期间(如果之前未调用)),这就是 IDisposable 存在的原因,它是一种确定性释放托管对象的方式,释放并释放非托管引用由它分配的资源。

如果一个对象被 GC 释放,它持有的所有托管引用也将被释放,因此在调用终结器时无需清除托管引用。

但是,您的应用程序应该尽最大努力释放它拥有的任何非托管资源。

如果您忘记了 Dispose(),应该有最后一次释放它们的机会(当 GC 收集对象时,或者在应用程序运行时的最终清理时)。这就是为什么在正常模式中您还实现了一个终结器,并告诉它清理非托管资源如果您之前没有这样做

请注意,与流行的看法相反,对 Dispose() 的调用没有什么特别之处,它只是一个方法调用:您可以将其称为 FreeMyObject()FooBar() 如果你愿意的话。它不会让垃圾收集器释放任何内存。使用 IDisposable 有一个模式,它非常重要,以至于它有自己的语言语法结构(using block ),但仅此而已,一个图案。您可以在完全不实现 IDisposable 的情况下执行与 Dispose() 相同的操作。

关于c# - Dispose、Finalize、SuppressFinalize 方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28230183/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com