我今天遇到了意想不到的问题,试图序列化/反序列化包含bool [,] DataMember的DataContract。 csc和运行时都不会反对这个定义,但是反序列化的bool [,] DataMember中的值是不正确的。在阅读this thread后,我最初的反应是将有问题的属性转换为锯齿状数组。不过,由于this article通知锯齿阵列在对角或随机访问时(正好是我的用例)表现糟糕,所以我不得不放弃这种方法。因此,我最终编写了上述msdn线程中提出的解决方案的策划版本(将矩形转换为锯齿形,并且在导出/导入时将其转换为反正方形,请参阅下面的代码摘录),并且工作正常。DataContractSerializer不支持矩形阵列
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;
}
我想知道如果有一个更简洁的解决方案,或这种或另一种方法。
“锯齿状阵列表现得很糟糕” - 但与I/O,转换和序列化相比,这确实很重要吗? –
持久性格式和运行时格式不必相同 –
在应用程序的核心,所讨论的数组被访问数百万次(并且它是一个电话应用程序,其中CPU不那么强大)。序列化仅在App停用或关闭时发生(不频繁)。 – javvin