A question about passing an object by reference

A

Abe Frohnman

Hello all,

I'm passing a reference to a class into the constructor of a form, like
so: public MyForm(int count, ref Area myArea) {...}

How can I use myArea outside the constructor? Should I create another
Area and assign myArea to it (ie: Area foo = myArea;) or is there a
better way?

~AF
 
B

Bruno Jouhier [MVP]

Here is how I would write it:

private int _count;
private Area _myArea;

public MyForm(int count, Area myArea) { _count = count; _myArea =
myArea; }

// Now, you can use _myArea in any method, like:
public void DoSomethingWithMyArea() { _myArea.DoSomething(); }

Note: You do not need the ref keyword in the constructor because objects are
always passed "by reference" in C#. So, with the code above (no ref
keyword), _myArea and myArea point to the same object, which is probably
what you want.

The ref keyword really means in/out. It means that the caller passes one
object and receives a different object when the call completes (so, you are
not passing a reference to the object, but rather a reference to a reference
(*) ). It is only useful when a method needs to return several results.

(*) This is a slight simplification of the real picture because in C# the
assignment of the new value is done by the caller rather than by the callee
(so that you can pass a property with a pair of r/w accessors), so if you
use the ref keyword, the value is copied to a temporary variable before the
call, the callee receives the address of the temporary variable, the callee
writes its new value to the temporary variable, and then the caller assigns
the temporary variable to the argument (which must be a valid target for
assignment) after the call completes.

Bruno.
 
J

Jon Skeet

Bruno Jouhier said:
Note: You do not need the ref keyword in the constructor because objects are
always passed "by reference" in C#.

No they're not. References are passed by value. I know it may be easier
to say this than to explain it fully, but I think it does harm in the
end.

To the OP: see http://www.pobox.com/~skeet/csharp/parameters.html for a
full discussion about what "passing by reference" really means, and
what C# does.
 
A

Abe Frohnman

Hmm...so C# passes objects differently than C++ does? I know that if you
don't explicitly tell a C++ function/method that the object is going to
be passed in by reference, it gets passed in by value. So just to ensure
that I'm understanding this correctly, whenever I pass an object into a
function/method it'll >always< be passed in by reference? And any
changes I make to that object in the method will affect the object
outside of that method?

AF
 
J

Jon Skeet

Abe Frohnman said:
Hmm...so C# passes objects differently than C++ does? I know that if you
don't explicitly tell a C++ function/method that the object is going to
be passed in by reference, it gets passed in by value. So just to ensure
that I'm understanding this correctly, whenever I pass an object into a
function/method it'll >always< be passed in by reference? And any
changes I make to that object in the method will affect the object
outside of that method?

You never pass a reference type object at all - you only pass a
reference, and that reference is passed by value. Any change to the
object referred to is also seen via the reference outside the method -
there's only one actual object involved.

See http://www.pobox.com/~skeet/csharp/parameters.html for more
information.
 
J

Jon Skeet

Abe Frohnman said:
Right, right. Sorry I've not yet had my morning coffee. :) Let me
rephrase that: In C#, objects are passed by reference automatically.

No, objects are never passed. References to objects are passed by
value. This is different to objects being passed by reference.
No need to use the 'ref' keyword in front of them?

That really depends on exactly what you want to do.
So if I have a class that takes a reference to an object in its
constructor, what's the best way to use that reference later in the class?

ie: MyForm(myClass foo) {...}

should the constructor do something like: this.foo = foo; or is there a
better way?

Assuming it has a foo field, then yes, that's perfectly okay.
 
A

Andre

hehe, I suggest you have another cup of coffee :) You keep saying the
same thing...

lemme give it a try this time
In C#, objects are passed by reference automatically. No
need to use the 'ref' keyword in front of them?

Objects aren't passed.. objects are on the heap.. if you have something
like :

MyClass foo = new MyClass();

You instantiate an object which is then stored in the heap.. the
reference-type variable 'foo' is stored on the stack and holds the
reference to this object. when you pass this variable onto a method like:

MyForm f = new MyForm(MyClass foo2)

you actually pass the value of foo (which is the reference to the actual
object in the heap) to foo2.. foo2 is then stored on the stack with the
passed reference as its value which was 'copied' accross. Now, foo and
foo2 both have access to the heap-allocated object. If foo2 were to
change the object in some way, foo will be able to see the change -
however, since foo2 is another variable on the stack, making changes to
foo2 itself will not affect foo. Consider this:

MyForm(MyClass foo2) {

foo2 = new MyClass();

// foo2, above, now holds a reference to a newly allocated object
// foo, however, was not affected
}


-Andre
 
J

Jon Skeet

Ming Chen said:
I'm not getting the context of the discussion. Here is just what I think
about your questions.
Generally speaking, ValueTypes are passed by value, while Reference types
are passed by reference by default.

No they are not. With reference types, the reference is passed by
value, which is a different thing to passing by reference.
See http://www.pobox.com/~skeet/csharp/parameters.html (again!)
For value types, it makes a lot sense to pass them by ref. Cause that's the
only way to change the parameter object value in a function.
For reference types, it still gives some bonus to pass them by ref.

.... which suggests that you *must* be wrong above, as if they are
passed by reference to start with, how could passing them by reference
give them some bonus?
 
B

Bruno Jouhier [MVP]

Jon,

You are right. The reference is passed by value, which is different from
passing by reference. I went back to my reference book on the subject (The
study of programming language -- Ryan Stansifer) and it confirms what you
say and what you write in your HTML document (and what the .NET
documentation says).

But rather than say, "no" when people says that objects are passed by
reference, I think that you should say "almost" or "not quite", because they
don't always grasp the difference between "passed by reference" and
"reference passed by value", and then, they get confused.

The most important point, as far as objects are concerned, is that the
reference is being passed around, and that the objects are never copied. So,
people don't need to use the "ref" keyword most of the time when they pass
an object because the reference is passed anyway (by value). The "ref"
keyword is only useful if they want the method to "return" a result (another
reference) through the parameter, which is not the usual case.

Bruno.
 
J

Jon Skeet

Bruno Jouhier said:
You are right. The reference is passed by value, which is different from
passing by reference. I went back to my reference book on the subject (The
study of programming language -- Ryan Stansifer) and it confirms what you
say and what you write in your HTML document (and what the .NET
documentation says).

But rather than say, "no" when people says that objects are passed by
reference, I think that you should say "almost" or "not quite", because they
don't always grasp the difference between "passed by reference" and
"reference passed by value", and then, they get confused.

To be fair, I *always* now give the URL to the more detailed
explanation. I'm trying to make the point that it really is quite a
sharp distinction in theoretical terms, even if a lot of the time they
end up having similar effects.
The most important point, as far as objects are concerned, is that the
reference is being passed around, and that the objects are never copied. So,
people don't need to use the "ref" keyword most of the time when they pass
an object because the reference is passed anyway (by value). The "ref"
keyword is only useful if they want the method to "return" a result (another
reference) through the parameter, which is not the usual case.

Indeed. And the fact that people *think* that they want to pass things
by reference when actually they want to pass a reference by value shows
how close things are in people's minds. By posting "almost" or "not
quite" there's an implication (IMO) that they really *are* quite close
together, whereas I'm trying to stress how different they are.

I'll think about it a bit more though, and maybe a bit less harsh :)
 
A

Andre

Ming said:
I'm not getting the context of the discussion. Here is just what I think
about your questions.
Generally speaking, ValueTypes are passed by value, while Reference types
are passed by reference by default.

No.. that's politically (and logically) incorrect. Reference types are
passed by value.. since reference type vars hold the reference to the
object, their reference is copied accross.


-Andre
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top