Using ref

This is a discussion on Using ref within the CSharp forums in Programming Languages category; On Jul 3, 8:36*am, "Hilton" <nos...@nospam.com> wrote: > 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 ...

Go Back   Application Development Forum > Programming Languages > CSharp

Object Mix

Register FAQ Calendar Search Today's Posts Mark Forums Read
  #11  
Old 07-03-2008, 04:13 AM
Jon Skeet [C# MVP]
Guest
 
Default Re: Using ref

On Jul 3, 8:36*am, "Hilton" <nos...@nospam.com> wrote:
> 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
Reply With Quote
  #12  
Old 07-03-2008, 04:25 AM
Peter Duniho
Guest
 
Default Re: Using ref

On Thu, 03 Jul 2008 00:36:38 -0700, Hilton <nospam@nospam.com> wrote:

> Jon,
>
> I have to disagree with you that objects themselves are passed by value.


Jon never said they were. In fact, he pointedly stated that objects are
themselves never passed at all in C#.

I agree with this viewpoint, and it's consistent with the usage of the
terms in the C# specification, as well as MSDN's documentation of C#.

> 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.


Straw man. You're arguing a point that was never in contention.

> Also, passing by value means that the thing cannot be changed;


That's not what "passing by value" means. It's true that the original
argument cannot be changed, but that's just a side-effect of what "by
value" really is: making a copy of the original argument and passing that
to the method.

> 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).


The method can _not_ change the original argument that was passed, which
is what distinguishes passing "by value" and "by reference".

> C# simple passes a reference to the object which is
> the same as C passing in a pointer to the data.


Not really. In C, you have the option of passing the data as a complete
copy. This simply doesn't exist in C#. The reference _is_ the data. But
more importantly, C++ distinguishes between passing a pointer by value,
and passing a pointer by reference. It's true that before C++ came along
and introduced the passing of parameters by reference, people would just
pass a pointer and call that "by reference". But it's not really what was
happening. In C/C++ when you pass a pointer without the "&" as part of
the parameter declaration, you are passing a pointer _by value_.

> 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.


That's right. Because in both cases the parameter is passed by value, the
original storage for that value cannot be modified by the method/function
being called.

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


Wrong. The fact that a reference is being passed does not mean the
parameter is being passed "by reference".

> C - passes a pointer to the data (not the data) and the data can be
> changed
> by the method


Again, wrong. The pointer is being passed by value.

> 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.


Wrong. Both are passing by value. That's why the caller's copy of the
value is not changed when the method assigns "x" to "null".

> If you view "x" as a reference to the StringBuilder
> object, then you're passing the object by reference


Saying the same thing over and over again isn't going to make it true.
The fact that a reference is being passed does not make it "passing by
reference". The reference is passed by value.

> (which you said did not
> happen). If you view "x" as the actual StringBuilder object,


Why would we do that? The actual object is accessible only through a
reference. There is no way to put the object itself into a variable.

> 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.


"It uses"? What uses? You haven't posted any code that you could be
referring to. 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.
Try it and see. If you just pass an object reference by value, a plain
"ldloc" instruction is used, not "ldloca".

If this is the basis of your argument, then I'd say you just blew up your
own argument. By your own description, since "ldloca" is _not_ used when
you pass by value, even when the argument is a object reference, obviously
the object reference is being passed by value, not by reference.

> Apart from ints, floats, etc, C# passes all objects by reference.


No. C# passes _everything_ by value, unless you state otherwise with
"ref" or "out". The fact that the value is sometimes a reference is
immaterial. It is still passed by value.

> "ref"
> simply passes the address of the reference thereby allowing the method to
> change it (exactly the same as C).


That's right...it passes a _reference_ to the reference. That is, using
"ref" is how you pass "by reference". If you're not using "ref" or "out",
you're not passing by reference.

> "out" is the same as "ref" except that
> the method is forced, by the compiler, to assign a value to the
> parameter.


And the caller is not.

> How is this C code that uses pass by reference:
>
> byte* b = {some array of bytes};
> method (b);


That's not C code that uses pass by reference. It's passing a pointer by
value.

> ...different to this C# code?
>
> byte[] b = new byte[]{some array of bytes};
> method (b);


It's exactly the same and both are passing 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 to
> get
> the filename".


I would never say "add the two strings" or "add the two string
references". I would say "concatenate the two strings". But how is this
at all related to the question of passing by value or by reference?

> So, if we view "s" as a string, then "method (s)" is pass by
> reference.


Huh? If we view "s" as a string, then "method(s)" is passing the object
"s" by value. Even using your incorrect terminology, the "method(s)" can
only be "pass by reference" is we view "s" as a 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.


I beg to differ. As long as you insist on posting a claim contrary to the
truth, there will be a need to "rehash what they ahve already written".

All that literature out there that agrees with our point of view, it
didn't just happen by accident. There's a _reason_ that the vast majority
of C# documentation (and _all_ of the definitive documentation, such as
the specification itself) agrees with this point of view.

> Maybe it's just me, but I cannot see how C# passes objects by
> value.


It'd be one thing if you were approaching this naïvely. We could just
explain how things really work, and you could get on with whatever it is
you're doing. But you've obviously put a lot of effort and thought into
your argument. Which means you're simply not paying attention to reality.

Don't get confused by the fact that the same word is used in two different
ways. That's a huge mistake on your part.

And consider this: if you are already always passing objects by reference,
then what does it mean to use "ref" when you are passing an object? Are
you passing "by reference by reference"?

Pete
Reply With Quote
  #13  
Old 07-03-2008, 06:09 AM
Hilton
Guest
 
Default Re: Using ref

Jon Skeet wrote:
Hilton wrote:
>> 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.


You replied to Steve:

Steve Harclerode <Lizard.That.Was@hot.mail.com> wrote:
> 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


Reply With Quote
  #14  
Old 07-03-2008, 06:28 AM
Jon Skeet [C# MVP]
Guest
 
Default Re: Using ref

On Jul 3, 11:09*am, "Hilton" <nos...@nospam.com> wrote:
> Jon Skeet wrote:
> Hilton wrote:
> >> 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.

>
> You replied to Steve:
>
> Steve Harclerode <Lizard.That....@hot.mail.com> wrote:
> > 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?


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/...al/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
Reply With Quote
  #15  
Old 07-03-2008, 06:33 AM
Hilton
Guest
 
Default Re: Using ref

Peter Duniho wrote:
> 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


Reply With Quote
  #16  
Old 07-03-2008, 07:00 AM
Marc Gravell
Guest
 
Default Re: Using ref

> 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
Reply With Quote
  #17  
Old 07-03-2008, 07:02 AM
Jon Skeet [C# MVP]
Guest
 
Default Re: Using ref

On Jul 3, 11:33*am, "Hilton" <nos...@nospam.com> wrote:
> > 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???


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
Reply With Quote
  #18  
Old 07-03-2008, 09:28 AM
raylopez99
Guest
 
Default Re: Using ref

On Jul 2, 10:46*pm, "Jon Skeet [C# MVP]" <sk...@pobox.com> wrote:

> 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 . . .
Reply With Quote
  #19  
Old 07-03-2008, 09:44 AM
Jon Skeet [C# MVP]
Guest
 
Default Re: Using ref

On Jul 3, 2:28*pm, raylopez99 <raylope...@yahoo.com> wrote:
> > 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;"


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
Reply With Quote
  #20  
Old 07-03-2008, 09:55 AM
Marc Gravell
Guest
 
Default Re: Using ref

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
Reply With Quote
Reply


Thread Tools
Display Modes


All times are GMT -5. The time now is 08:25 AM.


Powered by vBulletin® Version 3.7.2
Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO 3.2.0
vB Ad Management by =RedTyger=

In an effort to better serve ads to our visitors, cookies are used on objectmix.com. For more information, check out our Privacy Policy.