开发者

Static, sealed, singleton or something else for application-wide data which is serialized/deserialized

My application loads an XML data set from a file on disk using serialization, keeps that dataset in memory for various operations, then serializes the data set back to disk as it closes. Currently, the object which stores that data set is a child property of the MainForm class. I can access it from other classes using MainForm.MyDataSet.

However, I'd like to implement better practice in terms of the storage of MyDataSet. In an ideal world, I think that it should be static, but this prevents deserialization from XML. I tried making it a singleton, but the instance of the singl开发者_如何学JAVAeton still needs to 'live' somewhere.

What is best practice in this kind of scenario?


It really depends on your implementation of the singleton. If you use the static reference of the class strategy, which is pretty much the norm, then the singleton class is holding the instance. (That's the whole point.)

using System;

public class MyDataset
{
   private static MyDataset instance;

   // TODO: add property that is holding the dataset

   private MyDataset() {}

   public static MyDataset Instance
   {
      get 
      {
         if (instance == null)
         {
            instance = new MyDataset();
         }
         return instance;
      }
   }
}


You can use a Static class if you like (tested this in VS 2010 beta 2 compiled against FrameWork 2.0, and 4.0).

Here we are just using Static methods (to get and set the private instance) to work around the fact you can't have Static properties. The only real difference I see, comparing this approach with using a Public class, as in AlphaZero's excellent response, is that ... since you can never use 'new on a Static class ... you have a slight additional level of "singleton-ness" :)

< note 1 : I'm just beginning to "explore" this area myself, so I very much welcome any comments, feedback, on the sample code shown here : I'm here to learn :) >

< note 2 : the one thing I really question is whether I have "done the right thing" in the readXMLintoDataSet method in "lazy instantiating" of the private DataSet instance : perhaps using Clear() if the DataSet instance is already instantiated is not enough ? Perhaps the "right thing" is to always use Dispose() on it and re-instantiate it ? >

< note 3 : I use extra-longer variable/method names here for ... I hope ... making the code communicate : yes, you would have to type out something like :

TestStaticXMLDataSet.readXMLintoDataSet("someXML.xml");

to use this code ... assuming your consumer-class is in a different namespace ... and, obviously, if you make this class share the consumer-class namespace you can shorten it up the use syntax. >

using System.Xml;
using System.IO;
using System.Data;

namespace TestStaticXMLDataSet
{
    public static class DataSetClass
    {
        internal static DataSet _dataSet;

        public static void setDataSet(DataSet incomingDataSet)
        {
            _dataSet = incomingDataSet;
        }

        public static DataSet getDataSet()
        {
            return _dataSet;
        }

        public static void readXMLintoDataSet(string filePath)
        {
            if (_dataSet == null)
            {
                _dataSet = new DataSet();
            }
            else
            {
                _dataSet.Clear();
            }

            _dataSet.ReadXml(filePath);
        }

        public static void writeDataSetToXML(string filePath)
        {
            if (_dataSet == null)
            {
                return;
            }
            else
            {
                _dataSet.WriteXml(filePath);
            }
        }
    }
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜