1.前言
Dispose和析构函数都是释放资源的,但是到底怎么释放资源呢?这两个区别在哪儿呢?本篇来看下。
2.概述
Dispose的释放资源一般都是非托管资源,比如Stream流这种。而析构函数里面可以自由定义释放你想要释放的资源,不局限于非托管。因为自由,所以更复杂。分别来看下。
先上示例:
static void Main(string[] args)
{
StreamReader? streamReader = null;
streamReader = new StreamReader("Test_.dll");
streamReader?.Dispose();// streamReader?.Close();
Console.ReadLine();
}
这里有Dispose调用和析构函数。先来看下示例streamReader的Dispose里面代码:
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
这是微软官方的C#代码,我们可以看到它里面分别调用了Dispose函数和GC.SuppressFinalize。Dispose函数里面主要是释放实例streamReader占用的资源,里面的代码大约就是一句话:
streamReader?.Close();
而GC.SuppressFinalize主要是通知CLR不运行StreamReader的析构函数调用,因为资源已经释放了,如果你在析构函数里面进行了streamReader实例的再次释放,可能会出错。所以这里调用GC.SuppressFinalize不运行执行StreamReader的析构函数。
来整体看下StreamReader类继承
public class StreamReader : TextReader
{
}
public abstract partial class TextReader : MarshalByRefObject, IDisposable
{
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
}
StreamReader的析构函数。继承了TextReader,而后者继承了IDisposable,进行了非托管资源的释放以及通知CLR不运行StreamReader的析构函数。
以上是Dispose的官方运行代码,关于析构函数的释放特点比较复杂,可以参考如下:
C#.Net析构知识引申(CLR级的剖析)
.Net8 PreView的析构函数再叙
C#.Net里面的析构函数为什么不会被执行?
3.总结
关联性,Dispose里面可以运行析构函数的抑制函数GC.SuppressFinalize(this);其它的应该就没有了。释放资源两者区别在于:Dispose就是主打释放非托管资源,程序里面如果有非托管资源,可以继承IDispose接口进行释放。析构函数可以进行更复杂的资源释放。当然掌控力度析构函数更强,个人更喜欢它。