概要
1.1 问:析构函数一定会被调用吗
答:不一定
1.2 试验结果
测试情景 | 内存回收是否发生 | 系统结束前后 | 对象设置为null | 是否调用析构感受 |
1 | 是 | 前 | 是 | 调用 |
2 | 否 | 不调 | ||
3 | 后 | 是/否 | 不调 | |
4 | 否 | 前/后 | 是/否 | 不调 |
代码
using System;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
namespace 析构函数一定会被调用吗
{
internal class Program
{
static void Main(string[] args)
{
Console.WriteLine("");
MyData myData = new MyData();
myData.index++;
Console.WriteLine(myData.index);
myData = null; // 不置为null 也不会执行析构函数
GC.Collect();//回收垃圾 ,这里回收会执行析构函数
Console.ReadKey();
//GC.Collect();//回收垃圾 ,这里回收 就不会执行析构函数
// 不调用回收,也不会执行析构函数
}
}
/// <summary>
/// 测试用的实例
/// </summary>
[Serializable]
class MyData : BindClose
{
public int index = 0;
public MyData()
{
load();
}
protected override void LoadData(object o)
{
MyData myData = (MyData)o;
this.index = myData.index;
}
~MyData()
{
close();
}
}
/// <summary>
/// 绑定具有备份功能的接口
/// </summary>
interface IBindClose
{
void close();
}
/// <summary>
/// 具有自己备份功能的类
/// 关闭的时候备份数据
/// 构造的时候重新加载备份的数据
/// </summary>
[Serializable]
abstract class BindClose
{
public void close()
{
lock (this)
{
string name = this.GetType().Name;
using (FileStream fileStream = new FileStream(name, FileMode.OpenOrCreate))
{
BinaryFormatter binaryFormatter = new BinaryFormatter();
binaryFormatter.Serialize(fileStream, this);
}
}
}
public void load()
{
lock(this)
{
string name = this.GetType().Name;
using (FileStream fileStream = new FileStream(name, FileMode.OpenOrCreate))
{
BinaryFormatter binaryFormatter = new BinaryFormatter();
if (fileStream.Length > 0)
{
object o = binaryFormatter.Deserialize(fileStream);
LoadData(o);
}
}
}
}
abstract protected void LoadData(object o);
}
}
运行结果
调用析构函数的时候,数会增加
![](https://i-blog.csdnimg.cn/blog_migrate/12f271f061aef737a950a89e1457c99b.png)
附录
无