Ben Voigt said:
No, it's not. It's composition of two features: an array is an object,
and having arrays of objects.
Are you telling me that "jagged arrays" are not a .NET language concept
based on a well defined type in the type system and the CLR (CLI)?
The element type and shape of an array—including whether it is *jagged* or
*rectangular*, and the number of dimensions it has—are part of its type.
That why I keep saying that the declaration int[][] declares a distinct well
know array type!
Consider following snippets:
[1] An array of objects having an arrays of objects having an arrays of...
object[] oa = new object[2];
object[] oaa = new object[4];
oa[0] = oaa; // oa is an array of objects of array of objects
// Obviously the following is not possible, oa is not a jagged array
// oa[0][0] = new byte[4] {0, 2, 4, 6}; // NOT possible
// Following is OK.
oaa[0] = new byte[4] {0, 2, 4, 6};
Here 'oa' Defines an System.Object[] with Rank = 1, holding 2 elements of
element type CLASS (ELEMENT_TYPE_CLASS to be precise),
element oa[0] holds a System.Object[] with Rank = 1, holding 4 elements of
element type is CLASS (ELEMENT_TYPE_CLASS),
element oaa[0] Defines an System.Byte[] with Rank = 1, holding 4 elements of
element type Byte(ELEMENT_TYPE_BYTE)
[2]
string[] sa = new string[2];
sa[0] = "somestring";
Here 'sa' defines an System.String[] with Rank = 1, holding 4 elements of
element type CLASS (ELEMENT_TYPE_CLASS)
[3]
byte[,] nonJagged = new byte[4,5];
nonJagged[0,0] = 100;
nonJagged[1,1] = 200;
Here 'sa' defines an System.Byte[] with Rank = 2, holding 20 elements of
element type Byte(ELEMENT_TYPE_BYTE)
Notice Rank=2, This is a multi-dimentional rectangular array.
[4]
byte[][][] jagged = new byte[4][][];
jagged[0] = new byte[1][] {
new byte[4] {1, 2, 3, 4}};
jagged[1] ....
Here 'jagged' defines an System.Byte[][][] with Rank = 1, holding 4 elements
of element type SZARRAY(ELEMENT_TYPE_SZARRAY),
jagged[0] defines an System.Byte[][] with Rank = 1, holding 1 elements of
element type SZARRAY(ELEMENT_TYPE_SZARRAY)
and the element jagged[0] holds a reference to a
System.Byte[] with Rank = 1, holding 4 elements of element type
Byte(ELEMENT_TYPE_BYTE)
Take a look at the run-time type [4] above and notice the Element type
SZARRAY for the jagged array "jagged", SZARRAY is s type that indicates a
vector, an array with 0 bound and *no* upper bound. This is the way by which
the CLR makes a distiction between a "jagged array" and other array types,
the CLR treats them differently from the other types.
If you look at the snip in [3], you'll see the Rank being > 2, which is the
way by which the CLR distincts multi-dimentional arrays from other array
types. You can't have an array with Rank > 1 and Element type SZARRAY.
[2 ]show a regular array, that is Rank = 1 and Element type = CLASS.
[1] and [2] both define an array of element type CLASS, that means that they
are of the same Class (Execution Class) as such their instances point to the
same Method table, but the Class of [4] , is different from [1] (an array of
arrays of ...), so is it's Method table. The same is tru for [3] which is
treated differently as the others, this is reflected by it's Execution Class
which differs from the others.
See what I mean now?
Then what is the syntax for a managed jagged array in C++/CLI? Oh, it's
something like:
cli::array<cli::array<int>^>^
Not sure what you mean by this...
Anyway, make it:
array<array<Int32>^>^ local = gcnew array<array< Int32 >^>(2);
or:
array said:
to show that *only* one dimension (the first) can be specified, here we
declare "jagged arrays", using well defined language declaration syntax,
every
language has his own syntax, but finaly it boils down to the same thing.
based on a CLS compliant type from the CTS, and this is not true in C++.
in C#
int[3][] ja;
ja is a jagged array.
which is not possible in C++
int ja[3][];
The omitted dimension syntax is accepted in C and C++, but means something
entirely different. And I think it is the first dimension omitted, not
the last.
That's exactly the point, the you can ommit the first dimentions, never the
last, that means that you can only define a rectangular array using that
array syntax in C++. A jagged array *may* not specify the last dimension
will not compile.....
and
int ja[3][5];
is a two dimentional rectangular array, an array of arrays, but it's not
a jagged array!
No, it's not an array of arrays at all.
Right, my bad, no array of arrays, a two dimentional rectangular array, but
no jagged array.
It is a single array, and can be
treated interchangeable as a 3x5 array, a 5x3 array, or a 15 element
one-dimensional array.
int ja1[5], ja2[5], ja3[5];
int* ja[] = { ja1, ja2, ja3 };
is an array of arrays.
Right, still no jagged array.
Or, if you want to nitpick that this is an array of pointers,
int (&ja[])[5] = { ja1, ja2, ja3 };
Which is an array of arrays, but cannot be jagged.
Right, no jagged array.
P/invoke can't handle arrays of ref class types, and an array is a ref
class, so no, p/invoke can't do an array of arrays (or array of lists, or
list of arrays, or array of strings, or ...). Jagged arrays aren't a
special case in any sense.
Did I ever said otherwise?
It was me who said you can't pass a "jagged arrays" to C++, the PInvoke
marshaler has no knowlege on how to represent this type as an "unmanaged"
type (without creating a "new" kind of type of course).
That's why I asked the OP "why trying to pass a jagged array to C++". It
was me (and Nicholas) who said that the OP could pass a reference to a
single dimensional array or he should apply some custom marshaling, right?
Willy.