gpt4 book ai didi

c# - 当我们没有析构函数时为什么要调用 SuppressFinalize

转载 作者:IT王子 更新时间:2023-10-29 04:21:45 28 4
gpt4 key购买 nike

我有几个问题无法得到正确的答案。

1) 当我们没有析构函数时,为什么要在 Dispose 函数中调用 SuppressFinalize。

2) Dispose 和 finalize 用于在对象被垃圾回收之前释放资源。无论它是托管资源还是非托管资源,我们都需要释放它,然后为什么我们需要在 dispose 函数中设置一个条件,当我们从 IDisposable:Dispose 调用这个被覆盖的函数时说 pass 'true' 并在从 finalize 调用时传递 false。

下面是我从网上复制的代码。

class Test : IDisposable
{
private bool isDisposed = false;

~Test()
{
Dispose(false);
}

protected void Dispose(bool disposing)
{
if (disposing)
{
// Code to dispose the managed resources of the class
}
// Code to dispose the un-managed resources of the class

isDisposed = true;
}

public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
}

如果我删除 bool 保护的 Dispose 函数并实现如下所示会怎样。

   class Test : IDisposable
{
private bool isDisposed = false;

~Test()
{
Dispose();
}


public void Dispose()
{
// Code to dispose the managed resources of the class
// Code to dispose the un-managed resources of the class
isDisposed = true;

// Call this since we have a destructor . what if , if we don't have one
GC.SuppressFinalize(this);
}
}

最佳答案

我在这里冒险,但是...大多数人不需要需要成熟的处置模式。它旨在直接访问非托管资源(通常通过 IntPtr)和继承。大多数时候,这两者实际上都不是必需的。

如果您只是持有对实现 IDisposable 的其他对象的引用,您几乎肯定不需要终结器 - 直接持有资源的任何对象都负责处理它。你可以做这样的事情:

public sealed class Foo : IDisposable
{
private bool disposed;
private FileStream stream;

// Other code

public void Dispose()
{
if (disposed)
{
return;
}
stream.Dispose();
disposed = true;
}
}

请注意,这不是线程安全的,但这可能不会成为问题。

通过不必担心子类直接持有资源的可能性,你不需要抑制终结器(因为没有终结器)——你也不需要提供子类自定义处置的方法任何一个。没有继承,生活会更简单。

如果您确实需要允许不受控制的继承(即您不愿意打赌子类会有非常特殊的需求),那么您需要采用完整模式。

请注意,使用 .NET 2.0 中的 SafeHandle,与 .NET 1.1 相比,您需要自己的终结器的情况甚至更少。


为了解决您关于为什么首先有一个 disposing 标志的观点:如果您在终结器中运行,您引用的其他对象可能已经被终结。您应该让它们自行清理,并且您应该只清理您直接拥有的资源。

关于c# - 当我们没有析构函数时为什么要调用 SuppressFinalize,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2605412/

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