Pass by reference vs Pass by Value (is 'data aliasing' a problem in C#?)

  • Thread starter Francois Appert
  • Start date
F

Francois Appert

This post was originally in the C# Corner site, but their server is
down. I'd like to see if this group can answer.

I program in C++ and am learning C#.

The issue is: why should anybody bother in C# with pass-by-reference
using the "ref" keyword or "out" for objects in a method parameter
list, when, after all, it appears in C# that for all intents and
purposes a reference is always being passed, rather than the real
object (with, it seems, the exception of data primitives like int,
which are not 'boxed').

The reply from C# Corner by a poster, call him Brian, as to why 'ref'
is needed was to write out a simple demonstration program (see below),
which indeed seems to refute the above, and point out that unless you
use keyword "ref" in your method parameter, then you cannot change an
object passed to a method while inside the method.

However--and this is the point of this post--it seems I've found a
workaround so that even with the use of "pass by value", you can
indeed change an object passed, inside the called method (when you
exit the method), if you use the assignment operator "=" and return a
new object (see below, at the comments ////). I don't think what's
known in C++ as 'aliasing' is an issue here when doing this
"workaround" (correct me if I'm wrong). That's really the point of
this post--can you have 'data aliasing' when you pass-by-value in C#,
since we're always dealing with references, and in theory it's
supposed to be safe? Is there any other potential problem to my
'workaround' below, as a coding style?

Any comments? Why do we need 'ref' after all?

Fran

// start of console C# program

using System;

using System.Collections.Generic;

using System.Text;

namespace ConsoleApplication1

{


class Program

{

static void Main(string[] args)

{

MyObject A = new MyObject();

A.AMember = 1;

Methods.PassObjectByValue1(A);

Console.WriteLine(A.AMember);// 2 // That is, output is '2'

MyObject B = new MyObject();

B.AMember = 1;

Methods.PassObjectByValue2(B);

Console.WriteLine(B.AMember);// 1 //That is, output is '1' (not '2')

// while the above line 'proves' Brian's point, the 'change' below
(workaround) rebuts it?!

//////////////////////////////////////////////////

//change made here! "workaround"

B = Methods.PassObjectByValueTWO(B); //note use of "=" assignment
operator

//change object via pass by value? Yes! output is indeed
'2' not '1'

Console.WriteLine("B.AMember should equal TWO!: {0}",B.AMember);

// end of change made


/////////////////////////////////////////////////

/* rest of this listing shows how 'ref' superior when you want to
'change' the object--this is disputed above */

MyObject C = new MyObject();

C.AMember = 1;

Methods.PassObjectByRef1(ref C);

Console.WriteLine(C.AMember);// 2

MyObject D = new MyObject();

D.AMember = 1;

Methods.PassObjectByRef2(ref D);

Console.WriteLine(D.AMember);// 2

Console.ReadKey();

}

}

class MyObject

{

public int AMember;

}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// start of seperate source file now; // start of "Methods" class used
above

class Methods

{

public static void PassObjectByValue1(MyObject X)

{

// I can change the values of member of an

// parameter of a reference type passed by value

X.AMember = 2;

}

public static void PassObjectByValue2(MyObject X)

{

//I can't change the object

// THIS IS THE PART 'disputed' AND THE SUBJECT OF THE 'workaround'
above

X = new MyObject();

X.AMember = 2;
// the point by Brian being, that AMember = 2 here but still = 1
outside here

}

/////////////////////////////////////////// YES YOU CAN! ('workaround'
to above)
// add this function to the class Methods--

public static MyObject PassObjectByValueTWO (MyObject X)
{
//you can change the object!

MyObject WhyNot = new MyObject();
WhyNot.AMember = X.AMember + 1; //2

//now AMember is 2 here, and soon to be '2' outside too

return WhyNot; //returns object of type MyObject (this is the
key)
}

////////////////////////////////////////// END OF YES YOU CAN!

public static void PassObjectByRef1(ref MyObject X)

{

// I can change the values of member of an

// parameter of a reference type passed by ref

X.AMember = 2;

}

public static void PassObjectByRef2(ref MyObject X)

{

//I can also change the object that is referenced

X = new MyObject();

X.AMember = 2;

}

}

}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 
N

Nicholas Paldino [.NET/C# MVP]

Francois,

See inline:
This post was originally in the C# Corner site, but their server is
down. I'd like to see if this group can answer.

I program in C++ and am learning C#.

The issue is: why should anybody bother in C# with pass-by-reference
using the "ref" keyword or "out" for objects in a method parameter
list, when, after all, it appears in C# that for all intents and
purposes a reference is always being passed, rather than the real
object (with, it seems, the exception of data primitives like int,
which are not 'boxed').

You would pass a reference type with a ref keyword or out keyword when
you need to modify what reference itself, not what the reference points to.
So if you have a StringBuilder parameter, and you want to point it to a
completely different StringBuilder instance, you have to use ref or out in
order to be able to change the reference.

When you pass a reference type to a method, you can always modify what
the reference points to. The ref/out (or lack of it) is in reference (no
pun intended) to the reference itself, not what it points to.
The reply from C# Corner by a poster, call him Brian, as to why 'ref'
is needed was to write out a simple demonstration program (see below),
which indeed seems to refute the above, and point out that unless you
use keyword "ref" in your method parameter, then you cannot change an
object passed to a method while inside the method.

Brian's example is wrong. While a parameter that is not passed by ref
can be modified in the method it is declared it, that change will not be
seen outside of the method. Brian is assigning a NEW instance of MyObject
to X in PassObjectByValue2 and then changing AMember to 2. This doesn't
change what was originally passed to PassObjectByValue2, because that is not
the object that the property was changed on.
However--and this is the point of this post--it seems I've found a
workaround so that even with the use of "pass by value", you can
indeed change an object passed, inside the called method (when you
exit the method), if you use the assignment operator "=" and return a
new object (see below, at the comments ////). I don't think what's
known in C++ as 'aliasing' is an issue here when doing this
"workaround" (correct me if I'm wrong). That's really the point of
this post--can you have 'data aliasing' when you pass-by-value in C#,
since we're always dealing with references, and in theory it's
supposed to be safe? Is there any other potential problem to my
'workaround' below, as a coding style?

I don't see why you need a workaround here. Basically what it comes
down to is this. You will always be able to change members of a reference
type, whether or not it is passed by ref/out, or neither. If you want to
change what the reference actually points to, and have it be visibile
outside of the method, then you need ref/out.


--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)
Any comments? Why do we need 'ref' after all?

Fran

// start of console C# program

using System;

using System.Collections.Generic;

using System.Text;

namespace ConsoleApplication1

{


class Program

{

static void Main(string[] args)

{

MyObject A = new MyObject();

A.AMember = 1;

Methods.PassObjectByValue1(A);

Console.WriteLine(A.AMember);// 2 // That is, output is '2'

MyObject B = new MyObject();

B.AMember = 1;

Methods.PassObjectByValue2(B);

Console.WriteLine(B.AMember);// 1 //That is, output is '1' (not '2')

// while the above line 'proves' Brian's point, the 'change' below
(workaround) rebuts it?!

//////////////////////////////////////////////////

//change made here! "workaround"

B = Methods.PassObjectByValueTWO(B); //note use of "=" assignment
operator

//change object via pass by value? Yes! output is indeed
'2' not '1'

Console.WriteLine("B.AMember should equal TWO!: {0}",B.AMember);

// end of change made


/////////////////////////////////////////////////

/* rest of this listing shows how 'ref' superior when you want to
'change' the object--this is disputed above */

MyObject C = new MyObject();

C.AMember = 1;

Methods.PassObjectByRef1(ref C);

Console.WriteLine(C.AMember);// 2

MyObject D = new MyObject();

D.AMember = 1;

Methods.PassObjectByRef2(ref D);

Console.WriteLine(D.AMember);// 2

Console.ReadKey();

}

}

class MyObject

{

public int AMember;

}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// start of seperate source file now; // start of "Methods" class used
above

class Methods

{

public static void PassObjectByValue1(MyObject X)

{

// I can change the values of member of an

// parameter of a reference type passed by value

X.AMember = 2;

}

public static void PassObjectByValue2(MyObject X)

{

//I can't change the object

// THIS IS THE PART 'disputed' AND THE SUBJECT OF THE 'workaround'
above

X = new MyObject();

X.AMember = 2;
// the point by Brian being, that AMember = 2 here but still = 1
outside here

}

/////////////////////////////////////////// YES YOU CAN! ('workaround'
to above)
// add this function to the class Methods--

public static MyObject PassObjectByValueTWO (MyObject X)
{
//you can change the object!

MyObject WhyNot = new MyObject();
WhyNot.AMember = X.AMember + 1; //2

//now AMember is 2 here, and soon to be '2' outside too

return WhyNot; //returns object of type MyObject (this is the
key)
}

////////////////////////////////////////// END OF YES YOU CAN!

public static void PassObjectByRef1(ref MyObject X)

{

// I can change the values of member of an

// parameter of a reference type passed by ref

X.AMember = 2;

}

public static void PassObjectByRef2(ref MyObject X)

{

//I can also change the object that is referenced

X = new MyObject();

X.AMember = 2;

}

}

}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 
J

Jon Skeet [C# MVP]

Francois Appert said:
This post was originally in the C# Corner site, but their server is
down. I'd like to see if this group can answer.

I program in C++ and am learning C#.

The issue is: why should anybody bother in C# with pass-by-reference
using the "ref" keyword or "out" for objects in a method parameter
list, when, after all, it appears in C# that for all intents and
purposes a reference is always being passed, rather than the real
object (with, it seems, the exception of data primitives like int,
which are not 'boxed').

Because passing a reference by value isn't the same as passing a
parameter by reference.

See http://pobox.com/~skeet/csharp/parameters.html
 
F

Francois Appert

You would pass a reference type with a ref keyword or out keyword when
you need to modify what reference itself, not what the reference points to.
So if you have a StringBuilder parameter, and you want to point it to a
completely different StringBuilder instance, you have to use ref or out in
order to be able to change the reference.

I see what you mean. Microsoft has a great example (see Examples 4
and 5) on this point:
http://msdn.microsoft.com/library/d...s/csref/html/vclrfPassingMethodParameters.asp
I reproduce below for future reference.

However, I think that, using new(), you can actually do anything that
keyword ref is able to do, using passing-ref-by-value, rather than
using keyword 'ref' and passing-ref-by-reference, if you put a little
thought behind it. Agreed? (This is complete almost off-topic, since
I acknowledge your point). For example, if you change the reference
outside the method, then of course you can do whatever using keyword
'ref' and passing-by-reference would do inside the method. But that's
offtopic, since it's like saying you don't need to use a method to
achieve the same thing as using the method, which of course is almost
always true.
When you pass a reference type to a method, you can always modify what
the reference points to. The ref/out (or lack of it) is in reference (no
pun intended) to the reference itself, not what it points to.

Yes. But this is usually rare, hence no need to "pass-a-reference-by-
reference" (usually), just "pass-a-reference-by-value", since what the
reference points to is much more important (usually) than the
reference itself. That's why C# code seems to always omit the 'ref'
keyword--usually it's not important.
Brian's example is wrong. While a parameter that is not passed by ref
can be modified in the method it is declared it, that change will not be
seen outside of the method. Brian is assigning a NEW instance of MyObject
to X in PassObjectByValue2 and then changing AMember to 2. This doesn't
change what was originally passed to PassObjectByValue2, because that is not
the object that the property was changed on.

Yes, though Brian's example was not so bad. Examples 4 and 5 below
from Microsoft make the point that I believe is being made here.
I don't see why you need a workaround here. Basically what it comes
down to is this. You will always be able to change members of a reference
type, whether or not it is passed by ref/out, or neither. If you want to
change what the reference actually points to, and have it be visibile
outside of the method, then you need ref/out.

Yes, that's right.

Fran

--
Thank you. I think I understand this topic now, based on the
Microsoft example below, part of which I reproduce below (the best
parts). I now understand what you mean by saying 'passing Reference
types by reference is rarely done' (or needs to be done), since, if
you look at Example 5 below (and compare it to Example 4), you'll see
that if you pass (a reference) by reference rather than (pass a
reference) by value, and you change the reference, you can easily
"orphan" your original data structure "pointed to" by the (now
changed) reference. I suppose the C# garbage collector will clean up
the "orphaned" data, and it won't be a memory leak (please confirm
this if you care too), but it seems that indeed doing something like
Example 5 below is "rare" or "rarely needs to be done" in an
'ordinary' program (please confirm). Fran


http://msdn.microsoft.com/library/d...s/csref/html/vclrfPassingMethodParameters.asp


Example 4: Passing Reference Types by Value


The following example demonstrates passing a reference-type parameter,
myArray, by value, to a method, Change. Because the parameter is a
reference to myArray, it is possible to change the values of the array
elements. However, the attempt to reassign the parameter to a
different memory location only works inside the method and does not
affect the original variable, myArray.

// PassingParams4.cs

// Passing an array to a method without the ref keyword.

// Compare the results to those of Example 5.

using System;

class PassingRefByVal

{

static void Change(int[] arr)

{

arr[0]=888; // This change affects the original element.

arr = new int[5] {-3, -1, -2, -3, -4}; // This change is
local.

Console.WriteLine("Inside the method, the first element is:
{0}", arr[0]);

}



public static void Main()

{

int[] myArray = {1,4,5};

Console.WriteLine("Inside Main, before calling the method, the
first element is: {0}", myArray [0]);

Change(myArray);

Console.WriteLine("Inside Main, after calling the method, the
first element is: {0}", myArray [0]);

}

}

Output

Inside Main, before calling the method, the first element is: 1

Inside the method, the first element is: -3

Inside Main, after calling the method, the first element is: 888

Code Discussion


In the preceding example, the array, myArray, which is a reference
type, is passed to the method without the ref parameter. In such a
case, a copy of the reference, which points to myArray, is passed to
the method. The output shows that it is possible for the method to
change the contents of an array element (from 1 to 888). However,
allocating a new portion of memory by using the new operator inside
the Change method makes the variable arr reference a new array. Thus,
any changes after that will not affect the original array, myArray,
which is created inside Main. In fact, two arrays are created in this
example, one inside Main and one inside the Change method.


Example 5: Passing Reference Types by Reference


This example is the same as Example 4, except for using the ref
keyword in the method header and call. Any changes that take place in
the method will affect the original variables in the calling program.

// PassingParams5.cs

// Passing an array to a method with the ref keyword.

// Compare the results to those of Example 4.

using System;

class PassingRefByRef

{

static void Change(ref int[] arr)

{

// Both of the following changes will affect the original
variables:

arr[0]=888;

arr = new int[5] {-3, -1, -2, -3, -4};

Console.WriteLine("Inside the method, the first element is:
{0}", arr[0]);

}



public static void Main()

{

int[] myArray = {1,4,5};

Console.WriteLine("Inside Main, before calling the method, the
first element is: {0}", myArray [0]);

Change(ref myArray);

Console.WriteLine("Inside Main, after calling the method, the
first element is: {0}", myArray [0]);

}

}

Output

Inside Main, before calling the method, the first element is: 1

Inside the method, the first element is: -3

Inside Main, after calling the method, the first element is: -3

Code Discussion

All of the changes that take place inside the method affect the
original array in Main. In fact, the original array is reallocated
using the new operator. Thus, after calling the Change method, any
reference to myArray points to the five-element array [not the three-
element array], which is created in the Change method.
 
P

Peter Duniho

Francois said:
[...]
However, I think that, using new(), you can actually do anything that
keyword ref is able to do, using passing-ref-by-value, rather than
using keyword 'ref' and passing-ref-by-reference, if you put a little
thought behind it. Agreed?

I don't agree. How would you implement int.TryParse() without passing
by reference?

It is true that many uses of "ref" or "out" are unnecessary. That does
not, however, lead to the conclusion that "ref" and "out" are themselves
unnecessary.
[...]
When you pass a reference type to a method, you can always modify what
the reference points to. The ref/out (or lack of it) is in reference (no
pun intended) to the reference itself, not what it points to.

Yes. But this is usually rare, hence no need to "pass-a-reference-by-
reference" (usually), just "pass-a-reference-by-value", since what the
reference points to is much more important (usually) than the
reference itself. That's why C# code seems to always omit the 'ref'
keyword--usually it's not important.

That's true. Usually you don't need to pass by reference, and so that's
why usually passing by reference isn't done. But that doesn't mean you
don't need passing by reference at all. It just means that the
occasions in which it's necessary or desirable are infrequent.

Pete
 
J

Jon Skeet [C# MVP]

Peter Duniho said:
Francois said:
[...]
However, I think that, using new(), you can actually do anything that
keyword ref is able to do, using passing-ref-by-value, rather than
using keyword 'ref' and passing-ref-by-reference, if you put a little
thought behind it. Agreed?

I don't agree. How would you implement int.TryParse() without passing
by reference?

It is true that many uses of "ref" or "out" are unnecessary. That does
not, however, lead to the conclusion that "ref" and "out" are themselves
unnecessary.

Well, they're not strictly necessary - you can cope without them, e.g.
by passing in an array of length 1.

Java manages reasonably well without out/ref parameters. Sometimes it's
desirable, but I'd say that (within safe code at least) it's never
strictly necessary. (Obviously if an existing method has out/ref
parameters, it's necessary in order to call that method - but I'm
saying that a world without out/ref parameters is reasonable.)
 
F

Francois Appert

Because passing a reference by value isn't the same as passing a
parameter by reference.

Seehttp://pobox.com/~skeet/csharp/parameters.html


Thanks. I liked this explanation, albeit it took a while for it to
sink in: "There are four different kinds of parameters in C#: value
parameters (the default), reference parameters (which use the ref
modifier), output parameters (which use the out modifier), and
parameter arrays (which use the params modifier). You can use any of
them with both value and reference types. When you hear the words
"reference" or "value" used (or use them yourself) you should be very
clear in your own mind whether you mean that a parameter is a
reference or value parameter, or whether you mean that the type
involved is a reference or value type. If you can keep the two ideas
separated, they're very simple"

Fran
 
P

Peter Duniho

Jon said:
Peter Duniho said:
Francois said:
[...]
However, I think that, using new(), you can actually do anything that
keyword ref is able to do, using passing-ref-by-value, rather than
using keyword 'ref' and passing-ref-by-reference, if you put a little
thought behind it. Agreed?
I don't agree. How would you implement int.TryParse() without passing
by reference?

It is true that many uses of "ref" or "out" are unnecessary. That does
not, however, lead to the conclusion that "ref" and "out" are themselves
unnecessary.

Well, they're not strictly necessary - you can cope without them, e.g.
by passing in an array of length 1.

My main point is that the statements made do not in and of themselves
lead to the conclusion that passing by reference is unnecessary. I have
been having difficulty following the exact meaning in Francois's posts,
but he _seems_ to me to be saying that where he sees the keyword "ref",
he feels you can just replace that by returning the value instead.
That's not true, at least not in all cases (e.g. TryParse()).

That said, while it can be truthfully said that the keywords themselves
are not strictly necessary, that's not the same as saying that passing
by reference is unnecessary. For example, that's essentially what
passing in an array of length 1 is doing, so using that as an example
doesn't prove that passing by reference is unnecessary; it just
demonstrates an alternative way to pass by reference.

And of course, one can degenerate the question further by suggesting
that C#, .NET, the Windows API, etc. are not, strictly speaking,
necessary. That is, it is trivially demonstrable that you can always
implement something that would naturally be passing by-reference as
something that effectively works like passing by-reference, but which is
technically speaking not passing by-reference.

My experience has been that most of the time I find myself putting a
by-reference parameter, it's because I'm being lazy and avoiding
restructuring the design so that it's better. But I do every once in
awhile find a situation in which passing by reference is truly useful.
Absolutely necessary? No...hardly anything we do in code is literally
"necessary". But I'm not sure there's much value in taking the pedantry
that far. :)

Pete
 
P

Peter Duniho

Jon said:
Peter Duniho said:
Francois said:
[...]
However, I think that, using new(), you can actually do anything that
keyword ref is able to do, using passing-ref-by-value, rather than
using keyword 'ref' and passing-ref-by-reference, if you put a little
thought behind it. Agreed?
I don't agree. How would you implement int.TryParse() without passing
by reference?

It is true that many uses of "ref" or "out" are unnecessary. That does
not, however, lead to the conclusion that "ref" and "out" are themselves
unnecessary.

Well, they're not strictly necessary - you can cope without them, e.g.
by passing in an array of length 1.

My main point is that the statements made do not in and of themselves
lead to the conclusion that passing by reference is unnecessary. I have
been having difficulty following the exact meaning in Francois's posts,
but he _seems_ to me to be saying that where he sees the keyword "ref",
he feels you can just replace that by returning the value instead.
That's not true, at least not in all cases (e.g. TryParse()).

That said, while it can be truthfully said that the keywords themselves
are not strictly necessary, that's not the same as saying that passing
by reference is unnecessary. For example, that's essentially what
passing in an array of length 1 is doing, so using that as an example
doesn't prove that passing by reference is unnecessary; it just
demonstrates an alternative way to pass by reference.

And of course, one can degenerate the question further by suggesting
that C#, .NET, the Windows API, etc. are not, strictly speaking,
necessary. That is, it is trivially demonstrable that you can always
implement something that would naturally be passing by-reference as
something that effectively works like passing by-reference, but which is
technically speaking not passing by-reference.

My experience has been that most of the time I find myself putting a
by-reference parameter, it's because I'm being lazy and avoiding
restructuring the design so that it's better. But I do every once in
awhile find a situation in which passing by reference is truly useful.
Absolutely necessary? No...hardly anything we do in code is literally
"necessary". But I'm not sure there's much value in taking the pedantry
that far. :)

Pete
 
P

Peter Duniho

Jon said:
Peter Duniho said:
Francois said:
[...]
However, I think that, using new(), you can actually do anything that
keyword ref is able to do, using passing-ref-by-value, rather than
using keyword 'ref' and passing-ref-by-reference, if you put a little
thought behind it. Agreed?
I don't agree. How would you implement int.TryParse() without passing
by reference?

It is true that many uses of "ref" or "out" are unnecessary. That does
not, however, lead to the conclusion that "ref" and "out" are themselves
unnecessary.

Well, they're not strictly necessary - you can cope without them, e.g.
by passing in an array of length 1.

My main point is that the statements made do not in and of themselves
lead to the conclusion that passing by reference is unnecessary. I have
been having difficulty following the exact meaning in Francois's posts,
but he _seems_ to me to be saying that where he sees the keyword "ref",
he feels you can just replace that by returning the value instead.
That's not true, at least not in all cases (e.g. TryParse()).

That said, while it can be truthfully said that the keywords themselves
are not strictly necessary, that's not the same as saying that passing
by reference is unnecessary. For example, that's essentially what
passing in an array of length 1 is doing, so using that as an example
doesn't prove that passing by reference is unnecessary; it just
demonstrates an alternative way to pass by reference.

And of course, one can degenerate the question further by suggesting
that C#, .NET, the Windows API, etc. are not, strictly speaking,
necessary. That is, it is trivially demonstrable that you can always
implement something that would naturally be passing by-reference as
something that effectively works like passing by-reference, but which is
technically speaking not passing by-reference.

My experience has been that most of the time I find myself putting a
by-reference parameter, it's because I'm being lazy and avoiding
restructuring the design so that it's better. But I do every once in
awhile find a situation in which passing by reference is truly useful.
Absolutely necessary? No...hardly anything we do in code is literally
"necessary". But I'm not sure there's much value in taking the pedantry
that far. :)

Pete
 
P

Peter Duniho

Sorry for the repeat posts. Learning a new (to me) newsreader's UI and
it's got some idiosyncrasies. :)

(I tried canceling the posts, but it's my experience that news servers
rarely honor cancel requests any more, so that's probably not going to
have any effect).
 
J

Jon Skeet [C# MVP]

That said, while it can be truthfully said that the keywords themselves
are not strictly necessary, that's not the same as saying that passing
by reference is unnecessary. For example, that's essentially what
passing in an array of length 1 is doing, so using that as an example
doesn't prove that passing by reference is unnecessary; it just
demonstrates an alternative way to pass by reference.

The pedant in me has to point out that that *isn't* passing by
reference by the strict definition - the definition using lvalues etc.
It's like C - it is strictly pass-by-value, but you can accomplish the
same goals as the ones pass-by-reference is used for by passing a
pointer by value.
 
P

Peter Duniho

Jon said:
[...]
For example, that's essentially what
passing in an array of length 1 is doing, so using that as an example
doesn't prove that passing by reference is unnecessary; it just
demonstrates an alternative way to pass by reference.

The pedant in me has to point out that that *isn't* passing by
reference by the strict definition

The pedant in me agrees with the pedant in you.

However, the fact remains that one is still essentially passing by
reference in that case, in a similar way that passing a pointer to a
pointer in C is just as much passing the pointer by reference as using
an actual reference is, even if it's technically not passing by reference.

IMHO, there are really two questions here. One, is the act of passing a
parameter in a way that allows for the modification of that parameter a
necessary feature? And two, is passing a parameter "by reference" a
necessary feature?

I allow that the strict, technical answer to the second is "no", but in
the sense that the answer to the first is "yes", if you don't have
something that is technically passing "by reference", you still need
_some_ mechanism that effectively does the same.

Software would be a LOT less interesting if a function being called had
no way to modify data outside of that function. :)

Pete
 
J

Jon Skeet [C# MVP]

Peter Duniho said:
Jon said:
[...]
For example, that's essentially what
passing in an array of length 1 is doing, so using that as an example
doesn't prove that passing by reference is unnecessary; it just
demonstrates an alternative way to pass by reference.

The pedant in me has to point out that that *isn't* passing by
reference by the strict definition

The pedant in me agrees with the pedant in you.
:)

However, the fact remains that one is still essentially passing by
reference in that case, in a similar way that passing a pointer to a
pointer in C is just as much passing the pointer by reference as using
an actual reference is, even if it's technically not passing by reference.

Agreed. I just think it helps to keep things *absolutely* straight when
discussing pass-by-reference - it's casual use of the terminology
("objects are passed by reference" etc) which leads to confusion, in my
experience.
IMHO, there are really two questions here. One, is the act of passing a
parameter in a way that allows for the modification of that parameter a
necessary feature? And two, is passing a parameter "by reference" a
necessary feature?

I allow that the strict, technical answer to the second is "no", but in
the sense that the answer to the first is "yes", if you don't have
something that is technically passing "by reference", you still need
_some_ mechanism that effectively does the same.
Software would be a LOT less interesting if a function being called had
no way to modify data outside of that function. :)

Possibly. It can't be *strictly* necessary, as you could always return
a complete copy of everything you want, with the client then taking
appropriate action. That would be pretty silly though.
 
?

=?ISO-8859-1?Q?Arne_Vajh=F8j?=

Francois said:
The issue is: why should anybody bother in C# with pass-by-reference
using the "ref" keyword or "out" for objects in a method parameter
list, when, after all, it appears in C# that for all intents and
purposes a reference is always being passed, rather than the real
object (with, it seems, the exception of data primitives like int,
which are not 'boxed').

They are handy in some special cases where return values are not
suitable.

For an example try coding a Swap method.

It is relative rare that they are needed. I did a quick search
in a dir with 727 .cs files and I only used them in 12 of them.
And half of that usage were DllImport og Win32 API functions
where it was not my choice.
The reply from C# Corner by a poster, call him Brian, as to why 'ref'
is needed was to write out a simple demonstration program (see below),
which indeed seems to refute the above, and point out that unless you
use keyword "ref" in your method parameter, then you cannot change an
object passed to a method while inside the method.

However--and this is the point of this post--it seems I've found a
workaround so that even with the use of "pass by value", you can
indeed change an object passed, inside the called method (when you
exit the method), if you use the assignment operator "=" and return a
new object

I think his example was not well suited.

You need a method with more than one out to make the point.

Arne
 
B

Ben Voigt [C++ MVP]

Software would be a LOT less interesting if a function being called had
Possibly. It can't be *strictly* necessary, as you could always return
a complete copy of everything you want, with the client then taking
appropriate action. That would be pretty silly though.

I think you just insulted all the Functional Programmers in the world.
 
J

Jon Skeet [C# MVP]

I think you just insulted all the Functional Programmers in the world.

I suspect functional programmers have different idioms for coping with
the situation. I was meaning returning a value and then manually
copying all of the changed properties into the appropriate object. As
far as I'm aware that's *not* what functional programmers do :)

Jon
 

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