Well, this is kinda of a late answer, but ...
In order to initialize a 2D array of strings, you can do this (recommended, easier): array<System::String^, 2>^ example = gcnew array<System::String^, 2>(3, 5);
And that's all. "example" is a 2D array of strings, and it is not actually an array of arrays, but a rectangular array. Let's analyze this line of code a little bit. array<System::String^, 2>^ example - that 2 represents the dimension of our array, which is .. 2. gcnew array<System::String^, 2>(3, 5); - again, when we initialize the array, we must specify the size. 3 represents the number of rows in the array, and 5, number of columns. Using it is simple. Some example: example[0, 1] = "Example01" - pushes "Example01" at row 0 and column 1.
Earlier in the topic I told you that the above initialization method does not create an array of arrays, but a rectangular, managed array. This is basically a new, improved syntax, that took over the old initialization method, which created an array of arrays. As you can see, even the access to 2D array elements was changed. Now you have 2dArrayName[index_row, index_col] instead of 2dArrayName[index_row][index_col]. I'm gonna show you how to create an array of arrays too:
// Declaration: example is a jagged array, that can contain up to three arrays (3 rows).
array<array<System::String^> ^>^ example = gcnew array<array<System::String ^> ^>(3);
// Initialize each row. example[i] is nothing more than a 1D array, that can hold 5 elements.
// Therefore, we will have 5 columns.
for (int i = 0; i < 3; i++)
example[i] = gcnew array<System::String ^>(5);
example = "Example01";
// etc .. etc..
That is ugly. More complicated, as you have to initialize the array, row-by-row. In the above example, "example" is an array of arrays, containing 3 rows and 5 columns.