Using ref

  • Thread starter Thread starter Arjen
  • Start date Start date
A

Arjen

Hi,

Form a performance perspective, is it wise to use the ref statement as much
as possible?

Thanks!
Arjen
 
The objects themselves are passed by reference anyway, so I would think that
using "ref" would actually slow things down a tiny bit (adds one more level
of indirection.

I only use "ref" when I need to reseat the variable to point to a different
object.

- Steve
 

I agree with Jon Skeet here. A ref should be used when you have a
reference-type object passed to your function, which usually means
something that is instantiated with "new" in the function. But, if
you don't use "new" in your method/function for the object passed to
it, then use the default pass by value. Interestingly enough, both
pass by value and pass by reference *will* both alter the object
passed *outside* the function/method--the opposite is usually implied
in most textbook examples. In most examples it is stated that only
pass by reference will alter the object-- with usually the famous
'swap variables' example using 'temp' given--but what most people
don't realize is that this swap variable example is using 'new' inside
the function/method (check it out next time you see it, and you'll see
that's the case), which is exactly when you should use 'ref'--
otherwise stick to the default pass-by-value. If 'new' is not being
used for the object passed, use the default pass-by-value, as it's
slightly faster, as implied in this thread. The only exception to the
above is when primitive values (int, double, etc) are passed to a
function/method--but here, this seems to be an exception because these
are value-type parameters stored on the stack rather than heap, so
boxing/unboxing is involved. Technically, you could box these
primitive value-type parameters as reference-type objects, then there
would be no 'exception'. Anyway, it usually doesn't make sense to
refer to 'ref' when passing an int parameter to a method/function
anyway, so this is really not an exception to the rule.

In short, the rule is this: when using 'new' inside your method, to
instantiate a object being passed to the method (in the parameters
list), then use the 'ref' keyword in the parameters, to pass by
reference, otherwise, stick with the default (no keyword) pass-by-
value.

If the above doesn't make sense, don't worry about it--just keep
programming and it will become clear eventually.

Ray Lopez
[C# N00b MVP]
 
I've read the page, but I still don't see how my languaging would be
considered different than "references are passed by value". What part of
what I wrote isn't correct?

When a parameter is passed by reference, that means that changes to
the parameter are reflected in the variable used as the argument. When
a reference is passed by value, that's not the case.

So consider this code:

public void Swap (object a, object b)
{
object tmp = a;
a = b;
b = a;
}

If the parameter were passed by reference by default, that would work.
As it is, it does nothng.

The *object* isn't actually passed at all, which is another reason
that "objects are passed by reference" is incorrect. In particular,
consider the case where the reference is actually null. What's being
passed and in what way at that point?

It's a clearer and more accurate mental model to talk about references
being passed by value. It avoids confusing people who understand what
"by reference" means, and would expect the Swap method above to work
when presented with your description. (I've seen this happen on
various occasions.) It also makes it very confusing when you add the
"ref" parameter for a reference type - if things were already being
passed by reference, what would adding "ref" do?

Jon
 
I've read the page, but I still don't see how my languaging would be
considered different than "references are passed by value". What part of
what I wrote isn't correct?

Genuinely interested,
Steve
 
Jon,

I have to disagree with you that objects themselves are passed by value.
Passing by value means that you pass the value; i.e. a byte[] (or Vector, or
Hashtable) being passed as value passes the entire thing - that doesn't
happen. Also, passing by value means that the thing cannot be changed;
hence passing by value not reference. But when you do "method (list)",
method can change list because a reference to the list is being passed, not
the list (aka value). C# simple passes a reference to the object which is
the same as C passing in a pointer to the data. And the method cannot
change the reference in C# just as the method in C cannot change the pointer
(from the caller's point of view) - same thing.

Pass by reference:
C# - passes a reference to the data (not the data) and the data can be
changed by the method
C - passes a pointer to the data (not the data) and the data can be changed
by the method

The example you give on your page "method (StringBuilder x)" then "x = null"
is exactly the same as C having "method (int *x)", then "x = NULL"; i.e.
pass by reference. If you view "x" as a reference to the StringBuilder
object, then you're passing the object by reference (which you said did not
happen). If you view "x" as the actual StringBuilder object, then the VM is
effectively passing &x (C terminology) - again, by reference. It uses
ldloca.s which is defined as "Loads the address of the local variable at a
specific index onto the evaluation stack, short form." - same as C.

Apart from ints, floats, etc, C# passes all objects by reference. "ref"
simply passes the address of the reference thereby allowing the method to
change it (exactly the same as C). "out" is the same as "ref" except that
the method is forced, by the compiler, to assign a value to the parameter.

How is this C code that uses pass by reference:

byte* b = {some array of bytes};
method (b);

....different to this C# code?

byte[] b = new byte[]{some array of bytes};
method (b);

In a meeting, would you ever say "Add the two string references together to
get the filename"? I wouldn't, I'd say "Add the two strings together to get
the filename". So, if we view "s" as a string, then "method (s)" is pass by
reference.

Jon, Peter, before you reply, I know that most of the literature out there
agrees with your point of view, so no need to rehash what they have already
written. Maybe it's just me, but I cannot see how C# passes objects by
value.

Hilton
 
Jon Skeet said:
public void Swap (object a, object b)
{
object tmp = a;
a = b;
b = a;
}

If the parameter were passed by reference by default, that would work.
As it is, it does nothng.

Thinking back on my Pascal days, by golly you're right (you probably knew
that already).
It's a clearer and more accurate mental model to talk about references
being passed by value. It avoids confusing people who understand what

It is a better mental model, I'll use it the next time I have to mentor a
new person. God help the others I've already worked with. Actually, they
seem to be doing all right, so hopefully they absorbed the correct
information somewhere.
:-)

- Steve
 
I have to disagree with you that objects themselves are passed by value.

Where did I say that they were? I said that *references* are passed by
value. Objects aren't passed at all.
Passing by value means that you pass the value; i.e. a byte[] (or Vector, or
Hashtable) being passed as value passes the entire thing - that doesn't
happen.  Also, passing by value means that the thing cannot be changed;
hence passing by value not reference.

No, it means that the parameter is independent of the argument. In
other words, changing the parameter's value (which is just a
reference, for reference types) doesn't affect the caller.
But when you do "method (list)",
method can change list because a reference to the list is being passed, not
the list (aka value).

The list isn't the value. The value of the expression "list" is a
reference, not an object.
 C# simple passes a reference to the object which is
the same as C passing in a pointer to the data.  And the method cannot
change the reference in C# just as the method in C cannot change the pointer
(from the caller's point of view) - same thing.

Pass by reference:
C# - passes a reference to the data (not the data) and the data can be
changed by the method
C - passes a pointer to the data (not the data) and the data can be changed
by the method

The example you give on your page "method (StringBuilder x)" then "x = null"
is exactly the same as C having "method (int *x)", then "x = NULL"; i.e.
pass by reference.

C doesn't have pass by reference at all. In C, all parameters are
passed by value. Taking the address of a variable and passing that as
a pointer is *not* the same as pass-by-reference. It's used to achieve
the same effect, but it's not the same thing - because the type of the
parameter is then the pointer, not the type of the original variable.
When you take the address of a variable in order to pass that pointer,
the pointer itself is passed by value.
 If you view "x" as a reference to the StringBuilder
object, then you're passing the object by reference (which you said did not
happen).

No, you're passing the reference by value.
 If you view "x" as the actual StringBuilder object, then the VM is
effectively passing &x (C terminology) - again, by reference.

But you shouldn't view "x" as the actual StringBuilder object, because
it's not. "x" is a variable, and the result of evaluating that
variable is a reference - not an object.
Apart from ints, floats, etc, C# passes all objects by reference.  "ref"
simply passes the address of the reference thereby allowing the method to
change it (exactly the same as C).

Once again, C is strictly pass by value.
How is this C code that uses pass by reference:

byte* b = {some array of bytes};
method (b);

...different to this C# code?

byte[] b = new byte[]{some array of bytes};
method (b);

It's not - because neither of them use pass by reference. In both
cases the parameter (whether it's a pointer or a byte array reference)
is passed by value.
In a meeting, would you ever say "Add the two string references together to
get the filename"?  I wouldn't, I'd say "Add the two strings together toget
the filename".  So, if we view "s" as a string, then "method (s)" is pass by
reference.

That's because typically in a meeting you don't require precision of
terminology. When the topic in question is parameter passing, however,
it's worth being precise.
Jon, Peter, before you reply, I know that most of the literature out there
agrees with your point of view, so no need to rehash what they have already
written.

So are you not willing to discuss why I view your point of view as
incorrect?
 Maybe it's just me, but I cannot see how C# passes objects by value.

Who said it did? I certainly didn't. I have said (several times) that
it passes *references* by value. The value of an expression is never
an object.

Jon
 
Jon Skeet wrote:
Where did I say that they were? I said that *references* are passed by
value. Objects aren't passed at all.

You replied to Steve:

Steve Harclerode said:
The objects themselves are passed by reference anyway

No, they're not.
---

I then made the assumption that if the object wasn't passed by reference, it
is passed by value - which is it?

[zap your reply]

Jon, I totally 'see' you view on this (which seems to be consistent with
many/most others - i.e. I acknowledge that I am in the minority here). My
point is that a method works on data and I care about the data, I care about
the stuff that is in arrays, lists etc. Now, even though you assert that "C
doesn't have pass by reference at all.", for decades millions of people were
taught the difference between passing by reference and passing by value
using C, were they wrong? If I have data, and I don't pass that data to a
method, but rather pass a reference/pointer (whatever the syntax), then (in
my mind) it is pass by reference. C# and C really aren't that different in
these terms, just that it is hidden (thankfully) - I don't think that the
syntax of the language should change the terminology of what really is
happening under the covers. The key here is that you're thinking strictly
in terms of the parameters, I'm thinking in terms of the data.

Wow, I'm still trying to wrap my head around your "C doesn't have pass by
reference at all" comment. I understand your logic of it, but it sure as
heck doesn't make any sense to me. Having said that, I think Wikipedia sums
up our two opposing views in this line: "Java is a call-by-value language,
but since most Java expressions are references to anonymous objects, it
frequently displays call-by-reference semantics without the need for any
explicit reference syntax."

Hilton


Hilton
 
Jon Skeet wrote:


You replied to Steve:



No, they're not.

Well, you could have read the *very next sentence* in my reply, which
explained what actually happens:

"The references are passed by value."

Your assumption reminds me of the "When did you stop beating your
wife?" question.
[zap your reply]

Jon, I totally 'see' you view on this (which seems to be consistent with
many/most others - i.e. I acknowledge that I am in the minority here).  My
point is that a method works on data and I care about the data, I care about
the stuff that is in arrays, lists etc.  Now, even though you assert that "C
doesn't have pass by reference at all.", for decades millions of people were
taught the difference between passing by reference and passing by value
using C, were they wrong?

Yes. If they'd read K&R, I believe they'd have seen something
explicitly saying that C only supports pass by value. (I don't have a
copy to hand, but I'm pretty sure I've seen it there before.) You can
*simulate* pass by reference in C, but it's not true pass by
reference.
 If I have data, and I don't pass that data to a
method, but rather pass a reference/pointer (whatever the syntax), then (in
my mind) it is pass by reference.

Then your mind is wrong by the technical definitions of pass by
reference.
See http://en.wikipedia.org/wiki/Evaluation_strategy
 C# and C really aren't that different in
these terms, just that it is hidden (thankfully) - I don't think that the
syntax of the language should change the terminology of what really is
happening under the covers.

Whether the language supports pass by reference or not is defined by
the language specification. C# *does* support pass by reference using
the "ref" keyword. C doesn't support it (directly - you can emulate it
but that's not the same thing).
 The key here is that you're thinking strictly
in terms of the parameters, I'm thinking in terms of the data.

I'm thinking in terms of the meanings of technical terms, which are
how we communicate.
Wow, I'm still trying to wrap my head around your "C doesn't have pass by
reference at all" comment.  I understand your logic of it, but it sure as
heck doesn't make any sense to me.

That's because I believe you've been misunderstanding the meaning of
"pass by reference" as indeed many people do.
Pass by reference has a very specific meaning, and it isn't directly
supported by the C language. You have to work round the lack of
support by explicitly passing (and receiving) a pointer *by value*.

It's not just me that says that C doesn't directly have pass-by-
reference semantics though:
http://en.wikipedia.org/wiki/C_(programming_language)
http://www.math.cam.ac.uk/undergrad/catam/ccatsl/manual/node50.html
http://www.comp.nus.edu.sg/~esim/faq/node12.html

As I say, I believe it's explicitly stated in K&R as well.
 Having said that, I think Wikipedia sums
up our two opposing views in this line: "Java is a call-by-value language,
but since most Java expressions are references to anonymous objects, it
frequently displays call-by-reference semantics without the need for any
explicit reference syntax."

Yes, the effects can be similar in many cases. That doesn't mean it's
the same thing. Calling C#'s default behaviour "pass by reference" can
be very confusing (I've seen several people get confused by it) and
often leads to the mistaken belief that adding the "ref" modifier for
a parameter which uses a reference type makes no difference. After
all, if it's already being passed by reference, what difference could
"ref" make?

Once you understand that the value of a variable (or any expression)
is either a value type value or a reference (including null) you end
up with a much more consistent mental model which works well with
parameters, assignment, GC etc. Trying to think of the world in terms
where the value of a variable is the object itself falls down all over
the place, as well as being further removed from the technical
details. Why do you want to push a more complicated world view which
just doesn't stand up to scrutiny?

Jon
 
Peter said:
Hilton wrote:
What example is it that you are saying uses "ldloca.s"? Are you
comparing this to managed code? If not, how can that be "same as C"?

In any case, the "ldloca.s" instruction is used when you pass by
reference, yes. But that's only when you use the "ref" or "out" keyword.

My point is that the C# call "method (ref x)" is defined by
you/Jon/community as being pass by reference, yet the C call "method (&x)"
is defined by you/Jon/community as being pass by value - they're doing
EXACTLY the same thing. Both simply take the address of x and pass it
along. Does a prettier syntax changes the entire concept? And if
Microsoft has used "&" instead of "ref" in its definition of the C#
language, would that now mean that the C# call "method (&x)" was now pass by
value???

Pete, really, I don't want to spend more of your time or my time on this.
In my mind (which I agree probably doesn't fit the pure definition of the
pass-by definitions), if I pass a reference or pointer to my chunk of data,
I'm passing by reference (the focus being on the data, not the actual
parameter). I think millions of other people think that way too since
pass-by-reference has been taught for decades when discussing C, but
apparently that capability never existed.

Hilton
 
if I pass a reference or pointer to my chunk of data,
I'm passing by reference

You can keep repeating this, but it doesn't make it true. And re-
iterating it only adds confusion for new C# developers; one of the
reasons so many people get it wrong is because others (like yourself)
seem to be going out of their way to keep the myth alive.

In short: no; you simply happen to be passing a value that *is* a
reference. Bass-by-reference (of a class) would be passing a reference/
pointer to something that *itself* happens to be a reference. In this
case, it is the address of the variable/field "x" that is actually
passed. In the original case, it is the current *value* of the
variable/field "x" that is passed - i.e. the reference to the
instance. The explanation works better with a picture, but...

I very-much doubt my voice will sway you much, but there we go...

Marc
 
My point is that the C# call "method (ref x)" is defined by
you/Jon/community as being pass by reference, yet the C call "method (&x)"
is defined by you/Jon/community as being pass by value - they're doing
EXACTLY the same thing. Both simply take the address of x and pass it
along.  Does a prettier syntax changes the entire concept?   And if
Microsoft has used "&" instead of "ref" in its definition of the C#
language, would that now mean that the C# call "method (&x)" was now pass by
value???

You're only looking at the calling side. Look at the declaring side.

In C, you're declaring the parameter with a different type - a pointer
type. You then have to *use* that parameter differently as well,
explicitly dereferencing etc.
In C#, you declare that the parameter is passed by reference, but the
actual parameter has the same original type, and can be used within
the method as if it were any other variable of that type.

If Microsoft had used & but still had all the pass by reference
semantics on the declaring side, it would still have been pass by
reference. If it had involved changing the parameter type to be a
pointer, and then dereferencing the pointer etc, it would have been
pass by value.
Pete, really, I don't want to spend more of your time or my time on this.
In my mind (which I agree probably doesn't fit the pure definition of the
pass-by definitions), if I pass a reference or pointer to my chunk of data,
I'm passing by reference (the focus being on the data, not the actual
parameter).  I think millions of other people think that way too since
pass-by-reference has been taught for decades when discussing C, but
apparently that capability never existed.

The ability to simulate it has existed, but the calling mechanism has
always been pass-by-value.

Look at it this way:
1) You accept that you're technical incorrect
2) Your way of thinking *has* confused people in the past, several
times
3) Your mental model makes talking about other concepts such as
assignment harder
4) Your mental model leads to confusion when reference types *are*
passed by reference

Where exactly are the benefits of using the inaccurate terminology?

Since writing the article on my web page, I've had dozens of people
emailing me to say they now understand both parameter passing *and
other aspects of reference types* much clearer. Why try to cling onto
an inaccurate model where the value of a variable is an object instead
of a reference?

Jon
 
So consider this code:

public void Swap (object a, object b)
{
    object tmp = a;
    a = b;
    b = a;

}

If the parameter were passed by reference by default, that would work.
As it is, it does nothng.

This example is totally wrong Jon. You probably meant to write
"b=tmp;"
And you call yourself a "[C# MVP]"? Well, I can call myself an "C#
N00b MVP" then.

But we all make mistakes--in my previous post in this thread, I stated
'ref' is only needed when objects are passed if the calling method
uses 'new'--this is not strictly speaking true, as evidenced by the
line by Jon above "object tmp = a;". (Though, to be pedantic, "object
tmp = new object(); tmp = a;" would also work, but not be as concise
and fast).

To demonstrate that for most stuff, except for swap, 'new' and stuff
where you are redirecting the references, I wrote a short program
below to show when to use 'ref' and pass-by-reference for reference-
types (objects, strings) and when to not use 'ref' and just rely on
pass-by-value for reference-types, which usually for most stuff gives
the same result.

As you can see for the string (a reference type) passing by reference
is the same as passing by value when changing the string--and outside
the method the string *is* changed. However, if 'new' were involved,
it would be different.

You can see this by looking at the StringBuilder methods below--one is
pass-by-value, and the other is pass-by-reference. Both 'do stuff' to
the strings that are persistent--even outside the methods--for example
X.Append("SB1") changes the string in the pass-by-value method. But
when 'new' is involved, you must pass-by-reference when passing a
reference-type parameter (such as a string, an array, an object).

In the second example, the traditional "swap" method is demonstrated,
which shows again why 'ref' keyword is needed to make such a
'redirection' of objects and/or references to objects persistent
outside the method.

Ray Lopez
[C# N00b MVP]
-
using System;
using System.Collections.Generic;
using System.Text;

namespace ParaPassingPassByValByRef_01
{
class Program
{
static void Main(string[] args)
{
StringBuilder mainY = new StringBuilder();
mainY.Append("Hellow");
Console.Write("Output of mainY is true or false?...");
Console.WriteLine(mainY != null);
Console.WriteLine("value of string mainY is:{0}", mainY);
// mainY = null; //causes runtime error!
mainY.Append(" ");

// ignore the next few lines dealing with mainY2--it's an
attempt to see if a string can be set to null

StringBuilder mainY2 = new StringBuilder ("");
mainY2 = null;

Console.Write("..................");

//mainY2.Append("hello2");
//Console.WriteLine("str hello2: {0}", mainY2);

Console.WriteLine(mainY2 == null); //it's dangerous to do
anything but check for this condition when setting an object to
'null' (runtime error)
// end of mainY2

FooClass1 myFC1 = new FooClass1();
myFC1.FooClassSB1(mainY);
Console.WriteLine("mainY after SB1 is: {0}, int is: {1}",
mainY, myFC1.j);
myFC1.FooClassSB2(ref mainY);
Console.WriteLine("mainY after SB2 is: {0}, int is: {1}",
mainY, myFC1.j);
// myFC1.FooClassSB1(mainY2); //dangerous!: compiles but
gives runtime error

AClass1 A = new AClass1();
A.Aint = 111;
AClass1 B = new AClass1();
B.Aint = 222;
Console.WriteLine("main A,B before swap: {0}, {1}",
A.Aint, B.Aint);
myFC1.Swap(ref A, ref B);

Console.WriteLine("main A,B after swap: {0}, {1}", A.Aint,
B.Aint);
Console.WriteLine("................");
Console.WriteLine("reset back to A=111, B=222");
A.Aint = 111; B.Aint = 222;
Console.WriteLine("main A,B before swap2: {0}, {1}",
A.Aint, B.Aint);
myFC1.Swap2(A, B);

Console.WriteLine("main A,B after swap2: {0}, {1}",
A.Aint, B.Aint);

}
}
}


//////////////////////
using System;
using System.Collections.Generic;
using System.Text;

namespace ParaPassingPassByValByRef_01
{
class FooClass1
{
public FooClass1()
{
j = 101;
}
public int j;

public void FooClassSB1(StringBuilder x)
{
x.Append("SB1");
Console.WriteLine("inside FCSB1, part I: {0}", x);
j = j + 123;
StringBuilder temp = new
StringBuilder("temp_string_local_only!");
x = temp;
Console.WriteLine("inside FCSB1, part II: {0}", x);
}
public void FooClassSB2(ref StringBuilder x)
{
x.Length = 0; //this truncates [sets] string to zero
length (nice feature)
x.Append("SB2!");
Console.WriteLine("inside FCSB2, part I: {0}", x);
j = 22222;

StringBuilder temp = new
StringBuilder("temp_string_NOT_just_local_only!");
x = temp;
Console.WriteLine("inside FCSB2, part II: {0}", x);

}

public void Swap(ref AClass1 a, ref AClass1 b)
{
AClass1 temp = a; //no need for ‘new’ for temp
instantiation
Console.WriteLine("inside Swap a: {0}", a.Aint);
a = b;
Console.WriteLine("inside Swap a, b, before b swap: {0},
{1}", a.Aint, b.Aint);
b = temp;
Console.WriteLine("inside Swap a,b, after swap: {0}, {1}",
a.Aint, b.Aint);

}

public void Swap2(AClass1 a, AClass1 b)
{
// this version, Swap2, does not get the job done since 'ref' not
being used
AClass1 temp = new AClass1();
temp = a;
Console.WriteLine("inside Swap2 a: {0}", a.Aint);
a = b;
b = temp;
Console.WriteLine("inside Swap2 a,b, after swap: {0},
{1}", a.Aint, b.Aint);

}


}
}

/*

*/
/////////////////////////////////
using System;
using System.Collections.Generic;
using System.Text;

namespace ParaPassingPassByValByRef_01
{
class AClass1
{
public int Aint;

}
}

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

// OUTPUT

Output of mainY is true or false?...True
value of string mainY is:Hellow
..................True
inside FCSB1, part I: Hellow SB1
inside FCSB1, part II: temp_string_local_only!
mainY after SB1 is: Hellow SB1, int is: 224
inside FCSB2, part I: SB2!
inside FCSB2, part II: temp_string_NOT_just_local_only!
mainY after SB2 is: temp_string_NOT_just_local_only!, int is: 22222
main A,B before swap: 111, 222
inside Swap a: 111
inside Swap a, b, before b swap: 222, 222
inside Swap a,b, after swap: 222, 111
main A,B after swap: 222, 111
................
reset back to A=111, B=222
main A,B before swap2: 111, 222
inside Swap2 a: 111
inside Swap2 a,b, after swap: 222, 111
main A,B after swap2: 111, 222
Press any key to continue . . .
 
This example is totally wrong Jon.  You probably meant to write
"b=tmp;"

Yes, thank you for the correction.
And you call yourself a "[C# MVP]"?  Well, I can call myself an "C#
N00b MVP" then.

Well, you'll still just look foolish - as well as potentially confuse
a few newcomers.
As you can see for the string (a reference type) passing by reference
is the same as passing by value when changing the string--and outside
the method the string *is* changed.  However, if 'new' were involved,
it would be different.

Where is your string test? Where do you supposedly "change" a string?
(Strings are immutable.)

You do admittedly have various log lines which *claim* to be about
strings ("value of string mainY") but as mainY is of type
StringBuilder rather than string, that doesn't really say much.

Jon
 
Please tell me you're kidding. You aren't passing a String; you are
passing a StringBuilder. This does not prove *anything* relating to a
string (which is what you claim). A StringBuilder is a mutable wrapper
(which as an implementation detail, tortures a string internally).
Again, what this comes down to is passing a reference to the object
(StringBuilder). Try actually passing a *string* with/without "ref",
changing it inside the method, and see how far you get...

I'm not sure the swap example proves anything that we didn't already
know? The entire discussion of "new" is unrelated and purely
misleading/distracting to the actual discussion; the key thing is that
any *assignment* to the argument (be it to "new", to "null", or any
other value) - i.e. something that changes *the reference* is only
reflected to the caller with "ref". Which is the entire *point* of the
distinction of pass-by-reference vs reference-type.

Re MVP, the difference here is that it isn't the awardee who suddenly
decides that they are an MVP...

Marc
 
Please tell me you're kidding. You aren't passing a String; you are
passing a StringBuilder. This does not prove *anything* relating to a
string (which is what you claim). A StringBuilder is a mutable wrapper
(which as an implementation detail, tortures a string internally).

OK, picky picky! StringBuilder is what I meant, which is similar in
some way to String (capital S), but not a 'string', which in C# is not
a recognized type outside of String (that is, 'string' is the same as
'String' in C#, apparently the first letter is not case sensitive,
i.e., the C# compiler developers overloaded this term).
Again, what this comes down to is passing a reference to the object
(StringBuilder). Try actually passing a *string* with/without "ref",
changing it inside the method, and see how far you get...

I guess I would get the same as my demo program.
I'm not sure the swap example proves anything that we didn't already
know? The entire discussion of "new" is unrelated and purely
misleading/distracting to the actual discussion; the key thing is that
any *assignment* to the argument (be it to "new", to "null", or any
other value) - i.e. something that changes *the reference* is only
reflected to the caller with "ref". Which is the entire *point* of the
distinction of pass-by-reference vs reference-type.

Yes, I'm sure your correct *in your mind's eye*. But from the prose
you type, it's confusing. The point I made with the demo program is
that 'changes' the reference implies something happens to the
reference--and that something is permanent outside the method/function
calling it and the object it points to. What I showed is that whether
you pass a reference to an object by value or by reference in C#, in a
method/function, you can still do something 'permanent' to the object,
even when the method/function goes out of scope. This was
demonstrated in my program--which is copyright by the way-- in the
line: x.Append("SB1"); The StringBuilder variable mainY is assigned,
permanently, the value "SB1" even though mainY was passed (or a
reference to the same, if you're pedantic) to the function/method 'by
value' rather than 'by reference'.
Re MVP, the difference here is that it isn't the awardee who suddenly
decides that they are an MVP...

Marc

OK, OK, I'll stop using "N00b" then, if that's the problem. I'll put
a different disclaimer in.

Ray Lopez
[C# MVP] <--kinda, sorta, "in the mind's eye"
 

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

Back
Top