12

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:

  1. Layman's (or super architect's) plain english explaination with example code.

  2. 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.

Community
  • 1
  • 1
dFlat
  • 819
  • 7
  • 19
  • 1
    You typically get these kind of objects from COM interop. A SAFEARRAY with a non-zero lower bound, usually it is 1. Use Array.GetValue() and GetLower/UpperBound() to convert it. – Hans Passant Feb 26 '12 at 21:52
  • @Hans, Yep got them from the Excel PIA and hit that out of bounds issue. See here: http://stackoverflow.com/questions/9357092/fastest-way-to-convert-t-to-t – dFlat Feb 27 '12 at 16:18

2 Answers2

15

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

Community
  • 1
  • 1
Massimiliano
  • 16,770
  • 10
  • 69
  • 112
3

Actually...

C# does support 1-dimensional arrays... sort of.

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!

Visual Studio Screenshot

Hope you have fun with it.

Community
  • 1
  • 1
user541686
  • 205,094
  • 128
  • 528
  • 886
  • Interesting. The picture is not loading for me... Can you fix it? – Massimiliano Feb 20 '12 at 17:26
  • @Yacoder: That's weird... it's fine for me. Try clicking [the link](http://i.stack.imgur.com/0rKOO.png) instead? – user541686 Feb 20 '12 at 19:34
  • I see, it works now. Yeah, IDE and compiler seems to be aware of that case, though the C# spec only considers array types that are zero-based. There's no syntax to write smth like string[*] in C#. – Massimiliano Feb 21 '12 at 01:47