无法将对象序列化为XML文件

时间:2014-12-26 12:53:01

标签: c# xml save

我试图将Matrix字典保存到Xml文件中。 我的Matrix类属性是:

public class Matrix 
{
    public int Lines { get; set; }
    public int Columns { get; set; }
    public double[,] Elements { get; set; }
    public string name { get; set; }
 }

经过多次尝试,我写了这个:

string fileName = dlg.FileName;
Stream writer = new FileStream(fileName,FileMode.Create);

foreach (KeyValuePair<String, Matrix> matrice in CalMat.Calculatrice.listMatrix)
{
    XmlSerializer x = new XmlSerializer(matrice.GetType());
    x.Serialize(writer, matrice);
}

writer.Close();

如果我使用一个矩阵运行此代码,则会创建该文件,但我只写了这句话:

<?xml version="1.0"?><KeyValuePairOfStringMatrix xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" /><?xml version="1.0"?> 

我认为我的代码遗漏了一些东西,但我不知道是什么。我想是一种写法。

感谢您的时间!

2 个答案:

答案 0 :(得分:1)

我不认为默认的KeyValuePair是可序列化的, 尝试构建自己的KeyValuePair类:

[Serializable]
[XmlType(TypeName="MyTypeName")]
public struct KeyValuePair<T1, T2>
{
  public T1 Key { get; set; }
  public T2 Value { get; set; }
}

答案 1 :(得分:0)

使用BinaryFormatter这是代码:

[Serializable]  // mark with Serializable
public class Matrix
{
    public Matrix(string name, int lines, int columns)
    {
        Name = name;
        Lines = lines;
        Columns = columns;
        Elements = new double[Lines, Columns];
    }
    public int Lines { get; set; }
    public int Columns { get; set; }
    public double[,] Elements { get; set; }
    public string Name { get; set; }
}

public static void Main()
{
    var path = @"D:\serialize.data"; // use the path that you want

    // this is an example collection
    var listMatrix = new Dictionary<string, Matrix>();
    listMatrix.Add("matrix_1", new Matrix("Matrix 1", 1, 2));
    listMatrix.Add("matrix_2", new Matrix("Matrix 2", 2, 2));

    // Serialization
    var stream = new FileStream(path, FileMode.Create);
    var binaryFormatter = new BinaryFormatter();
    binaryFormatter.Serialize(stream, listMatrix);
    stream.Close();

    // Deserialization
    stream = new FileStream(path, FileMode.Open);
    var result = (Dictionary<string, Matrix>)binaryFormatter.Deserialize(stream);
    stream.Close();
}

使用XmlSerializer,这是代码:

// I implement my custom KeyValuePair to serialize (because XmlSerializer can not serialize the .net KeyValuePair)
public struct CustomKeyValuePair<T1, T2>
{
    public CustomKeyValuePair(T1 key, T2 value): this()
    {
        Key = key;
        Value = value;
    }

    public T1 Key { get; set; }
    public T2 Value { get; set; }

    // here I specify how is the cast
    public static explicit operator CustomKeyValuePair<T1, T2>(KeyValuePair<T1, T2> keyValuePair)
    {
        return new CustomKeyValuePair<T1, T2>(keyValuePair.Key, keyValuePair.Value);
    }
}

// Matrix class used to Serialize with XmlSerailzer
public class Matrix
{
    public Matrix() { }  // need a default constructor
    public Matrix(string name, int lines, int columns)
    {
        Name = name;
        Lines = lines;
        Columns = columns;
        Elements = new double[Columns][];
        for (int i = 0; i < Elements.Length; i++)
        {
            Elements[i] = new double[Columns];
        }
    }
    public int Lines { get; set; }
    public int Columns { get; set; }
    public double[][] Elements { get; set; }  // I use double[][] because XmlSerialzer can not serialize a two-dimensional array (double[,])
    public string Name { get; set; }
}

public static void Main()
{
    var path = @"D:\serialize.data"; // use the path that you want

    // this is an example collection
    var listMatrix = new Dictionary<string, Matrix>();
    listMatrix.Add("matrix_1", new Matrix("Matrix 1", 1, 2));
    listMatrix.Add("matrix_2", new Matrix("Matrix 2", 2, 2));

    // Serialization
    var stream = new FileStream(path, FileMode.Create);
    var xmlSerializer = new XmlSerializer(typeof(CustomKeyValuePair<string, Matrix>[]));
    var aux = listMatrix.Select(keyValuePair => (CustomKeyValuePair<string, Matrix>) keyValuePair).ToArray();
    xmlSerializer.Serialize(stream, aux);  // I serialize an array to make easy the deserailizer
    stream.Close();

    // Deserialization
    stream = new FileStream(path, FileMode.Open);
    var result = (CustomKeyValuePair<string, Matrix>[])xmlSerializer.Deserialize(stream);
    stream.Close();
}