Wystąpił dzisiaj nieoczekiwany problem, próbując przekształcić/deserializować DataContract zawierający bool [,] DataMember. Ani csc, ani środowisko wykonawcze nie wyraziły sprzeciwu wobec tej definicji, jednak wartości w deserializowanym boolu [,] DataMember właśnie nie były poprawne. Po przeczytaniu this thread, moją pierwszą reakcją było przekształcenie problematycznej właściwości w poszarpaną tablicę. Musiałem zrezygnować z tego podejścia wkrótce, ponieważ this article informuje, że postrzępione tablice wykonują marnie, gdy są dostępne po przekątnej lub losowo (dokładnie mój przypadek użycia). Więc skończyłem pisać napisaną wersję rozwiązania zaproponowanego w powyższym wątku msdn (konwertuj prostokątny na postrzępiony i visa versa przy eksporcie/imporcie, zobacz fragmenty kodu poniżej) i to działa dobrze.DataContractSerializer nie obsługuje prostokątnych tablic
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;
}
Zastanawiam się jednak, czy istnieje bardziej zwięzłe rozwiązanie tego lub innego podejścia.
"że poszarpane tablice wykonują żałośnie" - ale czy to naprawdę ma znaczenie w porównaniu z we/wy, konwersją i serializacją? –
Format utrwalania i format środowiska wykonawczego nie muszą być takie same. –
W rdzeniu aplikacji omawiana macierz jest dostępna miliony razy (i jest to aplikacja telefoniczna, w której procesory nie są tak wydajne). Serializacja ma miejsce tylko po wyłączeniu lub zamknięciu aplikacji (rzadko). – javvin