c# passing objects as method parameters??

A

Andy

Hi

Could someone clarify for me the method parameter passing
concept?

As I understand it, if you pass a variable without
the "ref" syntax then it gets passed as a copy.

If you pass a variable with the "ref" syntax then it gets
passed as a reference to the object and any changes to
the variable will be reflected in the calling method.

What happens with objects??? For example if I pass a
SqlConnection object from one method to another do I need
to ensure I use the "ref" syntax or are objects dealt
with differently to variables???

Thanks in advance

Andy
 
M

Marina

For objects, a copy of the *reference* gets passed - not a copy of the
object.

Meaning, that the copy of the references you have, can be changed, without
modifying the original one.

So:

public void MyFunc(SqlConnection conn)

{
conn = null;
}

Sets the copy to null. However, the original SqlConnection reference that
you passed in here is still pointing to what it was. However:

public void MyFunc(ref SqlConnection conn)

{
conn = null;
}

There is no copy passed in - the actual reference is passed. Thus setting it
to null, will set the original one to null as well (they are one and the
same).
 
R

Rob Windsor

Hi Andy,

You do not NEED to use the ref keyword when passing objects as parameters,
and under most circumstances you won't. When you pass an object as a
parameter a copy of the reference is passed to the method so you can still
access the properties and methods of the object.

Now, let's examine the case where the method changes the object that the
parameter references (e.g. the method creates a new SqlConnection and has
the parameter reference it). If you do not use "ref" the method will use the
newly created object but the variable that the caller passed in to the
parameter will remain unchanged and continue to reference the original
object. If you do use "ref" then the method will use the newly created
object AND the variable that the caller passed in to the parameter will also
reference this newly created object.
 
R

Richard Grimes [MVP]

Andy said:
Hi

Could someone clarify for me the method parameter passing
concept?

As I understand it, if you pass a variable without
the "ref" syntax then it gets passed as a copy.

If you pass a variable with the "ref" syntax then it gets
passed as a reference to the object and any changes to
the variable will be reflected in the calling method.

What happens with objects??? For example if I pass a
SqlConnection object from one method to another do I need
to ensure I use the "ref" syntax or are objects dealt
with differently to variables???

Thanks in advance

Andy

*All* object parameters are passed by reference. By default all value type
(struct, integers, real numbers, enums) are passed by value. When a
parameter is passed by value a copy of the type is put on the stack and the
method has access to the copy, not the original. This means that if you
change the parameter passed by value in the method, the original is not
affected.

void f(int i)
{
i = 4; // no effect on original item
}

int j = 10;
f(j); // j is not affected

When a parameter is passed by reference (all object parameters, and 'ref'
for a value type) a reference is passed, in effect this is like a pointer
pointing to the actual item. In C# the passed-by-reference item is accessed
just like a pass-by-value item, which I think is a bad thing, in managed C++
a value type passed by reference is passed as a managed pointer and hence it
is clearer what is happening. If the method changes a value in the item
(for example, a field in a struct passed by reference, or a member of an
object) then the original item is changed.

void f(ref int i)
{
i = 4; // original item is changed
}

int j = 10;
f(ref j); // j now has a value of 4

class T { public int x = 10; }
void g(T t)
{
t.x = 42; // original is affected
}

T o = new T(); // o.x is 10
g(o); // o.x is now 42

However, if you change the actual parameter value to refer to another
object, the original is unaffected because you are merely changing the stack
frame, which no longer exists when the method returns. Using the T class:

// t is a copy of the reference to the object on the stack frame
void h(T t)
{
// change the reference to another object
t = new T();
} // stack frame destroyed, so new reference is destroyed too

T o = new T();
o.x = 99;
h(o); // o is unaffected

If you want to affect the reference to an object in the original stack frame
you need to use the ref keyword. Instead of a copy to the reference to the
object (which is the case without ref) you know have a reference to a
reference to the object (in C++ a pointer to a pointer to an object), so if
you change the item referred to by the parameter the original reference to
the object is changed. In C~ you don't see this de-referencing, but you have
to explicitly do this in managed C++.

For example:

class U
{
public string s;
public U(string str) {s = str;}
}

void q(ref U u)
{
Console.WriteLine("passed " + u.s);
u = new U("second"); // replace the original reference with a reference to
this new object
}

U u = new U("first"); // create an object, and pass a reference to q()
Console.WriteLine("created as " + u.s);
q(ref u); // when this returns u is the object created in q()
Console.WriteLine("changed to " + u.s);

Here, you can pass an object to q() and q() will change that object to
another one. You are more likely to want to have an object returned through
the parameter, without passing a reference into the method. To do this use
'out' rather than 'ref'

void p(out U u)
{
u = new U("second"); // replace the original reference with a reference to
this new object
}

U u; // not initialized
p(out u); // when this returns u is the object created in p()
Console.WriteLine("changed to " + u.s);

Richard
 
J

Jon Skeet

*All* object parameters are passed by reference.

No, they're not. Objects aren't passed at all. References (the values
of reference-type expressions) are passed by value.

References being passed by value is *not* the same as objects being
passed by reference. I view terminology like this as very important to
get right.

See http://www.pobox.com/~skeet/csharp/parameters.html for a more
detailed explanation.
 

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