通过序列化支持的单例类

我正在写一个Singleton类来访问一个List。 第一次初始化Singleton时,通过反序列化一个xml文件来填充这个List。

这一切都很好,但我希望这个列表是可更新的,为了做到这一点,我现在不得不重新序列化每次我添加或删除它。

我宁愿只有一个调用序列化列表时,从内存中删除对象。 不过我觉得在Destructor中尝试这样做可能会导致数据丢失等等。

实现这种行为的最佳模式是什么?

谢谢

C# 中的析构函数与C ++析构函数非常不同 。 它们不是实际的析构函数,它们是在不再需要的完全正确的对象上运行的,而是处理非托管资源( MSDN )的最后一种措施:

对于使用非托管资源(如文件句柄或数据库连接)的类,您应该重写Finalize,以便在垃圾回收过程中丢弃使用它们的托管对象时必须释放的文件句柄或数据库连接。

因此,使用Finalizer(Destructor)与托管资源进行交互操作是一个糟糕的主意,因为:

即使一个对象指向另一个对象,两个对象的终结器也不能保证以任何特定的顺序运行。 也就是说,如果对象A具有对象B的引用并且都具有终结器,则在对象A的终结器开始时,对象B可能已经被终止。

反序列化的数据列表可能是正确的,或者在以前的GC运行中已经回收了。 即使现在的垃圾收集器不是这样,没有人能保证这样的问题不会出现在下一个.NET版本中。 在Finalizer中访问托管资源实际上是一个未定义的行为。

可能的方案

考虑到你的对象是单例的,所以只有在应用程序退出的时候它才能被垃圾回收(或者永远不会被请求的话),允许这种持久化存储到对象数据的最简单的方法是将事件处理程序附加到应用程序close (退出)事件 。

... public static Singleton Instance { get { if (_Instance == null) { _Instance = new Singleton(); Application.Exit += (sender, args) => { _Instance.SaveChanges(); } } return _Instance; } } 

或者如果你的Singleton是基于它的使用,使用合适的Lazy<T>构造函数 。