Closed
Description
I know there is already a similar issue(#713), but that issue seems to focus on params
array or stackalloc
array. In this issue, I want to discuss more about it.
- Value type array should be a new struct type, different from the current array class, although they might share some syntax, for example
[]
. - Since it is struct, value type array is copied by value, not by ref.
- Value type array can be used anywhere, just like normal struct, not only used as local variables, but also used as class/struct fields.
- Value type array can be used as
params
array. - Value type array is mainly used for performance purpose. If small temp arrays could be value type, then heap allocation would be avoided, thus reducing GC pressure. If small arrays are class/struct fields and can not be null, then embedding them in the class/struct itself would reduce heap allocations too.
Here are some examples:
/* 1. used as local variables: allocated on stack, the length need not to be determined at compile time.
the value type array itself is value type, but its element could be either ref type or value type. */
static void foo(int n)
{
object[n] valueTypeArray; // I use Type[n] to represent value type array here
int i;
for(i=0;i<n;i++)
{
valueTypeArray[i]=new object();
}
valueTypeArray[n]=new object(); //Throw IndexOutOfRangeException here! Value type array should also have boundary check (compile-time check), so it is safe.
......
}
/* 2. used as params array: allocated on stack. The length need not to be determined at compile time, but need to have a variabe name to be used in the function. The length type is always int. */
static void foo(bool t, params int[n] a) //value type params, different from "params int[] a", which is ref type.
{
/* Here "n" is an int variable, represent the length of "a", should be treated as another parameter of "foo".
Value type array might not have Length property (depending on its implementation), so we need "n".
Of course, using other name instead of "n" is OK too. */
int[n] b=a; //copy by value, length must match.
int[] c=a; //compile error! Type mismatches, c is ref type, but a is value type.
......
}
/* 3. used as normal function parameters (not params array): allocated on stack, and copied by value */
static void foo(bool[2] a, int[m] b)
{
/* the length of a is determined at compile time, while the length of b is determined at run time (depending on the parameter provided by the caller). */
......
}
/* 4. used as class/struct fields: allocated on stack or heap, determined by its container. The length must be determined at compile time. */
class A
{
long a;
int[10] b;
object[20] c;
}
struct B
{
object[2] a;
int b;
byte[100] c;
}
/* 5. Value type array could also be used by ref: just like ref struct */
static void foo(ref int[m] a) //a is passed by ref
{
if(m>1)
{
a[0]++;
a[m-1]--;
}
}
/* If value type array support initialization and range syntax, we could do more interesting things */
static void main(....)
{
int[100] a={1,2,5,10}; //initialization: a[0]=1,a[1]=2,a[2]=5,a[3]=10, all other elements are zero.
foo(ref a[3..10]); //after foo, a[3]=11,a[10]=-1
}
Metadata
Metadata
Assignees
Labels
No labels