From a data-storage standpoint, if one will frequently be accessing all the parts of an items more often than one would be accessing some particular part from a group of consecutive items, caching behavior will be better with an array of structs.
A more interesting question is how to expose the data. If you expose the struct as an indexer, anyone wanting to change a field of the struct will have to read out the struct, change the field in their temporary copy, and write it back. You could expose methods to read/write individual properties, but "foo.setBar(100, 23)" seems rather less natural than "foo(100).Bar=23". Too allow the latter syntax, I'd suggest perhaps having the indexer return a struct with two private fields, "root" and "index", and properties for each field of the struct so that e.g. the setter for the Bar property of the indexer would perform root.setBar(index, value). The indexer should also have an "asWhateverStructType" property to get/set the struct as a whole.