【问题标题】:Unable to serialize object into XML file无法将对象序列化为 XML 文件
【发布时间】:2015-02-23 18:48:11
【问题描述】:

我正在尝试将 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"?> 

我认为我的代码缺少一些东西,但我不知道是什么。我猜是写方法。

感谢您的宝贵时间!

【问题讨论】:

  • 尝试使用System.Xml.XmlDictionary和相关的XmlDictionaryReader和Writer

标签: c# xml save


【解决方案1】:

使用 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();
}

【讨论】:

  • 我知道 BinaryFormatter。我试过了,它有效! =) 谢谢你的帮助。但我很沮丧,我无法让它与 Xml 一起工作。
  • @CAREAlexis 如果要使用 Xml,则不能使用 System.Collections.Generic 中的 KeyValuePair。您需要像我建议您的代码一样创建自定义 KeyValuePair
  • 我在使用 BinaryFormatter 之前尝试过。我有一个错误,我无法将常规 KeyValuePair 转换为我自己的 KeyValuePair。我是否还需要告诉我的字典使用我自己的 keyValuePair?
  • @CAREAlexis 当然,您不能将.net KeyValuePair 转换为您自己的KeyValuePair,您需要指定转换方式。你也可以说你的字典来使用你自己的 KeyValuePair。我会将所有代码发布给您。
【解决方案2】:

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

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

【讨论】:

  • 我尝试按照您说的做,但出现错误。该程序无法将默认 KeyValuePair (System.Collections.Generic.KeyValuePair 我不知道如何解决这个问题:/
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-03-26
  • 1970-01-01
  • 2011-05-06
  • 1970-01-01
相关资源
最近更新 更多