Passing arrays as parameters

S

Schizoid Man

Hello,

I am having some difficulty understanding the nuances of passing arrays as
parameters, and exactly how pass-by-reference is different from
pass-by-value for this particular example:

static void Main(string[] args)
{
int[] Test = { 1, 2, 3 };
Modify(Test);
Console.WriteLine(Test[0]);
Console.ReadLine();
}

static void Modify(int[] TestArray)
{
TestArray[0] = 4;
}

As far as I can tell, defining the function call as 'Modify(ref Test)' and
the method itself as 'static void Modify(ref int[] TestArray)' will make no
difference to the output of the program.

In this regard is C# similar to VB.Net, where arrays are always
pass-by-value (the trick being to make a copy of the array in the invoked
method)?

Thanks,
Schiz
 
P

Pavel Minaev

I am having some difficulty understanding the nuances of passing arrays as
parameters

There aren't really any nuances of passing arrays as parameters.
Arrays are normal .NET objects that live on the heap, and aren't value
types; therefore, when you declare a variable (including function
arguments) of array type, the variable actually holds a reference to
the array. Everything else follows from that.
and exactly how pass-by-reference is different from
pass-by-value for this particular example:

        static void Main(string[] args)
        {
            int[] Test = { 1, 2, 3 };
            Modify(Test);
            Console.WriteLine(Test[0]);
            Console.ReadLine();
        }

        static void Modify(int[] TestArray)
        {
            TestArray[0] = 4;
        }

As far as I can tell, defining the function call as 'Modify(ref Test)' and
the method itself as 'static void Modify(ref int[] TestArray)' will make no
difference to the output of the program.

Yep. Without "ref", you are passing by value an object reference to
the array to method Modify. With "ref", you are passing by reference
an object reference to the array to method Modify. Either way, you end
up passing that object reference. In either case, there is only a
single array object. Just as with any other reference types, there are
no silent copies created anywhere.
In this regard is C# similar to VB.Net, where arrays are always
pass-by-value (the trick being to make a copy of the array in the invoked
method)?

Arrays are not pass-by-value in VB.NET. If you replace your C# code
with equivalent VB.NET code (using "ByVal" where there is no "ref" in
C#, and "ByRef" where there is "ref" in C#), you will get the exact
same result.
 
F

Family Tree Mike

Schizoid Man said:
Hello,

I am having some difficulty understanding the nuances of passing arrays as
parameters, and exactly how pass-by-reference is different from
pass-by-value for this particular example:

static void Main(string[] args)
{
int[] Test = { 1, 2, 3 };
Modify(Test);
Console.WriteLine(Test[0]);
Console.ReadLine();
}

static void Modify(int[] TestArray)
{
TestArray[0] = 4;
}

As far as I can tell, defining the function call as 'Modify(ref Test)' and
the method itself as 'static void Modify(ref int[] TestArray)' will make
no difference to the output of the program.

In this regard is C# similar to VB.Net, where arrays are always
pass-by-value (the trick being to make a copy of the array in the invoked
method)?

Thanks,
Schiz


The differences come from redefining the array parameter within the
function, not the elements of the array. If you were to do something like
the following, the array after the call (in main) would look very different
from what was passed into the function.

static void Modify(ref int [] TestArray)
{
TestArray = new int [] {4, 3, 2, 1};
}
 
B

Branco

Schizoid said:
I am having some difficulty understanding the nuances of passing arrays as
parameters, and exactly how pass-by-reference is different from
pass-by-value for this particular example:

        static void Main(string[] args)
        {
            int[] Test = { 1, 2, 3 };
            Modify(Test);
            Console.WriteLine(Test[0]);
            Console.ReadLine();
        }

        static void Modify(int[] TestArray)
        {
            TestArray[0] = 4;
        }

As far as I can tell, defining the function call as 'Modify(ref Test)' and
the method itself as 'static void Modify(ref int[] TestArray)' will make no
difference to the output of the program.
<snip>

As others pointed out, th snippet you showed doesn't illustrate the
actual implications of the array being passed by value of by
reference.

An array, as it was said, is a reference type. Imagine it as a piece
of paper with a street name written in it so you can go to that
address and visit each house (the array elements). Now, suppose you
need to give this address to a friend, so he can also visit the good
folks in those houses. If you give your actual piece of paper to your
friend, it's call by ref. If, instead, you write the address down in a
separate piece of paper and pass *that* to your friend, it's call by
value. Neither way prevents your friend from visiting those houses
(i.e. access the elements of the array). But in the first case, if
your friend change the address in the paper, wipe it out or even tear
the paper appart, you'll have no way to recover the original address
back. In the second case, it won't matter what your friend did to the
piece paper you gave him, 'cause you still have the original with you
=)))))

(ducks and runs like hell)

HTH.

Regards,

Branco.
 
G

Göran Andersson

Michael said:
In this language, arrays are not value types, so they are always passed
by reference.

Actually, they are not. There is a difference between passing _a_
reference and passing _by_ reference.
 
G

Göran Andersson

Schizoid said:
Hello,

I am having some difficulty understanding the nuances of passing arrays
as parameters, and exactly how pass-by-reference is different from
pass-by-value for this particular example:

static void Main(string[] args)
{
int[] Test = { 1, 2, 3 };
Modify(Test);
Console.WriteLine(Test[0]);
Console.ReadLine();
}

static void Modify(int[] TestArray)
{
TestArray[0] = 4;
}

As far as I can tell, defining the function call as 'Modify(ref Test)'
and the method itself as 'static void Modify(ref int[] TestArray)' will
make no difference to the output of the program.

In this regard is C# similar to VB.Net, where arrays are always
pass-by-value (the trick being to make a copy of the array in the
invoked method)?

No, neither C# nor VB.NET are making copies of arrays to pass them by
value. An array in .NET is a reference type, so the default way to pass
it as a parameter is to pass the reference by value. This means that
it's the reference to the array that is copied, not the array itself.

If you pass a reference type by reference that means that you are in
fact passing a reference to the reference variable. The method gets
access to the variable holding the reference so that it can replace it
with another reference:

static void Modify(ref int[] TestArray) {
TestArray = new int[] { 2, 4, 8 };
}

If you did this without the ref keyword you would just replace the copy
of the reference, not the variable that was passed to the method.

Without the ref keyword you can still change the contents of the array.
The copy of the reference is still a reference to the original array.
 
C

Cor Ligthert[MVP]

Hi,

Goran is of course as mostly completely right, however about VB there is a
nuance. As you use in the method the ReDim command, then there is a complete
new Array created (copied), this is in fact in a way as using in all managed
program languages array.CopyTo method where is created a new array.

If you have then likewise Goran showed in his sample with a new array the
result of the copied array, then it looks as if a modified array is
returned.
The old array will then be garbaged by the GC.

http://msdn.microsoft.com/en-us/library/system.array.copyto(VS.71).aspx

Just a little nuance to Goran's nice sample

However, as you have to change the dimension of an array, then it is better
not to use an array but a list instead (like arraylist).

Cor

Göran Andersson said:
Schizoid said:
Hello,

I am having some difficulty understanding the nuances of passing arrays
as parameters, and exactly how pass-by-reference is different from
pass-by-value for this particular example:

static void Main(string[] args)
{
int[] Test = { 1, 2, 3 };
Modify(Test);
Console.WriteLine(Test[0]);
Console.ReadLine();
}

static void Modify(int[] TestArray)
{
TestArray[0] = 4;
}

As far as I can tell, defining the function call as 'Modify(ref Test)'
and the method itself as 'static void Modify(ref int[] TestArray)' will
make no difference to the output of the program.

In this regard is C# similar to VB.Net, where arrays are always
pass-by-value (the trick being to make a copy of the array in the invoked
method)?

No, neither C# nor VB.NET are making copies of arrays to pass them by
value. An array in .NET is a reference type, so the default way to pass it
as a parameter is to pass the reference by value. This means that it's the
reference to the array that is copied, not the array itself.

If you pass a reference type by reference that means that you are in fact
passing a reference to the reference variable. The method gets access to
the variable holding the reference so that it can replace it with another
reference:

static void Modify(ref int[] TestArray) {
TestArray = new int[] { 2, 4, 8 };
}

If you did this without the ref keyword you would just replace the copy of
the reference, not the variable that was passed to the method.

Without the ref keyword you can still change the contents of the array.
The copy of the reference is still a reference to the original array.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top