Is int[] a reference type or a value type?

Viewed 89137

I know an int is a value type, but what are arrays of value types? Reference types? Value types? I want to pass an array to a function to check something. Should I just pass the array, as it will just pass the reference of it, or should I pass it as ref?

10 Answers

Test to verify if it's a reference or value type:

// we create a simple array of int
var a1 = new int[]{1,2,3};
// copy the array a1 to a2
var a2 = a1;
// modify the first element of a1
a1[0]=2;
// output the first element of a1 and a2
Console.WriteLine("a1:"+a1[0]); // 2
Console.WriteLine("a2:"+a2[0]); // 2
//**************************
// all the two variable point to the same array
// it's reference type!
//**************************

You can test it online: https://dotnetfiddle.net/UWFP45

I would like to add to the other answers that though int[] is a reference type, with the introduction of stackalloc in C# you can allocate an array in stack as a value type. This may give you performance gain since placing array to stack reduces GC pressure (by the way, talking about value types in general you may often hear that value type is allocated in stack; it is not always true: https://docs.microsoft.com/en-us/archive/blogs/ericlippert/the-truth-about-value-types):

https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/operators/stackalloc

A stackalloc expression allocates a block of memory on the stack. A stack allocated memory block created during the method execution is automatically discarded when that method returns. You cannot explicitly free the memory allocated with stackalloc. A stack allocated memory block is not subject to garbage collection and doesn't have to be pinned with a fixed statement.

An example of stackalloc usage:

    Span<int> numbers = stackalloc int[10];
    for (int ctr = 0; ctr < numbers.Length; ctr++)
        numbers[ctr] = ctr + 1;
    foreach (int i in numbers)
        Console.WriteLine(i);

Using this technique don't forget about the limited stack memory. The link https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/operators/stackalloc provides the necessary information on how to use stackalloc safely considering this limitation.

Additionally, here is an answer that discusses the practical usage of stackalloc: Practical use of `stackalloc` keyword

Just a bit of an insight:

For example, int represents a single integer, int[] represents an array of integers.

To initialize the array with specific dimensions, you can use the new keyword, giving the size in the square brackets after the type name:

//create a new array of 32 ints.
int[] integers = new int[32];

All arrays are reference types and follow reference semantics. Hence, in this code, even though the individual elements are primitive value types, the integers array is a reference type. So if you later write:

int[] copy = integers;

this will simply assign the whole variable copy to refer to the same array, it won't create a new array.

C#'s array syntax is flexible, it allows you to declare arrays without initializing them so that the array can be dynamically sized later in the program. With this technique, you are basically creating a null reference and later pointing that reference at a dynamically allocated stretch of memory locations requested with a new keyword:

int[] integers;
integers = new int[32];

Thank You.

Related