References vs Copies

  • Thread starter Thread starter mehdi_mousavi
  • Start date Start date
M

mehdi_mousavi

Hi folks,
Consider the following line of code:

Address addr = ei.Address;

where ei is an instance of a class that has got a property of Address
type.

The question is that what is happening in the above assignment? Unlike
the C/C++, it seems that the above code instructs the compiler to point
the addr variable to the same location where ei.Address already
resides, i.e, it's somehow a pointer to the ei.Address. Therefore, any
modification on addr variable is instantly applied to the ei.Address.

Well, is this right? or, am I missing something?

Any help would be highly appreciated,
Cheers,
Mehdi
 
Yes, that is exactly what is happening - classes have reference-type
semantics, so your "variable" (address) is preceisly that: a (managed)
pointer to an object on the (managed) heap.

If you want value-type semantics (i.e. instances cloned at the blink of an
eye) then "struct" can be useful, although to be honest an address "feels"
like a class to me. Perhaps look at the ICloneable interface? i.e.

public class Address : ICloneable {
public Address Clone() { // your explicit copy code goes here
}
object ICloneable.Clone() {return this.Clone();} // non-typesafe version
usually done via an explicit implementation
}

then you can call:
Address addr = ei.Address.Clone();
 
Hi,

The question is that what is happening in the above assignment? Unlike
the C/C++, it seems that the above code instructs the compiler to point
the addr variable to the same location where ei.Address already
resides, i.e, it's somehow a pointer to the ei.Address. Therefore, any
modification on addr variable is instantly applied to the ei.Address.

Well, is this right? or, am I missing something?


In managed world it's called reference but yes, that's pretty much what
happens IF Address IS A class ; in your post you especify that ei is an
instance of a class, you say nothing about Address.

If Address is not a class but a struct the above is not true.
 
There are 2 distinct ways to reference data in .Net: By value, and by
reference. This is why the .Net platform defines reference types and value
types. Value types, such as integers and structures, are passed "by value,"
meaning that a copy of the data in the type is passed when an instance of
that type is referenced. Reference types, which constitute most of the .Net
types, are passed "by reference," meaning that a managed pointer to the
instance is passed when an instance of that type is referenced.

To pass a copy of a reference type, the instance must be copied, or Cloned.

--
HTH,

Kevin Spencer
Microsoft MVP
Chicken Salad Surgery

What You Seek Is What You Get.
 
No - value types can be passed by value or by reference and reference types
can be passed by value or by reference.

--
David Anton
www.tangiblesoftwaresolutions.com
Instant C#: VB to C# converter
Instant VB: C# to VB converter
Instant C++: C#/VB to C++ converter
C# Code Metrics: Quick metrics for C#
 
Hi folks,
Consider the following line of code:

Address addr = ei.Address;

where ei is an instance of a class that has got a property of Address
type.

The question is that what is happening in the above assignment? Unlike
the C/C++, it seems that the above code instructs the compiler to point
the addr variable to the same location where ei.Address already
resides, i.e, it's somehow a pointer to the ei.Address. Therefore, any
modification on addr variable is instantly applied to the ei.Address.

Well, is this right? or, am I missing something?

Any help would be highly appreciated,
Cheers,
Mehdi

See http://www.yoda.arachsys.com/csharp/parameters.html
 
"No?" No to what?

If I told you that 1 + 1 = 2, would you say "No - 2 + 0 = 2"?

The fact that 2 statements concerning anything state different things
doesn't imply that one of the 2 statements is wrong.

In fact, the only wrong statement so far has been your "No".

--
HTH,

Kevin Spencer
Microsoft MVP
Chicken Salad Surgery

What You Seek Is What You Get.
 
You had said that value types are passed by value and reference types are
passed by reference. This is the part that is obviously not correct.
To be clear, you could have said that value types *can* be passed by value
and that reference types *can* be passed by reference, but from your post, it
was pretty obvious that this isn't what you intended.
--
David Anton
www.tangiblesoftwaresolutions.com
Instant C#: VB to C# converter
Instant VB: C# to VB converter
Instant C++: C#/VB to C++ converter
C# Code Metrics: Quick metrics for C#
 
mehdi_mousavi said:
Hi folks,
Consider the following line of code:

Address addr = ei.Address;

where ei is an instance of a class that has got a property of Address
type.

The question is that what is happening in the above assignment? Unlike
the C/C++, it seems that the above code instructs the compiler to point
the addr variable to the same location where ei.Address already
resides, i.e, it's somehow a pointer to the ei.Address.

You say "unlike C/C++", but this is not necessarily so. In C, if the
Address field of ei is a pointer, then in fact addr will contain the
same pointer and any modifications to addr->Blah will also change
ei.Address->Blah.

Others here have given good answers, but I wanted to adapt them to your
situation. What will happen in this situation depends upon two things:

1) Whether the type Address is a class or a struct.
2) Whether the Address member of ei is a field, a property that returns
a reference that is part of the state of ei, or a property that returns
a clone of the Address held by ei.

Most here have talked about point #1. Specifically, if the Address type
is a struct--that is, a value type--then assignment and/or returning an
Address from a method implies copying it.

public struct Address
{ ... }

So, if this were the case then changes to the Address held by addr
would not affect the Address held by ei. This is regardless of point #2
above.

If the Address type is a class, then point #2 comes into play: is
ei.Address a field, or is a property. If it's a property, does it
return a reference held by ei or return a clone?

If the Address type is a class and ei.Address is a field:

public class Address
{ ... }

public class EiType
{
public Address Address;
}

then yes, addr will refer to the same object instance as does
ei.Address, and changes to one will be visible when referring to that
same object via the other reference. In effect the "two" will appear to
change in synch, because in reality there's only one.

Similarly, if the field is wrapped in a property that just returns the
object reference, the same applies:

public class Address
{ ... }

public class EiType
{
private Address _address;

public Address Address { get { return this._address; } }
}

However, if ei.Address is a property that returns a clone:

public class Address : ICloneable
{
public override object Clone() { ... }
}

public class EiType
{
private Address _address;

public Address Address { get { return
(Address)this._address.Clone(); } }
}

then the reference assigned to addr will be to a different object
instance than the one held by ei._address, and changes to one will not
be reflected in the other.
 
I intended to say exactly what I said. If I had intended to say otherwise, I
would have. That is why my software works well.

Value types *are* passed by value. Passing them by reference is a (rather
rare) exception (unless the developer is unskilled), and requires
instructions that specify that it should be done that way. Same thing with
reference types, only moreso. I honestly can't think of any time I've tried
to pass a reference type by value. But hey, if it makes you feel superior to
correct people who are not wrong, by all means, do so.

--
HTH,

Kevin Spencer
Microsoft MVP
Chicken Salad Surgery

What You Seek Is What You Get.
 
I think we are just talking about different things.
When I hear the terms "passing by value" and "passing by reference" I
assumed you were talking about passing arguments to methods, but after
reading the initial post more carefully, that's not what you were talking
about (since it's very common to pass a value type by reference or a
reference type by value to a method).
Please accept my humble apologies.
--
David Anton
www.tangiblesoftwaresolutions.com
Instant C#: VB to C# converter
Instant VB: C# to VB converter
Instant C++: C#/VB to C++ converter
C# Code Metrics: Quick metrics for C#
 
From what I remember of passing by reference, a copy of the reference address
is made and sent into a method (i.e., the reference itself is a copy-by-value)

So you should be able to change state in the object passed into a method
via reference, but if you try to assign to another object , you'll lose your
changes.

Right, right? :)
 
Saad Rehmani said:
From what I remember of passing by reference, a copy of the reference address
is made and sent into a method (i.e., the reference itself is a copy-by-value)

So you should be able to change state in the object passed into a method
via reference, but if you try to assign to another object , you'll lose your
changes.

Right, right? :)

Well, what you've described is passing a reference by value. Pass by
reference semantics dictate that changes to the variable used as the
parameter are visible to the caller as changes to the variable used as
the argument.

Now, by "changes to the variable" I mean making the value of the
variable a reference to a different object - changing the contents of
an object doesn't change the value of a variable holding a reference to
that object.

See http://www.pobox.com/~skeet/csharp/parameters.html for more
details.
 
Kevin said:
I intended to say exactly what I said. If I had intended to say otherwise, I
would have. That is why my software works well.

I do not want to use your software then.
There are 2 distinct ways to reference data in .Net: By value, and by
reference. This is why the .Net platform defines reference types and value
types. Value types, such as integers and structures, are passed "by value,"
meaning that a copy of the data in the type is passed when an instance of
that type is referenced. Reference types, which constitute most of the .Net
types, are passed "by reference," meaning that a managed pointer to the
instance is passed when an instance of that type is referenced.
Value types *are* passed by value. Passing them by reference is a (rather
rare) exception (unless the developer is unskilled), and requires
instructions that specify that it should be done that way. Same thing with
reference types, only moreso. I honestly can't think of any time I've tried
to pass a reference type by value. But hey, if it makes you feel superior to
correct people who are not wrong, by all means, do so.

You are wrong.

References are passed by values.

It is possible to pass references by reference by using the ref
keyword just as for value types.

It is to my best knowledge impossible to pass a reference type by
value.

Passing a reference by value mean that:
- you can change the content of the object and the changes
is effective outside the method
- you can not set the reference outside the method to
reference another object (only by using ref)

Arne

PS: I do not in general have a problem with people abbreviating
"reference by value" with "by reference". But please do not
correct people when they point out the difference.
 
Kevin Spencer said:
There are 2 distinct ways to reference data in .Net: By value, and by
reference. This is why the .Net platform defines reference types and value
types. Value types, such as integers and structures, are passed "by value,"
meaning that a copy of the data in the type is passed when an instance of
that type is referenced. Reference types, which constitute most of the .Net
types, are passed "by reference," meaning that a managed pointer to the
instance is passed when an instance of that type is referenced.

Having read the rest of the thread, it's not clear to me exactly what
you mean by "when an instance of that type is referenced".

What I *do* know is that when we're talking about method calls and
*parameters* being passed, both kinds of type are passed by value by
default. To this end, I think it's confusing to talk about reference
types being "passed by reference" in a different context. It certainly
confused me, and appeared to confuse David, so I'm concerned that
others may be confused too...
 
Kevin said:
I intended to say exactly what I said. If I had intended to say otherwise, I
would have. That is why my software works well.

Well, I haven't read your software, but I do read your posts. I, too,
got the impression from your original post that you had made the
classic error of saying that "class instances are passed by reference"
instead of "references to class instances are passed by value". I, like
Arne, understood what you meant to say and didn't bother posting a
correction because it's a fine point likely to be lost on newbies.
Besides, the OP doesn't appear to have been asking about that.
Value types *are* passed by value. Passing them by reference is a (rather
rare) exception (unless the developer is unskilled), and requires
instructions that specify that it should be done that way. Same thing with
reference types, only moreso. I honestly can't think of any time I've tried
to pass a reference type by value.

Ignoring the fact that I have no idea what "Same thing with reference
types, only moreso" could possibly mean, we do pass references by value
all the time: just call a method in .NET and pass a reference to a
class instance without doing anything special. What happens is that a
reference to the instance is passed by value. Anyway, as I said, it's a
fine point not usually worth making. Besides, the macro effect seen by
beginning programmers is that the instance is passed by reference. The
difference between "the instance was passed by reference" and "a
reference to the instance was passed by value" becomes important only
when you start passing references to instances using the "ref" keyword,
which is rare.

Nonetheless, David's correction was accurate, if picky.
But hey, if it makes you feel superior to
correct people who are not wrong, by all means, do so.

Evidently he's not the only one. ;-)
 
I do not want to use your software then.

Oh no! Mr. Bill!

--
;-),

Kevin Spencer
Microsoft MVP
Chicken Salad Surgery

What You Seek Is What You Get.
 
I understand what you're saying, Jon. I didn't want to get into a long
discussion of pointers, which many .Net developers are not very familiar
with. Yes, a reference type is passed by value, but it is the value of the
pointer (the address of the class instance), not the class instance, that is
passed, which effectively means that a reference to the class instance is
passed, since the pointer is simply a variable that represents (points to)
the class instance.

While a value type is (technically) referenced by a pointer as well, the
value of the instance is copied when it is passed, and the new instance
variable does not point to the same instance as the original.

I find it helpful to think of pointers in terms of street addresses and
mailboxes. The pointer is the street address. The mailbox is the class
instance. If you put a letter in the mailbox, it goes in the mailbox,
regardless of the address. When you send a letter to the address of the
mailbox, it may or may not go to the mailbox. It will not go to the mailbox
if the address of the mailbox has changed. For example, if the city renames
the street from "Maple" to "Elm" the address on the mailbox has changed,
although the mailbox itself has not moved. The address that formerly pointed
to the mailbox now points elsewhere, or nowhere at all, if there is no
mailbox at the new address.

--
HTH,

Kevin Spencer
Microsoft MVP
Chicken Salad Surgery

What You Seek Is What You Get.
 
Hi David,

Yes, I think we were misunderstanding one another. And that's likely as much
my fault as yours.

--

Kevin Spencer
Microsoft MVP
Chicken Salad Surgery

What You Seek Is What You Get.
 
I can see how this has become a confusing discussion, as discussions about
pointers often are.
Nonetheless, David's correction was accurate, if picky.


Evidently he's not the only one. ;-)

Hey, my only issue was the use of the word "No" - indicating that what I
said was wrong. If the post had simply clarified a point which I was
apparently not communicating well, I would not have objected. I knew what I
was talking about. Apparently I was misunderstood. Therefore, I have no
issue with David.

And my only objection to the contradiction was that it was indicating that
something true was not true, which is confusing to the other readers.
However, as apparently my own explanation was just as confusing, I am only
happy that perhaps this extended discussion will shed better light on the
topic, for the benefit of others.

I recall that it took me several months (way back when) to really get my
head around the concept of pointers (in C), and that I experienced a number
of headaches in the process. It was, of course, worth the effort. But I am
simply saying that any topic related to pointers is likely to cause some
confusion in a public forum such as this.

--
HTH,

Kevin Spencer
Microsoft MVP
Chicken Salad Surgery

What You Seek Is What You Get.
 
Back
Top