Ho avuto un problema inatteso oggi, tentando di serializzare/deserializzare un DataContract contenente un membro [,] DataMember. Né csc né runtime hanno contestato questa definizione, tuttavia i valori nel boer deserializzato [,] DataMember non erano corretti. Dopo aver letto this thread, la mia reazione iniziale è stata quella di convertire la proprietà problematica in una matrice seghettata. Presto però ho dovuto abbandonare questo approccio poiché lo this article informa che gli array frastagliati funzionano miseramente quando si accede in diagonale o in modo casuale (esattamente il mio caso d'uso). Così ho finito per scrivere una versione curata della soluzione proposta nel precedente thread msdn (convertire rettangolare in jagged e viceversa dopo l'esportazione/importazione, vedere gli estratti di codice sotto) e questo funziona bene.DataContractSerializer che non supporta matrici rettangolari
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;
}
Mi chiedo tuttavia se c'è una soluzione più concisa a questo o un altro approccio.
"gli array frastagliati si comportano in modo miserabile", ma ciò conta davvero rispetto all'I/O, alla conversione e alla serializzazione? –
Il formato di persistenza e il formato di runtime non devono essere gli stessi –
Al centro dell'applicazione si accede l'array in questione milioni di volte (ed è un'app per telefono in cui le CPU non sono così potenti). La serializzazione avviene solo quando l'app si disattiva o si chiude (poco frequente). – javvin