My Google-Jitsu is failing me. Question is in the title... What is the difference between T[,]
and T[*,*]
?
I am looking for a 2, 2-1/2 part answer:
Layman's (or super architect's) plain english explaination with example code.
Link to the formal documentation of this distinction.
Bonus: Point to subsection and page number in the C# 4 spec that defines this. (It is not in sect 12 "Arrays")
I got this notion here.
T[]
means a zero-based array of T (array[0] is its first element)
T[*]
means a non-zero-based array of T (array[0] is not its first element and can even be out of bounds)
The link from your question explains that there is no array of type T[*,*]
, because all multi-dimensional arrays of T[,]
are treated as arrays with unknown lower-bound.
Code snippet below shows how you can create an instance of T[*]
. Note that you can not cast it to T[]
, because they are different types. a[0]
here will throw an OutOfRangeException, the index of the first element in this array is 1 (ah, good old Pascal days...).
Array a = Array.CreateInstance(typeof(String), new Int32[] { 1 }, new Int32[] { 1 });
Console.WriteLine(a.GetType()); // System.String[*]
More example code
Bonus. The C# language spec says, "The indices of the elements of an array range from 0 to Length - 1". Obviously, the language does not provide built-in support for non-zero-based arrays, it's just a custom data structure that you can create; although specific in a sense that the compiler happens to have a special symbol for its type and VS uses standard array visualizer for them when you're debugging.
See also:
How to create a 1-Dimensional Array in C# with index starting at 1
C#: Nonzero-based arrays are not CLS-compliant
Well, it does... if you use var
.
First, you would need to compile this into an assembly using ILAsm.exe
(I know, this isn't C#... yet):
.assembly extern mscorlib
{
.publickeytoken = (B7 7A 5C 56 19 34 E0 89 )
.ver 2:0:0:0
}
.assembly ArrayHelper { }
.module ArrayHelper.dll
.subsystem 0x0003
.class public ArrayHelper
{
.method public hidebysig static !!T[...]
CastTo1D<T>(class [mscorlib]System.Array 'array') cil managed
{
ldarg.0
castclass !!T[...]
ret
}
.method public hidebysig static !!T[...] Create1D<T>(int32 len) cil managed
{
ldarg.0
newobj instance void !!T[...]::.ctor(int32)
ret
}
.method public hidebysig static !!T[...]
Create1D<T>(int32 lowerBound, int32 length) cil managed
{
ldarg.0
ldarg.1
newobj instance void !!T[...]::.ctor(int32, int32)
ret
}
}
Then you can do something like:
var my1DArray = ArrayHelper.Create<int>(1, 5);
to create a 1-D array of length 5 with lower bound 1.
Heck, even Visual Studio supports this!
Hope you have fun with it.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With