DataContractSerializer不支持矩形数组

jav*_*vin 6 c#

我今天遇到了一个意想不到的问题,试图序列化/反序列化包含bool [,] DataMember的DataContract.csc和运行时都没有反对这个定义,但是反序列化的bool [,] DataMember中的值只是不正确.读完这个帖子之后,我最初的反应是将有问题的属性转换为锯齿状数组.我不得不很快放弃这种方法,但是因为这篇文章告诉我,当对角线或随机访问时(参与我的用例),锯齿状数组表现不佳.所以我最终编写了上述msdn线程中提出的解决方案的策划版本(将矩形转换为锯齿状,反之亦然,导出/导入,请参阅下面的代码摘录),这样可以正常工作.

public object GetDeserializedObject(object obj, Type targetType)
{
    if (obj is GridArrayWrapper)
    {
        bool[,] arr;
        GridArrayWrapper wrapper = (GridArrayWrapper)obj;
        if (wrapper.Array == null) return null;
        int d0 = wrapper.Array.Length;
        if (d0 == 0)
        {
            return new bool[0, 0];
        }
        var d1 = wrapper.Array[0].Length;
        arr = new bool[d0, d1];
        for (int i = 0; i < d0; i++)
        {
            if (wrapper.Array[i].Length != d1) throw new ArgumentException("Not a rectangular array");
            for (var j = 0; j < d1; j++)
            {
                arr[i, j] = wrapper.Array[i][j];
            }
        }
        return arr;
    }
    return obj;
}

public object GetObjectToSerialize(object obj, Type targetType)
{
    if (obj is bool[,])
    {
        bool[,] arr = (bool[,])obj;
        GridArrayWrapper wrapper = new GridArrayWrapper();
        int d0 = arr.GetLength(0);
        int d1 = arr.GetLength(1);
        wrapper.Array = new bool[d0][];
        for (int i = 0; i < wrapper.Array.Length; i++)
        {
            wrapper.Array[i] = new bool[d1];
            for (int j = 0; j < d1; j++)
            {
                wrapper.Array[i][j] = arr[i, j];
            }
        }
        return wrapper;
    }
    return obj;
}
Run Code Online (Sandbox Code Playgroud)

我想知道是否有更简洁的解决方案来解决这个问题或另一种方法.

Rom*_*sse 0

我不会实现 GetDeserializedObject 和 GetObjectToSerialize,而是公开一个不同的对象进行序列化。顺便说一句,一维数组就足够了。我会这样做:

//No Datamember here
public bool[,] Data;

[DataMember(Name="Data")]
public bool[] XmlData
{
  get {
    bool[] tmp = new bool[Data.GetLength(0) * Data.GetLength(1)];
    Buffer.BlockCopy(Data, 0, tmp, 0, tmp.Length * sizeof(bool));
    return tmp;
  }
  set {
    bool[,] tmp = new bool[,];
    Buffer.BlockCopy(value, 0, tmp, 0, value.Length * sizeof(bool));
    this.Data = tmp;  
  }
}
Run Code Online (Sandbox Code Playgroud)