Are Arrays or Lists Passed by Default by Reference in C#

C# array parameter reference

The array is passed by a reference, you can see this by doing A[0] = 7; from inside another method.

That reference (held by the outer variable A), however is passed by value to the function. The reference is copied and a new variable is created and passed to the function. The variable outside the function is not affected by the reassignment to the parameter variable A inside the function.

To update the original variable you need to use the ref keyword so the parameter inside the function represents the same object as outside of the function.

int[] A = new int[] {1, 2, 3};
fun2(A);
// A at this point says 7, 2, 3.
fun(ref A);
// A at this point says 4, 5, 6.

void fun2(int[] a)
{
a[0] = 7;
}

void fun(ref int[] a)
{
int[] B = new int[] {4, 5, 6};
a = B;
}

Arrays passed by reference or by value

The reference to the array is passed by value. This is the source of the confusion :-)

C# Passing array by reference

All references/values in paramaters of function other than with out and ref modifiers can be considered as solely local variables (though, you still can change values inside referenced objects).

In C# we do such extension methods like this, so it looks like it is stateless extension method:

public static Array Reverse(this Array array, int dimension, int start, int end)
{
object[] jag = array.ToJaggedArray();

if (!jag.ReverseAux(0, dimension, start, end))
throw new ArgumentOutOfRangeException("dimension", dimension, "Dimension must be nonnegative and less than array dimensions number.");

return jag;
}

var output = input.Reverse(...);

List passed by ref - help me explain this behaviour

You are passing a reference to the list, but your aren't passing the list variable by reference - so when you call ChangeList the value of the variable (i.e. the reference - think "pointer") is copied - and changes to the value of the parameter inside ChangeList aren't seen by TestMethod.

try:

private void ChangeList(ref List<int> myList) {...}
...
ChangeList(ref myList);

This then passes a reference to the local-variable myRef (as declared in TestMethod); now, if you reassign the parameter inside ChangeList you are also reassigning the variable inside TestMethod.

Passing array by value in c#

As far is i understand, the default type or argument passing in c# is by value.

Unfortunately it is a bit more complicated and also has some execptions:

Reference types like Decomposition you hand in by making a copy of the reference. Unfortunately that means both still reference the same instance in memory. So despite a copy operation, it is call-by-Reference.

With value types like Int or double and their aliases, usually a copy is made. I do not know of any case where it does not, but I was wrong on those things before. So they are call by value.

Finally String and a few other reference types are inmutable by design. That has the advantage that they behave kinda like value types in this area. You hand in a Reference, but the instance itself can not be changed. The code can only create a new instance in memory with a different value. So despite handing over literal references, it kinda works like call by value.

Your specific case

Arrays are very explicitly Reference types. Handing them into a function without side effects, requires proper cloning. If it is a array of reference types, the cloning must be deep.

In your case you have arrays of value types. If you want to avoid call-by-reference side effects, you those arrays must be cloned. However as double is a value type, this cloning can be shallow. No need for a deep clone.

Unlike Java there is not a dedicated Clone() Method. And I am not sure why exactly. However you can often use one Collection to initialize another through the constructor. Or they even have a function like Array.Copy(), as TheBatman pointed out.

Values of Array are changed even though not passed a reference C#

You only need to pass by ref if you want to assign the triangles variable to some other array and have that assignment propagate to the caller.

That's what ref does, it allows assignment to propagate. Because Array<int> is a reference type, you are already passing a reference around (by value) and so modifications to the object's state are automatically "picked up" by the caller, since they are both pointing to the same object.

How to add an array to a list by value not by reference?

Make a copy:

testList.Add(testArray.ToArray());


Related Topics



Leave a reply



Submit