Pergunta

Eu estou encontrando um problema ao tentar serializar uma matriz multi-dimensionada de inteiros via XmlSerializer para um projeto de XNA que estou trabalhando. Eu sou capaz de serializar todos os meus outros dados (booleans, cordas, até mesmo cores, etc.) sem problemas. Eu também vi muitas pessoas afirmam que XmlSerializer vai nativamente lidar com matrizes (single-dimensionado) de inteiros também. Existe uma limitação sobre arrays multi-dimensionada, ou é outra coisa acontecendo aqui?

Aqui está o código relevante:

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(); 

A exceção que recebo é "uma exceção sem tratamento do tipo 'System.InvalidOperationException' ocorreu no System.Xml.dll. Ocorreu um erro ao gerar o documento XML."

Eu também tentei usar essa matriz como uma variável de membro em um struct (onde todos os meus outros dados jogador está armazenado), mas eu recebo a mesma exceção quando fazer as coisas dessa forma, bem, o que me leva a crer que não é um erro de sintaxe simples ou qualquer coisa assim.

Eu preciso reestruturar meu código para serializar através de uma série single-dimensionado, ou há algo que eu estou com vista?

Agradecemos antecipadamente!

Foi útil?

Solução

Leia as internas-exceções:

  • Houve um erro ao refletir tipo 'SomeType'. Não é possível membro serialize 'SomeType.Data' do tipo 'System.Int32 [,,]', ver exceção interna para obter mais detalhes.
  • Não é possível objeto serialize do tipo System.Int32 [,,]. arrays multidimensionais não são suportadas.

Portanto, não: arrays multi-dimensionais simplesmente não são suportados. Você pode ter que calçar-lo através de como um vetor de dimensão única ... você pode fazer isso por ter uma propriedade separada que faz a tradução:

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

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

Outras dicas

Levei um tempo para descobrir o que deve ir para get de Marc e chaves definidos para achatar e expandir matrizes multi-dimensionais.

Aqui está a minha solução para matrizes 2D.

No meu caso, eu sei que em tempo de compilação que uma das dimensões é 4 então eu não tenho que loja (de alguma forma) as dimensões da matriz.

    [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;
    }
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top