0
public class StorageOfData
{
    public static StorageOfData instance;

    private StorageOfData()
    { }

    public static StorageOfData getInstance()
    {
        if (instance == null)
            instance = new StorageOfData();
        return instance;
    }

    private List<List<VersionOfFile>> list = new List<List<VersionOfFile>>();

    public List<VersionOfFile> this[int index]
    {
        get
        {
            return list[index];
        }
    }

    public void RestoreDataFromFile(String path)
    {
        StorageOfData DATA;
        XmlSerializer mySerializer = new XmlSerializer(typeof(StorageOfData));
        FileStream myFileStream = new FileStream(path + @"BAK\" + "history.xml", FileMode.Open);
        DATA = (StorageOfData)mySerializer.Deserialize(myFileStream);
    }

    public void SaveDataToFile(String path)
    {
        StorageOfData DATA = StorageOfData.getInstance();
        XmlSerializer mySerializer = new XmlSerializer(typeof(StorageOfData));
        StreamWriter myWriter = new StreamWriter(path + @"BAK\" + "history.xml");
        mySerializer.Serialize(myWriter, DATA);
        myWriter.Close();
    }

    public void AddNewEntryIfRenamed(string filename, string real_filename, DateTime date, bool isDeleted)
    {
        for (int i = 0; i < list.Count; i++)
        {

            if (list[i][list[i].Count - 1].Filename == filename)
            {
                list[i].Add(new VersionOfFile(filename, real_filename, date, isDeleted));
                return;
            }
        }
        list.Add(new List<VersionOfFile>());
        list[list.Count - 1].Add(new VersionOfFile(filename, real_filename, date, isDeleted));
    }


    public void AddNewEntryIfCopyExists(string filename, string real_filename, DateTime date, bool isDeleted)
    {
        for (int i = 0; i < list.Count; i++)
        {

            if (list[i][list[i].Count - 1].Filename == filename)
            {
                list[i].Add(new VersionOfFile(filename, real_filename, date, isDeleted));
                return;
            }
        }
        list.Add(new List<VersionOfFile>());
        list[list.Count - 1].Add(new VersionOfFile(filename, real_filename, date, isDeleted));
    }

    public void AddNewEntry(string filename, DateTime date, bool isDeleted)
    {
        for (int i = 0; i < list.Count; i++)
        {

            if (list[i][list[i].Count - 1].Filename == filename)
            {
                list[i].Add(new VersionOfFile(filename, date, isDeleted));
                return;
            }
        }
        list.Add(new List<VersionOfFile>());
        list[list.Count - 1].Add(new VersionOfFile(filename, date, isDeleted));
    }

}

internal struct VersionOfFile
{
    private string filename;
    private string real_filename;
    private DateTime date;
    private bool isDeleted;

    public string Filename
    {
        get
        {
            return filename;
        }
    }

    public string Real_filename
    {
        get
        {
            return real_filename;
        }
    }

    public DateTime Date
    {
        get
        {
            return date;
        }
    }

    public bool IsDeleted
    {
        get
        {
            return isDeleted;
        }
    }

    public VersionOfFile(string filename, string real_filename, DateTime date, bool isDeleted)
    {
        this.filename = filename;
        this.real_filename = real_filename;
        this.date = date;
        this.isDeleted = isDeleted;
    }

    public VersionOfFile(string filename, DateTime date, bool isDeleted)
    {
        this.filename = filename;
        this.date = date;
        this.isDeleted = isDeleted;
        this.real_filename = String.Empty;
    }

I'm writing a simple program for backuping my files, but I run into a problem. I should log any changes, but when I try to serialize my singletone-storage of information about changes, I get just an empty .xml file. What should I do to seriallise dynamaic arrays (List<>) ??

dbc
  • 104,963
  • 20
  • 228
  • 340
Byg1
  • 1
  • 1
    OK... with all due respect @Byg1 for a 'a simple program' I think you are over complicating things... Can you ether explain exactly what you are attempting to achieve or provide a sample of the XML you would expect to see.... – Monty Mar 28 '16 at 16:17
  • 1
    To serialize your `StorageOfData` class with `XmlSerializer`, it must have a public parameterless constructor. Yours is private. See http://stackoverflow.com/questions/267724/why-xml-serializable-class-need-a-parameterless-constructor. You might have other problems beyond that. If you do, try to break your code down into [minimal, complete examples](http://stackoverflow.com/help/mcve) of each problem. – dbc Mar 28 '16 at 19:36
  • 1
    Also, `XmlSerializer` only serializes properties with a public `get` and `set`. See https://stackoverflow.com/questions/575432/why-isnt-my-public-property-serialized-by-the-xmlserializer. So your `VersionOfFile` won't serialize properly. – dbc Mar 28 '16 at 19:43
  • @dbc The constructor does not have to be public, only parameterless. The serializer can call it via reflection. – Rotem May 11 '16 at 09:28
  • @Rotem - It seems you're right: https://dotnetfiddle.net/Li4dG4. That's inconsistent with what is stated [here](https://support.microsoft.com/en-us/kb/330592): *When you try to use the XmlSerializer class to serialize a class that does not have a public default constructor, you may receive [a] System.InvalidOperationException exception error message*. And in [Troubleshooting Common Problems with the XmlSerializer](https://msdn.microsoft.com/en-us/library/aa302290.aspx): *Test.NonSerializable cannot be serialized because it does not have a default public constructor.* – dbc May 11 '16 at 18:57

2 Answers2

0

Also , a simpler way (in my opinion to do this) , as dictated in this video (https://www.youtube.com/watch?v=UvEF7UPh1Qg) , is to just create a class where you specify the elements and attributes of the xml file and then just fill them in and give them values through code.

Damianos
  • 59
  • 5
0

To serialize your class you must put public read/write attributes for data to be serialized.

Just add

public List<List<VersionOfFile>> List
    {
        get { return list; }
        set { list = value; }
    }

To StorageOfData class and add setter to attributes in VersionOfFile struct.

PS :

Your code is not optimized for your need. Try to secure your singleton class Thread safe Singleton. For performance issue you can use Dictionary< string, List< OfFileVersion>>" and add [XmlAttribute] tag to attributes of struct to reduce file size. Instead of

<VersionOfFile>
    <Filename>test</Filename>
  </VersionOfFile> 

You will get

<VersionOfFile Filename="test"/>

Add Try/ Catch Bloc, Test if Back Folder Exist, Use System.IO.Path.Combine to add path, Test if History.xml file exists and backup it before adding new file, etc.

S. Gmiden
  • 147
  • 5