pass the table to work with or without reference keyword


I'm trying to do something with array passed to the function in .NET and I'm a little confused. Array is reference type so changes made to array passed to the function are visible outside the function. Example

static void Main(string[] args)
    byte[] arr = new byte[] { 1,2, 3, 4, 5 };
    Console.WriteLine(string.Join("", arr));        //console output: 12345
    Console.WriteLine(string.Join("", arr));        //console output: 52341
static void doSomething(byte[] array)
    byte tmp = array[0];
    array[0] = array[array.Length - 1];
    array[array.Length - 1] = tmp;

so it works exactly the same as with "ref" keyword used (same console output)

doSomething(ref arr);  for static void doSomething(ref byte[] array)

However if I add following line to my function:

array = (new byte[] { 1 }).Concat(array).ToArray(); //size of array is changed

the results are different:

52341// "ref" keyword is not used


152341 "ref" keyword is used

Could someone explain me why results are different ?

value type variables are variables containing a value. arr is object variable that points to an instance of byte[] in memory. When you pass it by value to the method doSomething you are passing a pointer to the instance of byte[] in memory. This way both arr and array both point to the same instance of byte[] in memory. If DoSomething changes the instance of byte[] that both arr and array are pointing too it does not actually change the variable arr, since it is still pointing to the same place in memory. However, since arr is still pointing to the same place in memory and the instance in that place has been updated, then arr can "see" the changes.

When you call Concat it generates a new instance of byte[] somewhere else in memory, and it poitns the variable array to the new instance in memory. The old instance of byte[] still exists, and arr is still pointing to it.

When you pass the variable arr by ref, then any change to where array is pointing will also affect where arr is pointing. When it is not passed by ref DoSomething can only change the instance of byte[] in memory that arr points to, but it cannot change where arr is pointing.

That is why there is a difference between passing an object by reference and passing an object by value.