Сериализация массива целых чисел с помощью XmlSerializer

StackOverflow https://stackoverflow.com/questions/553824

  •  23-08-2019
  •  | 
  •  

Вопрос

Я столкнулся с проблемой при попытке сериализовать многомерный массив целых чисел через XmlSerializer для проекта XNA, над которым я работаю.Я могу без проблем сериализовать все остальные данные (логические значения, строки, даже цвета и т. д.).Я также видел, как многие люди утверждали, что XmlSerializer также может обрабатывать (одномерные) массивы целых чисел.Есть ли ограничение на многомерные массивы или здесь происходит что-то еще?

Вот соответствующий код:

int[,,] scoredata = scores;  // Populated with data elsewhere 

filename = Path.Combine(container.Path, "scoredata.sav"); 
stream = File.Open(filename, FileMode.Create); 
serializer = new XmlSerializer(typeof(int[,,])); 
serializer.Serialize(stream, scoredata);  // This line throws the exception. 
stream.Close(); 

Я получаю исключение: «В System.Xml.dll произошло необработанное исключение типа System.InvalidOperationException».Произошла ошибка при создании XML-документа».

Я также пытался использовать этот массив в качестве переменной-члена в структуре (где хранятся все остальные данные моего игрока), но я получаю то же исключение, когда делаю что-то таким образом, что заставляет меня полагать, что это не простая синтаксическая ошибка или что-то в этом роде.

Нужно ли мне реструктурировать свой код для сериализации через одномерный массив, или я что-то упускаю из виду?

Заранее спасибо!

Это было полезно?

Решение

Прочтите внутренние исключения:

  • Произошла ошибка, отражающая тип SomeType.Невозможно сериализовать элемент «SomeType.Data» типа «System.Int32[,,]», дополнительные сведения см. во внутреннем исключении.
  • Невозможно сериализовать объект типа System.Int32[,,].Многомерные массивы не поддерживаются.

Так что нет:многомерные массивы просто не поддерживаются.Возможно, вам придется пропустить его как одномерный массив...вы можете сделать это, имея отдельное свойство, которое выполняет перевод:

[XmlIgnore]
public int[, ,] Data { get; set; }

[XmlElement("Data"), Browsable(false)]
[EditorBrowsable(EditorBrowsableState.Never)]
public int[] DataDto
{
    get { /* flatten from Data */ }
    set { /* expand into Data */ }
} 

Другие советы

Мне потребовалось некоторое время, чтобы понять, что должно быть в команде Марка get и установить фигурные скобки для сглаживания и расширения многомерных массивов.

Вот мое решение для 2D-массивов.

В моем случае во время компиляции я знаю, что одно из измерений равно 4, поэтому мне не нужно было (каким-то образом) хранить размеры массива.

    [XmlIgnore]
    public int[,] Readings { get; set; }
    [XmlArray("Readings")]
    public int[] ReadingsDto { 
        get { return Flatten(Readings); }
        set { Readings = Expand(value, 4); }
    }

    public static T[] Flatten<T>(T[,] arr)
    {
        int rows0 = arr.GetLength(0);
        int rows1 = arr.GetLength(1);
        T[] arrFlattened = new T[rows0 * rows1];
        for (int j = 0; j < rows1; j++)
        {
            for (int i = 0; i < rows0; i++)
            {
                var test = arr[i, j];
                arrFlattened[i + j * rows0] = arr[i, j];
            }
        }
        return arrFlattened;
    }
    public static T[,] Expand<T>(T[] arr, int rows0)
    {
        int length = arr.GetLength(0);
        int rows1 = length / rows0;
        T[,] arrExpanded = new T[rows0, rows1];
        for (int j = 0; j < rows1; j++)
        {
            for (int i = 0; i < rows0; i++)
            {
                arrExpanded[i, j] = arr[i + j * rows0];
            }
        }
        return arrExpanded;
    }
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top