4

I'm encountering a problem while trying to serialize a multi-dimensioned array of integers via XmlSerializer for an XNA project I'm working on. I'm able to serialize all of my other data (booleans, strings, even Colors, etc) without a hitch. I've also seen plenty of people claim that XmlSerializer will natively handle (single-dimensioned) arrays of integers as well. Is there a limitation regarding multi-dimensioned arrays, or is something else going on here?

Here's the relevant code:

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

The exception I receive is

An unhandled exception of type 'System.InvalidOperationException' occurred in System.Xml.dll. There was an error generating the XML document.

I've also tried using this array as a member variable in a struct (where all of my other player data is stored) but I get the same exception when doing things that way, as well, which leads me to believe that it's not a simple syntax error or anything like that.

Do I need to restructure my code to serialize via a single-dimensioned array, or is there something I'm overlooking?

Thanks in advance!

2 Answers 2

12

Read the inner-exceptions:

  • There was an error reflecting type 'SomeType'. Cannot serialize member 'SomeType.Data' of type 'System.Int32[,,]', see inner exception for more details.
  • Cannot serialize object of type System.Int32[,,]. Multidimensional arrays are not supported.

So no: multi-dimensional arrays simply aren't supported. You may have to shim it through as a single-dimension array... you can do this by having a separate property that does the translation:

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

[XmlElement("Data"), Browsable(false)]
[EditorBrowsable(EditorBrowsableState.Never)]
public int[] DataDto
{
    get { /* flatten from Data */ }
    set { /* expand into Data */ }
} 
Sign up to request clarification or add additional context in comments.

1 Comment

That's kind of the answer I was expecting. Thank you!
0

It took me a while to figure out what should go into Marc's get and set braces to flatten and expand multi-dimensional arrays.

Here is my solution for 2D arrays.

In my case, I know at compile time that one of the dimensions is 4 so I did not have to store (somehow) the array dimensions.

    [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;
    }

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.