By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
455,670 Members | 1,512 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 455,670 IT Pros & Developers. It's quick & easy.

Using ref

P: n/a
Hi,

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

Thanks!
Arjen

Jul 2 '08 #1
Share this Question
Share on Google+
65 Replies


P: n/a
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

"Arjen" <bo*****@hotmail.comwrote in message
news:1B**********************************@microsof t.com...
Hi,

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

Thanks!
Arjen

Jul 2 '08 #2

P: n/a
Steve Harclerode <Li*************@hot.mail.comwrote:
The objects themselves are passed by reference anyway
No, they're not. The references are passed by value. There's a big
difference. See
http://pobox.com/~skeet/csharp/parameters.html
I only use "ref" when I need to reseat the variable to point to a different
object.
Exactly.

--
Jon Skeet - <sk***@pobox.com>
Web site: http://www.pobox.com/~skeet
Blog: http://www.msmvps.com/jon_skeet
C# in Depth: http://csharpindepth.com
Jul 2 '08 #3

P: n/a

"Jon Skeet [C# MVP]" <sk***@pobox.comschreef in bericht
news:MP*********************@msnews.microsoft.com. ..
Steve Harclerode <Li*************@hot.mail.comwrote:
>The objects themselves are passed by reference anyway

No, they're not. The references are passed by value. There's a big
difference. See
http://pobox.com/~skeet/csharp/parameters.html
>I only use "ref" when I need to reseat the variable to point to a
different
object.

Exactly.

--
Jon Skeet - <sk***@pobox.com>
Web site: http://www.pobox.com/~skeet
Blog: http://www.msmvps.com/jon_skeet
C# in Depth: http://csharpindepth.com
Thank you!

Jul 2 '08 #4

P: n/a
On Jul 2, 2:12*pm, Jon Skeet [C# MVP] <sk...@pobox.comwrote:
--
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]
Jul 2 '08 #5

P: n/a
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 Skeet [C# MVP]" <sk***@pobox.comwrote in message
news:MP*********************@msnews.microsoft.com. ..
Steve Harclerode <Li*************@hot.mail.comwrote:
>The objects themselves are passed by reference anyway

No, they're not. The references are passed by value. There's a big
difference. See
http://pobox.com/~skeet/csharp/parameters.html

Jul 3 '08 #6

P: n/a
On Jul 3, 7:33*am, "Steve Harclerode" <Camel.Software...@hot.mail.com>
wrote:
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
Jul 3 '08 #7

P: n/a
On Wed, 02 Jul 2008 23:33:57 -0700, Steve Harclerode
<Ca***************@hot.mail.comwrote:
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?
You wrote "objects are passed by reference". But _all_ parameters,
including references to objects, are passed _by value_, except when using
"ref" and "out" of course.

The fact that the value you're passing is a reference does not make the
parameter a "by reference" parameter, nor does it mean that the object is
passed by reference.

IMHO, Jon's article does in fact explain this.

Pete
Jul 3 '08 #8

P: n/a
"Jon Skeet [C# MVP]" <sk***@pobox.comwrote in message
news:ef**********************************@s50g2000 hsb.googlegroups.com...
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
Jul 3 '08 #9

P: n/a
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
Jul 3 '08 #10

P: n/a
On Thu, 03 Jul 2008 00:36:38 -0700, Hilton <no****@nospam.comwrote:
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
Jul 3 '08 #11

P: n/a
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 <Li*************@hot.mail.comwrote:
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
Jul 3 '08 #12

P: n/a
On Jul 3, 11:09*am, "Hilton" <nos...@nospam.comwrote:
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.comwrote:
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
Jul 3 '08 #13

P: n/a
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
Jul 3 '08 #14

P: n/a
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
Jul 3 '08 #15

P: n/a
On Jul 3, 11:33*am, "Hilton" <nos...@nospam.comwrote:
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
Jul 3 '08 #16

P: n/a
On Jul 2, 10:46*pm, "Jon Skeet [C# MVP]" <sk...@pobox.comwrote:
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 . . .
Jul 3 '08 #17

P: n/a
On Jul 3, 2:28*pm, raylopez99 <raylope...@yahoo.comwrote:
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
Jul 3 '08 #18

P: n/a
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
Jul 3 '08 #19

P: n/a
On Jul 3, 6:55*am, Marc Gravell <marc.grav...@gmail.comwrote:
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"
Jul 3 '08 #20

P: n/a
[walks away from the troll]
Jul 3 '08 #21

P: n/a
"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."
That is true, but not THE point. If your client lives, say, in Dallas, then,
when you want to reach it, you look where? in Dallas, no! if you are in
Seattle, you look at your cardfile holding your clients addresses. Now, if
one of your buddy (procedure), living in New York, ask to contact the said
client, you have two options: make a copy of your cardfile and 'pass' it to
him, that is 'by value', or you cant 'rent' him, for a while, your cardfile,
that will be 'passed by reference'. In both case, your New York buddy can
reach your client, in Dallas, and he can change your client to a not-client
anymore, quite permanently, sure, but, and there is a but, in the last case,
it can do much more, he can screw your cardfile too. And NEVER you ever
"passed" (ouch) the client it-self to your buddy.

Vanderghast, Access MVP

Jul 3 '08 #22

P: n/a
On Thu, 03 Jul 2008 03:33:13 -0700, Hilton <no****@nospam.comwrote:
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
That point is not supported by your assertion regarding the IL generated
for some hypothetical C# code (which you didn't post anyway, so who knows
what the hell you really meant).

In any case, the passing mechanism is defined by the declaration of the
method/function, not by the caller. The caller doesn't get to pick how
the method is called. It simply complies with whatever declaration was
made.

Since there's no such thing as passing "by reference" in C, I don't see
any inconsistency at all between the two examples you gave. The fact that
in C you can generate an arbitrary reference value to pass for a parameter
is irrelevant. You're still passing the reference by value, and the
function being called still cannot change the original value that was
passed.
- they're doing EXACTLY the same thing.
They are _not_ "doing EXACTLY the same thing". The C# version is passing
the address of a variable that contains a reference to an object, while
the C version is passing the address of a variable that contains the
object itself.
Both simply take the address of x and pass it along.
Does a prettier syntax changes the entire concept?
It's not just about "prettier syntax". In fact, it's not at all about
prettier syntax. There are fundamental differences between the two
examples.
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???
See above. The syntax is irrelevant. The caller is irrelevant. The only
thing that matters is the declaration of the method.
Pete, really, I don't want to spend more of your time or my time on this.
If that were true, you would stop arguing about it. Or if it's really a
true statement, then it seems that you're less concerned about my own
expenditure of time, and more concerned about how that reflects on you.
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
You remind me of the people who continue to cling to the idea that Iraq
had something to do with the 9/11 attacks and that Hussein was hiding
weapons of mass destruction somewhere in his country, in spite of
absolutely no evidence in support of those ideas and in spite of volumes
of evidence to the contrary.

In other words, you've decided on your dogma and no amount of actual facts
will have any effect on your beliefs.

That's an unfortunate characteristic for any human being, but it's
especially problematic for someone in a field like programming. Computers
don't adjust themselves to accommodate your way of thinking. No matter
how much you wish for C to have pass by reference, and no matter how much
you wish for C#'s pass by value to be the same as C#'s pass by reference,
it simply will not be.
(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.
From K&R, section A7.3.2 "Function Calls":

In preparing for the call to a function, a copy is
made of each argument; ALL ARGUMENT-PASSING IS
STRICTLY BY VALUE

(emphasis mine)

I really don't see how it could be any clearer than that. If you continue
to insist that the simple act of passing any reference is the same as
passing "by reference", we can only conclude that you are simply guilty of
willful ignorance.

It's unfortunate that you would continue to refuse to change your view on
the matter, but the worst part is your insistence on continuing to
promulgate your view as the correct one. If you want to remain ignorant
yourself, that's fine. But please, stop trying to make everyone else
ignorant too.

Pete
Jul 3 '08 #23

P: n/a
Peter Duniho wrote:
It's unfortunate that you would continue to refuse to change your view on
the matter, but the worst part is your insistence on continuing to
promulgate your view as the correct one.
I have no problem discussing things with people, but I don't like it (and I
think it shows your true colors - others have mentioned this too) when you
start trying to spread BS about people. I'm not trying to 'promulgate' my
view as the correct one, look what I said in my posts:

"I know that most of the literature out there agrees with your point of
view."
"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)."

Then you accuse me of not posting code. Without trying to sound sarcastic,
I assumed someone of your knowledge and experience (I mean this, I'm not
being sarcastic) would know how to write the following code, compile and run
ildasm and see the IL:

class Class1
{
[STAThread]
static void Main(string[] args)
{
new Class1 ().Go();
}

void Go ()
{
string s = "C#";

Method1 (s);
Method2 (ref s);

}

void Method1 (string s)
{}

void Method2 (ref string s)
{}
}
Hilton
Jul 3 '08 #24

P: n/a
On Thu, 03 Jul 2008 11:09:23 -0700, Hilton <no****@nospam.comwrote:
I have no problem discussing things with people, but I don't like it
(and I
think it shows your true colors - others have mentioned this too) when
you
start trying to spread BS about people. I'm not trying to 'promulgate'
my
view as the correct one,
Of course you are. Every time you state your disagreement with the
correct view, you are promulgating the incorrect view.
[...]
Then you accuse me of not posting code. Without trying to sound
sarcastic,
I assumed someone of your knowledge and experience (I mean this, I'm not
being sarcastic) would know how to write the following code, compile and
run
ildasm and see the IL: [snip]
I do know how to do that. I can even write it more concisely than you
did. So what?

The point is that YOU had some code in mind, but without seeing what code
you're talking about, there's no way to understand your statement. Given
the other errors you've made, there's no way I can make the assumption
that when you write about a particular IL instruction, you actually know
what code goes with that instruction.

Especially given that the only code preceding your statement that "It uses
ldloca.s" was this: "method (StringBuilder x)", it's difficult to see why
you'd say that the IL would use "ldloca".

There certainly is code that can generate that instruction, but you hadn't
mentioned any such code up to the point where you brought up that
instruction.

If I were going to give you the benefit of the doubt and assume that you
actually knew what you were talking about, I'd just ignore this whole
thread, figuring that when you write that passing an object's reference is
the same as passing the parameter "by reference", what you really mean is
that it's actually the same as passing the parameter "by value".

It's pretty obvious that making that assumption would be incorrect, and so
it's also pretty obvious that I can't make any other assumptions about
anything else you post. If you are going to state that some specific code
generates some specific IL instruction, you had darn well better post the
code that you claim generates that IL instruction. Otherwise, whatever
statement you make about the IL instruction doesn't add a single thing to
the discussion.

Pete
Jul 3 '08 #25

P: n/a
"Peter Duniho" <Np*********@nnowslpianmk.comwrote in message
news:op***************@petes-computer.local...
The fact that the value you're passing is a reference does not make the
parameter a "by reference" parameter, nor does it mean that the object is
passed by reference.

IMHO, Jon's article does in fact explain this.

Pete
Yes it does, and some days I'm slower than others. It didn't sink in for me
until Jon put up the Swap example.

- Steve
Jul 3 '08 #26

P: n/a
On Jul 3, 11:06*am, "Steve Harclerode" <Lizard.That....@hot.mail.com>
wrote:
>
Yes it does, and some days I'm slower than others. It didn't sink in for me
until Jon put up the Swap example.
Then you'll love my example even more. And Jon's Swap example had a
typo in it (that I corrected).

Remember the rules of Ray then: for optimal performance, use Ref.
For stuff that's primitive, use non-Ref (Swap by value). For objects
(including arrays, strings [all forms, including String,
StringBuilder], user defined classes), use ref only if "new" is
present in the function/method, or only if you are 'redirecting' the
object like with "Swap", otherwise it's OK to use pass-by-value.

RL

Jul 3 '08 #27

P: n/a
On Jul 3, 11:09*am, "Hilton" <nos...@nospam.comwrote:

Hilton--FYI Peter is a bit dogmatic, been that way for years, but he
is a useful reference here. We see your point, but I say give it a
rest. But for Jon and Peter, we wouldn't have decent programmers
working for free.

RL

[C# "newbie" MVP]

Jul 3 '08 #28

P: n/a
On Thu, 03 Jul 2008 11:55:13 -0700, raylopez99 <ra********@yahoo.com>
wrote:
[...]
Remember the rules of Ray then: for optimal performance, use Ref.
For stuff that's primitive, use non-Ref (Swap by value). For objects
(including arrays, strings [all forms, including String,
StringBuilder], user defined classes), use ref only if "new" is
present in the function/method, or only if you are 'redirecting' the
object like with "Swap", otherwise it's OK to use pass-by-value.
And to Steve: I _strongly_ recommend you use Google Groups to review
previous discussions and posts by Ray. You should take everything you
read on the Internet with a grain of salt anyway, but in this case you can
make a decision for yourself as to what advice is likely to be correct,
useful, etc. by examining previous contributions and seeing if they look
like they were written by someone you'd consider reliable.

And for what it's worth, the same thing is true for any of the rest of
us. You shouldn't accept any of our statements without at least some
critical consideration, and I'm not going to try to convince you that Jon,
I, or anyone else is more or less reliable than someone else. You can
make an informed decision yourself just by looking at past contributions
to the newsgroup.

As far as this particular question goes, it's my strongly-held opinion
that using "ref" as a performance tool is almost never going to be useful
in a real-world scenario. If it does help, then it's because there's
something more fundamentally wrong about your design or implementation.

'nuff said. :)

Pete
Jul 3 '08 #29

P: n/a
On Jul 3, 8:42*am, "Michel Walsh"
<vanderghastArobaseMsnDot...@nospam.comwrote:
"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."

That is true, but not THE point.
Thanks Michel Walsh! "That is true..."; I take that as a sort of
newbie moral victory of sorts, kinda, sorta.
If your client lives, say, in Dallas, then,
when you want to reach it, you look where? in Dallas, no! if you are in
Seattle, you look at your cardfile holding your clients addresses. Now, if
one of your buddy (procedure), living in New York, ask to contact the said
client, you have two options: make a copy of your cardfile and 'pass' it to
him, that is 'by value', or you cant 'rent' him, for a while, your cardfile,
that will be 'passed by reference'. In both case, your New York buddy can
reach your client, in Dallas, and he can change your client to a not-client
anymore, quite permanently, sure, but, and there is a but, in the last case,
it can do much more, he can screw your cardfile too. And NEVER you *ever
"passed" (ouch) the client it-self to your buddy.
So are you saying 'pass-by-value' is like 'constant' in C++ (which to
my newbie knowledge C# lacks) in that you can safely pass an object to
a function so it cannot be manipulated to change the original? If so,
please let me know how to do that, since honestly once I learned C# I
have yet to find how you can make a function/method take a 'read only'
copy of a class (not a primitive type, but of a class). In fact,
Googling this confirmed this fact (see below). So I don't see how
pass-by-value is any 'safer' (or read-only) than 'pass-by-value' for a
class passed.

RL

Googling on 'const', note the **** text ****--RL

The const keyword only applies to variables, which MSDN calls
fields. A field with the const keyword indicates that the field
cannot be changed. The value of the field must be initialized in the
declaration. Interestingly, attributes cannot be declared as const,
and furthermore, attributes referring to const fields can only have
getters, not setters.

****In C++, the const keyword was also used to indicate that the
method did not modify any variables:****
void Foo() const;

****or that the method returned a reference that could not be
modified:****
const int& Foo();

or that the parameter being passed as a reference could not be
modified by the method:
void Foo(const int& i);

which could lead to some ridiculous but valid statements:
const int& Foo(const int& i) const;

Happily, C# treats the keyword const with only one meaning.

Declaring fields as const protects both you and other programmers from
accidentally changing the value of the field. Also note that with
const fields, the compiler performs some optimization by not declaring
any stack space for the field.

Furthermore, const can only be applied to intrinsic types. You cant
say:
const HasConstField hcf2=new HasConstField();
Jul 3 '08 #30

P: n/a
On Jul 3, 10:13*am, "Peter Duniho" <NpOeStPe...@nnowslpianmk.com>
wrote:
They are _not_ "doing EXACTLY the same thing". *The C# version is passing *
the address of a variable that contains a reference to an object, while *
the C version is passing the address of a variable that contains the *
object itself.
That's pretty slick, and you have to acknowledge that people coming
from a non-managed, non-automatic garbage collected, non-Intermediate
language background like C or C++ (classic version) might not grasp
this subtitety, PD.
>
You remind me of the people who continue to cling to the idea that Iraq *
had something to do with the 9/11 attacks and that Hussein was hiding *
weapons of mass destruction somewhere in his country, in spite of *
absolutely no evidence in support of those ideas and in spite of volumes *
of evidence to the contrary.
Well, if you define chemical weapons as "WMD" then arguably S. Hussein
had this capability, or he did have this capability, or he could
quickly acquire this capability, though your point is understood. And
let's not get politics involved, shall we? We're trying to keep this a
flame free and troll free thread.

In other words, you've decided on your dogma and no amount of actual facts *
will have any effect on your beliefs.

That's an unfortunate characteristic for any human being, but it's *
especially problematic for someone in a field like programming. *Computers *
don't adjust themselves to accommodate your way of thinking. *No matter*
how much you wish for C to have pass by reference, and no matter how much*
you wish for C#'s pass by value to be the same as C#'s pass by reference,*
it simply will not be.
We can will it away, Nietzsche style. Remember, F. Nietzsche did not
believe there was one objective "TRUTH" out there, but many points of
view. Put another way: if a competent scientist publishes a paper on
evolution that is correct in terms of received wisdom, but privately
believes in Creationism, does that make his paper unacceptable? No.
And if this poster believes that C and C#.NET pass-by-reference the
same way, which they don't according to your world view, but writes
code that works, is that unacceptable? Probably not unless you are
teaching or writing a paper on C. Sci theory. In short, William
James '19th century pragmatism' as it applies to philosophy probably
overrules whatever 'objective' objections you might have to the
posters 'wrong' world view. In short, whatever works, works,
regardless of the 'Truth' of the matter.

RL

[C# troll who makes occasionally incisive comments MVP]
Jul 3 '08 #31

P: n/a
Jon wrote:
Hilton 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.
So, if I understand you correctly, the determination of "pass by value" or
"pass by reference" is based on syntax and not functionality (here I mean
what actually gets passed etc). Please see my code below:

Where exactly are the benefits of using the inaccurate terminology?
None, I don't like to.
OK, back to basics and as simple as I can make it. Let use the C# code:

void Go ()
{
int x = 10;

Method (ref x);
}

void Method (ref int y)
{
y = 20;
}

I am claiming that this is exactly the same as the C code that has "Method
(&x)" (caller) and "Method (int *py)" (callee). All that is happening is
that the compiler is hiding the 'ugliness' from you, so that when you write
"y=20" (above), it really does a "*py= 20". So IMHO, it is just some
language/compiler smoke and mirrors, the *same thing* is happening under the
covers. But don't take my word for it, let's look at the IL:

The Caller IL is:

..method private hidebysig instance void Go() cil managed
{
// Code size 12 (0xc)
.maxstack 2
.locals init ([0] int32 x)
IL_0000: ldc.i4.s 10
IL_0002: stloc.0
IL_0003: ldarg.0
IL_0004: ldloca.s x
IL_0006: call instance void Test.Class1::Method(int32&)
IL_000b: ret
} // end of method Class1::Go

Kinda curious that Microsoft label the call as "int32&", anyway... This is
why I mentioned "ldloca.s" in an earlier post - according to Microsoft's
documentation, this "Loads the address of the local variable at a specific
index onto the evaluation stack, short form." So it is passing the address
of "x", exactly the same as our C code. Now, let's look at the Callee IL:

..method private hidebysig instance void Method(int32& y) cil managed
{
// Code size 5 (0x5)
.maxstack 2
IL_0000: ldarg.1
IL_0001: ldc.i4.s 20
IL_0003: stind.i4
IL_0004: ret
} // end of method Class1::Method

Again, I have to smile at the "&" in the first line. According to
Microsoft's documentation, stind.i4 "Stores a value of type int32 at a
supplied address." which is exactly the same (functionally) as the C code's
"*py = 20".

So, here we have C# and C code, the IL, Microsoft documentation, and I have
(hopefully) shown that the code is functionality exactly the same (by this I
mean what gets passed/received/used).

Jon, is this C# code "pass by value" or "pass by reference"? By your
earlier claims, the C code is "pass by value". So either:

1. The C# is "pass by value" in which case "ref" does not mean "pass by
reference", or
2. The C# code is "pass by reference" even though exactly the same as its C
counterpart, just a different syntax, or
3. The whole "pass by value/reference" claim is a syntactic claim and not a
functional/performance claim.

Hilton
Jul 3 '08 #32

P: n/a
I don't see it as the same thing, no, since my New York buddy CAN still
write over the cardfile, a copy, I sent him (for whatever reason he may have
to write over it, such as re-using the cardfile to store another address).
The safeguard is that doing so, he won't destroy MY cardfile content.
Vanderghast, Access MVP

"raylopez99" <ra********@yahoo.comwrote in message
news:44**********************************@k13g2000 hse.googlegroups.com...
On Jul 3, 8:42 am, "Michel Walsh"
<vanderghastArobaseMsnDot...@nospam.comwrote:

(...)
So are you saying 'pass-by-value' is like 'constant' in C++ (which to
my newbie knowledge C# lacks) in that you can safely pass an object to
a function so it cannot be manipulated to change the original?
(...)
Jul 3 '08 #33

P: n/a
On Thu, 03 Jul 2008 13:19:29 -0700, Hilton <no****@nospam.comwrote:
[...]
So, if I understand you correctly, the determination of "pass by value"
or
"pass by reference" is based on syntax and not functionality (here I mean
what actually gets passed etc).
It's based on what the language itself supports.

You can write C code that has the same effect as lambda expressions in
C#. That doesn't mean C supports lambda expressions.
[...]
Jon, is this C# code "pass by value" or "pass by reference"?
The C# code is clearly "by reference".
By your earlier claims, the C code is "pass by value".
Yes. Since C doesn't support "by reference", it would have to be.
So either:

1. The C# is "pass by value" in which case "ref" does not mean "pass by
reference", or
Nope.
2. The C# code is "pass by reference" even though exactly the same as
its C
counterpart, just a different syntax, or
It's not "exactly the same". There are important differences between the
two that you are ignoring.
3. The whole "pass by value/reference" claim is a syntactic claim and
not a
functional/performance claim.
It is a critically important description of how the _language_ works.
Just because you can get the compiled result to accomplish the same thing,
that doesn't mean that the _language_ concepts are the same.

Pete
Jul 3 '08 #34

P: n/a
Peter Duniho wrote:
Hilton wrote:
>2. The C# code is "pass by reference" even though exactly the same as
its C
counterpart, just a different syntax, or

It's not "exactly the same". There are important differences between the
two that you are ignoring.
They both pass an address, they both store 20 to the memory pointed to by
that address. What important differences am I ignoring?

>3. The whole "pass by value/reference" claim is a syntactic claim and
not a
functional/performance claim.

It is a critically important description of how the _language_ works.
Just because you can get the compiled result to accomplish the same thing,
that doesn't mean that the _language_ concepts are the same.
They don't simply accomplish the same thing, they are doing the same thing.
Does the fact that you keep going back to the language (and its syntax) mean
that you agree with me that this is all about syntax? Probably not. :)

Again, two pieces of code doing the same thing yet one is pass-by-value, the
other is pass-by-reference? (as you confirmed)

If we're talking about how it 'looks' (i.e. syntax), then I agree with you
and Jon (as I stated before). But to me, the whole concept is not the
pretty smoke and mirrors on the surface, but what is actually happening -
that's why I posted the code, IL etc.

Hilton
Jul 3 '08 #35

P: n/a
On Thu, 03 Jul 2008 14:29:06 -0700, Hilton <no****@nospam.comwrote:
>>2. The C# code is "pass by reference" even though exactly the same as
its C
counterpart, just a different syntax, or

It's not "exactly the same". There are important differences between
the
two that you are ignoring.

They both pass an address, they both store 20 to the memory pointed to by
that address. What important differences am I ignoring?
Well, for one, how the parameter can be used in the called method. As Jon
points out, when it's passed by value, the method can then change that
value locally. When it's passed by reference, the method cannot change
the reference; it can only change the thing that is referenced.
[...]
>It is a critically important description of how the _language_ works.
Just because you can get the compiled result to accomplish the same
thing,
that doesn't mean that the _language_ concepts are the same.

They don't simply accomplish the same thing, they are doing the same
thing.
No, they are not. Again, you are arbitrarily ignoring important
differences.
Does the fact that you keep going back to the language (and its syntax)
mean
that you agree with me that this is all about syntax? Probably not. :)
I don't even see why that's important. In truth, there's a real semantic
difference here. But even if it were just about syntax, does that justify
you insisting on refusing to accept the standard definitions used by every
well-informed, well-educated programmer?
Again, two pieces of code doing the same thing yet one is pass-by-value,
the
other is pass-by-reference? (as you confirmed)
The code you posted accomplishes the same thing. That doesn't mean that
the two situations are exactly the same.
If we're talking about how it 'looks' (i.e. syntax), then I agree with
you
and Jon (as I stated before).
We're not. There are fundamental differences in the way the parameters
are used when you have a language that actually supports passing "by
reference", as compared to a language that does not.

That said, I'm done trying to help you understand. Every time you think
you've come up with an example that illustrates why things are the same,
we point out why the example is wrong. You either ignore those points
altogether (and why not? why bother to listen to any fact that conflicts
with your own view?), or you come up with some new example that is
similarly flawed (repeating the cycle).

You obviously aren't interested in learning something new. You reject
anything that confronts your own pre-established beliefs, and frankly, I
find religious debates pointless.

At least for the time being, this thread has sufficient content to avoid
any naïve reader thinking that you actually know what you're talking
about, and that's good enough for me. As I said, I don't really care what
_you_ believe...I just don't want anyone else thinking you're right. I'm
sure that goal has been accomplished.

Pete
Jul 3 '08 #36

P: n/a
Hilton <no****@nospam.comwrote:
It's not "exactly the same". There are important differences between the
two that you are ignoring.

They both pass an address, they both store 20 to the memory pointed to by
that address. What important differences am I ignoring?
The fact that the type of the parameter in the C version is a pointer
type, as is the argument - whereas in the C# version the type is just a
normal type. The fact that in the C version you could pass in any
pointer, including NULL - and treat it just like any other pointer,
beyond just dereferecing it to change the original variable's value.
3. The whole "pass by value/reference" claim is a syntactic claim and
not a
functional/performance claim.
It is a critically important description of how the _language_ works.
Just because you can get the compiled result to accomplish the same thing,
that doesn't mean that the _language_ concepts are the same.

They don't simply accomplish the same thing, they are doing the same thing.
Does the fact that you keep going back to the language (and its syntax) mean
that you agree with me that this is all about syntax? Probably not. :)
Not syntax, language definitions.
Again, two pieces of code doing the same thing yet one is pass-by-value, the
other is pass-by-reference? (as you confirmed)
They are achieving the same effect. In Java you can achieve a similar
effect by creating a single-element array, passing that (to a method
which has to take an array of the right type) and then changing that
element within the method.

Would you call that workaround "pass by reference" as well, just
because it can achieve the same eventual effect?
If we're talking about how it 'looks' (i.e. syntax), then I agree with you
and Jon (as I stated before). But to me, the whole concept is not the
pretty smoke and mirrors on the surface, but what is actually happening -
that's why I posted the code, IL etc.
It's not just syntax, it's the behaviour which is defined by the
language specification.

--
Jon Skeet - <sk***@pobox.com>
Web site: http://www.pobox.com/~skeet
Blog: http://www.msmvps.com/jon_skeet
C# in Depth: http://csharpindepth.com
Jul 3 '08 #37

P: n/a
Hilton wrote:
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).
It is important to use standard terminology.

You could design the foobar language where you define that:
7 * 3 is 4
* is the add operator
but noone will be able to understand what is going on, because
+-* and add subtract multiply has meanings.

The terms pass by value and pass by reference has meanings as
well.

Use them instead of creating confusion with your own definitions.

Arne
Jul 3 '08 #38

P: n/a
raylopez99 wrote:
Remember the rules of Ray then: for optimal performance, use Ref.
Not. You use ref or not ref based on what fits the problem, not what
you think may perform best (and there are no guarantee that ref will
perform best).

Arne
Jul 3 '08 #39

P: n/a
Peter wrote:
We're not. There are fundamental differences in the way the parameters
are used when you have a language that actually supports passing "by
reference", as compared to a language that does not.

That said, I'm done trying to help you understand. Every time you think
you've come up with an example that illustrates why things are the same,
we point out why the example is wrong. You either ignore those points
altogether (and why not? why bother to listen to any fact that conflicts
with your own view?), or you come up with some new example that is
similarly flawed (repeating the cycle).

You obviously aren't interested in learning something new. You reject
anything that confronts your own pre-established beliefs, and frankly, I
find religious debates pointless.

At least for the time being, this thread has sufficient content to avoid
any nave reader thinking that you actually know what you're talking
about, and that's good enough for me. As I said, I don't really care what
_you_ believe...I just don't want anyone else thinking you're right. I'm
sure that goal has been accomplished.
Just to beat a dead horse and debunk your usual "Hilton's own view" opinion,
I did a quick search and found stuff on multiple university web sites and in
books teaching/showing "pass by reference" using C - here are some links,
but "pass by reference" using C is in many many many places:

http://www.youtube.com/watch?v=Dw76YHFQjaw (note the title)
http://www.cs.princeton.edu/~lworthi...s_val_ref.html - "With
pointers, we can pass the values 'by reference.' Passing by reference means
that we'll pass the addresses of the variables instead of the values."

It's silly getting all heated up about these discussions. Again, your view
(which is consistent with Jon and many others) is that it is how it looks
and works from the source code point of view - fine, I have no problem with
that. But to me (and many others), that is mostly academic, what concerns
me is what is actually happening - i.e. is the entire array or just a
pointer/reference to the array being passed.

Having said that, I understand your frustration with another point of view.
I don't like hearing the media say that a plane stalled when its engine
stopped. Although we can blame the Wright brothers for this one. :)

Hilton
Jul 3 '08 #40

P: n/a
On Thu, 03 Jul 2008 15:55:36 -0700, Hilton <no****@nospam.comwrote:
Just to beat a dead horse and debunk your usual "Hilton's own view"
opinion,
I did a quick search and found stuff on multiple university web sites
and in
books teaching/showing "pass by reference" using C
No one disputes that the same mistake is made by people other than you.
Showing other examples of the same mistake doesn't change anything, since
it's not the goal here to show that you are unique in making the mistake.
[...]
It's silly getting all heated up about these discussions. Again, your
view
(which is consistent with Jon and many others) is that it is how it looks
and works from the source code point of view - fine, I have no problem
with
that. But to me (and many others), that is mostly academic, what
concerns
me is what is actually happening - i.e. is the entire array or just a
pointer/reference to the array being passed.
Well, first of all, as has been pointed out over and over, this isn't just
a situation of exactly equivalent behaviors. There are in fact
differences between what you claim to be "by reference" and what is
actually "by reference".

But secondly, regardless of what might or might not be valid in other
contexts, the definitions of "by value" and "by reference" as regards to
parameter passing are very specific and well-defined for C#. This is a C#
newsgroup. There is absolutely no excuse whatsoever to _intentionally_
misuse those terms in this context.
Having said that, I understand your frustration with another point of
view.
I don't like hearing the media say that a plane stalled when its engine
stopped.
It boggles my mind that you can understand the problem with people
misusing terminology, and yet can insist that it's acceptable for _you_ to
intentionally misuse terminology. I've seen people being hypocritical
before, but they aren't usually willing to actually _admit_ to it.

Pete
Jul 3 '08 #41

P: n/a
"Peter Duniho" <Np*********@nnowslpianmk.comwrote in message
news:op***************@petes-computer.local...
On Thu, 03 Jul 2008 11:55:13 -0700, raylopez99 <ra********@yahoo.com>
wrote:

And to Steve: I _strongly_ recommend you use Google Groups to review
previous discussions and posts by Ray. You should take everything you
read on the Internet with a grain of salt anyway, but in this case you can
make a decision for yourself as to what advice is likely to be correct,
useful, etc. by examining previous contributions and seeing if they look
like they were written by someone you'd consider reliable.
It's like you're inside my head...
;-)

- Steve
Jul 4 '08 #42

P: n/a
On Jul 3, 11:55*pm, "Hilton" <nos...@nospam.comwrote:
It's silly getting all heated up about these discussions.
No, I don't believe it is. I've seen the results of people being loose
with terminology: other people get confused. If you say that reference
types are pased by reference by default, people who understand the
true meaning of pass by reference *will* get confused. I've seen it
happen in groups time and time again.
>*Again, your view
(which is consistent with Jon and many others) is that it is how it looks
and works from the source code point of view
Not just from the source code point of view - from the *language*
point of view. It's how the language defines the behaviour.
- fine, I have no problem with
that. *But to me (and many others), that is mostly academic, what concerns
me is what is actually happening - i.e. is the entire array or just a
pointer/reference to the array being passed.
But the beauty of the accurate way of talking about things is that it
not only gets "what is actually happening" right, but it gives a
consistent view across the whole language. It also has the benefit of
being right by the specification :)

If we can't convince you that the inaccurate terminology is worth
avoiding just for the sake of correctness and avoiding confusing
others, perhaps I can present a different reason: your terminology
just won't stand up in the face of some odd situations. Consider this
code:

using System;
using System.Text;

struct Foo
{
public int x;
public StringBuilder sb;

public Foo(int x)
{
this.x = x;
sb = new StringBuilder();
}
}

class Test
{
static void Main()
{
Foo f = new Foo(5);
Method(f);
Console.WriteLine(f.x);
Console.WriteLine(f.sb);
}

static void Method(Foo foo)
{
foo.x = 10;
foo.sb.Append("Hi");
}
}

The result is 5 and then "Hi". The accurate view copes with this very
simply - when Method is called, f is passed by value - a copy is made
of both fields, one of which is a reference. The change to foo.x in
Method is therefore only made to the copy - but the references foo.sb
and f.sb are identical - they refer to the same object, so changes
made to that object (not to the sb variable itself) are still visible
after the call.

Now, I don't believe you'll be able to explain that in your overly
simplistic view of pass by value vs pass by reference - at least not
without making it pretty convoluted. At some point you'll have to come
back to the fact that sb isn't an object, it's a reference. When
you've gone that far, the next logical step is to look at exactly what
gets passed when you *just* have a StringBuilder.

In short, using the accurate terminology has these benefits:
1) It avoids confusing people
2) It's consistent across all situations
3) It agrees with the spec, which is meant to be our means of
communicating

Which of these benefits can you deny? If you don't deny them, why do
you ignore them? What benefit does your terminology have over them?

Jon
Jul 4 '08 #43

P: n/a
On Jul 3, 3:55*pm, "Hilton" <nos...@nospam.comwrote:>
It's silly getting all heated up about these discussions. *Again, your view
(which is consistent with Jon and many others) is that it is how it looks
and works from the source code point of view - fine, I have no problem with
that. *But to me (and many others), that is mostly academic, what concerns
me is what is actually happening - i.e. is the entire array or just a
pointer/reference to the array being passed.
I think it's the pointer/reference to the array, since it's faster.
Like you say, or so it seems, "behind the scenes" the effect is the
same. But, Jon, Arne and Pete are correct because we deal with the
source code, not the IL stuff 'behind the scenes'.

Put another way: 'behind the scenes' you can, at the machine code
level, say that C and C++ and Pascal and Visual Basic are "all the
same", because the microprocessor uses op codes in 1's and 0's that
push, pop, fetch, etc, instructions and data 'the same way'. But that
distinction blurs the real differences between the languages.

RL
Jul 4 '08 #44

P: n/a
On Jul 3, 12:03*pm, "Peter Duniho" <NpOeStPe...@nnowslpianmk.com>
wrote:
>
And to Steve: I _strongly_ recommend you use Google Groups to review *
previous discussions and posts by Ray. *You should take everything you *
read on the Internet with a grain of salt anyway, but in this case you can *
make a decision for yourself as to what advice is likely to be correct, *
useful, etc. by examining previous contributions and seeing if they look *
like they were written by someone you'd consider reliable.
No, you can also look at the code I post you blowhard.
>
And for what it's worth, the same thing is true for any of the rest of *
us. *You shouldn't accept any of our statements without at least some *
critical consideration, and I'm not going to try to convince you that Jon, *
I, or anyone else is more or less reliable than someone else. *
That's right, you're slightly more reliable than me, but I back up my
stuff with code and you just rely on your authoritative sounding
posts.

You can *
make an informed decision yourself just by looking at past contributions *
to the newsgroup.
Right. And I deliver. I even have posted stuff on depthwise
traversed n-ary trees that I've never seen before on the net. BTW,
the library of C# sucks when it comes to trees--really primitive, I
don't think they even have a black-red binary balanced tree, last I
checked.

RL
Jul 4 '08 #45

P: n/a
On Jul 3, 2:33*pm, "Hilton" <nos...@nospam.comwrote:
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 passby
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.
Where the difference is really visible is when you use C++/CLI:

void TakesObjectReferenceByValue(Object^ reference);
void TakesObjectReferenceByReference(Object^% reference);

Note that C++/CLI explicitly spells out the "reference to .." part of
an object reference type as "^" - only they call it a "handle" there.
On the other hand, to declare a by-reference parameter, you use "%",
which is called a "reference" there. It is really unfortunate that C#
designers chose to overload the term "reference" for both object
references and byref arguments. Also, I think that, if the nature of
object references would be explicitly spelt out in the code (as in C++/
CLI), it would make it easier to wrap one's head around the concept of
"passing an object reference by reference".

This distinciton is visible all the way down to CLI level, by the way.
The canonical terms there are: "reference" for an object reference,
and "managed pointer" for what is "ref" in C# and "%" in C++/CLI.

It is conventional, therefore, to only say that an argument is "passed
by reference" if the actual type of the argument is a CLI managed
pointer; otherwise, it is "passed by value".

In a plain C++ context, by the way, the same distinction exists. A
method taking a pointer to int is usually spoken of as "taking a
pointer by value". A method taking a reference, on the other hand, is
"taking an integer by reference":

void TakesIntPointerByValue(int* p);
void TakesIntByReference(int& p);
void TakesIntPointerByReference(int*&p );
Jul 4 '08 #46

P: n/a
On Fri, 04 Jul 2008 02:44:08 -0700, raylopez99 <ra********@yahoo.com>
wrote:
>And to Steve: I _strongly_ recommend you use Google Groups to review *
previous discussions and posts by Ray. *You should take everything you *
read on the Internet with a grain of salt anyway, but in this case you
can *
make a decision for yourself as to what advice is likely to be correct,
*
useful, etc. by examining previous contributions and seeing if they
look *
like they were written by someone you'd consider reliable.

No, you can also look at the code I post you blowhard.
Methinks thou doth protest too much.

First, your "previous contributions" include everything you posted,
including code.

Second, there's nothing insulting at all about what I wrote if your
previous posts are indicative of a reliable source. I even made the same
recommendation regarding everyone else's contributions, including my own.
Assuming your posts are uniformly useful and accurate, what is there for
you to get upset about?

If you're concerned that your reliability will be more questionable when
someone takes the time to look at what you've posted in the past, that's
not my fault. Your anger is misdirected (not to mention revealing).

Pete
Jul 4 '08 #47

P: n/a
On Jul 4, 9:35*am, "Peter Duniho" <NpOeStPe...@nnowslpianmk.com>
wrote:
>*Your anger is misdirected (not to mention revealing).
I'm just flaming you, that's all.

BTW I think Pavel Minaev got the better of you, essentially pointing
out that in C++ (CLI) the distinction that Hilton makes is explictly
present in C++.net. But, this being a C# forum, perhaps you and Jon
make good points. It's all over my head anyway. After learning C, C++,
C++.NET (CLI) and now C#.NET it's all a blur, especially the way C#
deals with inhereitance --much more primitive than C++, and I barely
figured out the difference between ref and non-ref (pass by value)
just recently. This thread was good as a refresher. ANd see my other
thread why C# is flawed because you cannot pass an object using, as in
C++, a 'const' keyword to prevent it from being modified. How
primitive is that? I guess you have to be super careful in C# and not
depend on the compiler to save you.

RL
Jul 4 '08 #48

P: n/a
On Fri, 04 Jul 2008 16:25:23 -0700, raylopez99 <ra********@yahoo.com>
wrote:
On Jul 4, 9:35*am, "Peter Duniho" <NpOeStPe...@nnowslpianmk.com>
wrote:
>*Your anger is misdirected (not to mention revealing).

I'm just flaming you, that's all.
As I said.
BTW I think Pavel Minaev got the better of you, essentially pointing
out that in C++ (CLI) the distinction that Hilton makes is explictly
present in C++.net.
That's funny. Considering that the issue here is the _lack_ of
distinction that Hilton makes, and that Pavel's post is simply reinforcing
what the rest of us have been explaining.

"The better of me"? Uh, right. I welcome Pavel's contribution, and don't
feel it reflected poorly on me at all.
But, this being a C# forum, perhaps you and Jon
make good points. It's all over my head anyway. After learning C, C++,
C++.NET (CLI) and now C#.NET it's all a blur, especially the way C#
deals with inhereitance --much more primitive than C++,
Again, proving your lack of expertise in C#. Inheritance in C# is
different than in C++, yes. But "more primitive"? Hardly.
and I barely
figured out the difference between ref and non-ref (pass by value)
just recently. This thread was good as a refresher. ANd see my other
thread why C# is flawed because you cannot pass an object using, as in
C++, a 'const' keyword to prevent it from being modified.
It doesn't prevent something from being modified in C++ either.

More importantly, a much better way to ensure that a data structure isn't
modified is simply to make that data structure immutable. For example,
the String class is essentially "const" all the time. Works great.

The lack of "const" for methods or their parameters doesn't make C# any
more flawed than any of the other languages people use on a daily basis.
It just makes it different from one of them.

If having "const" methods and parameters was such an important feature,
everyone would use C++ and no one would use C#, Java, VB, etc. Odd, then,
that so many people find languages other than C++ preferable, or at the
very least, just as useful.
How
primitive is that? I guess you have to be super careful in C# and not
depend on the compiler to save you.
You can guess that all you like. The rest of us will go on knowing better.

Of course, if you hate C# so much, I am bewildered as to why you continue
using it. I suppose it's the troll in you.

Pete
Jul 4 '08 #49

P: n/a
Hilton <no****@nospam.comwrote:
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 <Li*************@hot.mail.comwrote:
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 that's what they were taught, then yes.

Perhaps a shift to another language and some examples will help.

Pascal

program example;

var myArg: integer;

(* the parameter j is passed by reference, it has type "integer" *)
procedure showit(var j: integer);
begin
myArg = 42;
(* j has a value of 42 *)
end;

begin
showit(myArg);
end.
C

int myValue;
int myValue2;
int* myArg;

/* parameter j is passed by value, w/type of "int *" aka pointer to int */
showit (int* j) {
j = &myValue2;
*j = 3;
/* j now points to myValue2, the value of *j is 3 */
/* myArg STILL points to myValue, the value of *myArg is still 42 */
}
main()
{
myValue = 42;
myValue2 = 2;
myArg = &myValue;
showit(myArg);
}

Do you see the difference? When the parameter is a reference parameter
then changes to the parameter are changes to the argument. In C,
changes to the parameter never has an effect on the argument.

--
J.B. Moreno
Jul 5 '08 #50

65 Replies

This discussion thread is closed

Replies have been disabled for this discussion.