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

Passing arguements by reference

P: n/a
Hi,

I have two classes, A and B,

B takes an A as an argument in its constructor:
A a1 = new A();
B b = new B(a1);

///

A a2;
public B(A aa)
{
a2 = aa;
}


However, I figured that I could reduce memory usage and increase
performance by passing aa by reference.

How do I alter my code to do this?

I know I need to do this:

public B(ref A aa)

but how do i declare a2? If i leave it as it is, does that mean a1 and
a2 both point to the same memory location, or when assigning a2 is the
object copied?
Thanks

Andrew
Feb 26 '06 #1
Share this Question
Share on Google+
12 Replies


P: n/a
"Andrew Bullock" <an*********************@ANDntlworldTHIS.com> wrote in message
news:oI*******************@newsfe4-gui.ntli.net...
Hi,

I have two classes, A and B,

B takes an A as an argument in its constructor:
A a1 = new A();
B b = new B(a1);

///

A a2;
public B(A aa)
{
a2 = aa;
}


However, I figured that I could reduce memory usage and increase performance by passing aa by
reference.


That would be an incorrect assumption.
In the code above, you are already passing a reference to an A object in to the constructor for B.
In C#, you never directly pass objects as parameter, instead you pass references to objects.
Thus, in class B, you only pay for the cost of a reference.
The net effect is that a1 and a2 in your code both are references to the same A object.

If you don't wish to share the object, then you need to clone it and save the reference to the
clone.
Of course, since you mentioned reducing memory usage, this is obviously not a problem in this case

Hope this helps

Bill

<snip>
Feb 26 '06 #2

P: n/a
However, I figured that I could reduce memory usage and increase performance by passing aa by
reference.


That would be an incorrect assumption.
In the code above, you are already passing a reference to an A object in to the constructor for B.
In C#, you never directly pass objects as parameter, instead you pass references to objects.
Thus, in class B, you only pay for the cost of a reference.
The net effect is that a1 and a2 in your code both are references to the same A object.

If you don't wish to share the object, then you need to clone it and save the reference to the
clone.
Of course, since you mentioned reducing memory usage, this is obviously not a problem in this case

Hope this helps

Bill

<snip>

Hi,

So is the ref keyword just for passing value variables by reference?
Thanks

Andrew
Feb 26 '06 #3

P: n/a
Hi Andrew,
in your example you are already passing the instance of A by reference
even without using the ref keyword. There are a number of ways you can pass
values:

1. Passing a value type by value
2. Passing a value type by reference
3. Passing a reference type by value
4. Passing a reference type by reference

In .Net there are two main types value types and reference types. Value
types are variables which hold the actual value of the item they refer to, so
for example:

int i = 3;

i ------- stored at ------> Memory Address 1234567 which holds value 3

so above really means i is refering to a memory location in which the value
3 is stored.
A reference type is a variable which does not hold the actual data, but
points to a memory location that stores the actual value i.e.

Person p1 = new Person("bob");
Person p2 = p2;

p1 ---stored in ------> Address 12345: contains memory address 67890
p2 ---stored in ------> Address 12134: contains memory address 67890

Memory address 67890 stores the actual data for the Person called Bob.

So even though you have two different variable they are both referencing the
same object.

When you pass value types they by default get copied, so passing an int into
a function causes the value type to be copied and it is the copy of the int
which you are accessing inside the function. If you use the ref keyword on
the int then the copy is not made and a reference to the same int is passed
into the function, for example:

using System;
using System.Text;

namespace ConsoleApplication19
{
class Program
{
static void Main(string[] args)
{
// Value Type Examples
int j = 1;
AddOne(j);

//j will still be 1
Console.WriteLine("passing value by value: j after AddOne=" + j);

int k = 1;
AddOne(ref k);

// k will now be 2
Console.WriteLine("passing value by ref: k after AddOne=" + k);

Console.ReadLine();
}

/// <summary>
/// Passing Value type by value
/// </summary>
static void AddOne(int i)
{
i = i + 1;
}

/// <summary>
/// Passing value type by reference
/// </summary>
static void AddOne(ref int i)
{
i = i + 1;
}
}
}
Now classes are by default reference types, when you pass a reference into
a function as a parameter a copy of the object is not made, but (a subtle
point to note) the reference that refers to the object is copied if the ref
keyword is not used. For example:

void DoSomething(Person q)
{
//Change the name of the person
q.Name = "Frank";

//make q point to nothing
q = null;
}

void Main()
{
Person p = new Person();
p.Name = "Bob";

DoSomething(p);

//at this point p.Name == "Frank"
//and p is not null
}

The variables p and q were still pointing to the same object but when p was
passed to the function a copy of the p variable was made so when we set q to
null we were not setting p to null because they were different variables.

If we want q and p to be the same variable pointing to the same object we
can use the ref keyword on the ref object i.e.

void DoSomething(ref Person q)
{
q.Name = "John";
q = null;
}

void Main()
{
Person p = new Person();
p.Name = "Mark";

DoSomething(ref p);

//here p is null, because of the DoSomething method.
}
Hope that makes some sense.

Mark
http://www.markdawson.org
"Andrew Bullock" wrote:
Hi,

I have two classes, A and B,

B takes an A as an argument in its constructor:
A a1 = new A();
B b = new B(a1);

///

A a2;
public B(A aa)
{
a2 = aa;
}


However, I figured that I could reduce memory usage and increase
performance by passing aa by reference.

How do I alter my code to do this?

I know I need to do this:

public B(ref A aa)

but how do i declare a2? If i leave it as it is, does that mean a1 and
a2 both point to the same memory location, or when assigning a2 is the
object copied?
Thanks

Andrew

Feb 26 '06 #4

P: n/a
> <snip>
Now classes are by default reference types, when you pass a reference into
a function as a parameter a copy of the object is not made, but (a subtle
point to note) the reference that refers to the object is copied if the ref
keyword is not used. For example:

void DoSomething(Person q)
{
//Change the name of the person
q.Name = "Frank";

//make q point to nothing
q = null;
}

void Main()
{
Person p = new Person();
p.Name = "Bob";

DoSomething(p);

//at this point p.Name == "Frank"
//and p is not null
}

The variables p and q were still pointing to the same object but when p was
passed to the function a copy of the p variable was made so when we set q to
null we were not setting p to null because they were different variables.

If we want q and p to be the same variable pointing to the same object we
can use the ref keyword on the ref object i.e.

void DoSomething(ref Person q)
{
q.Name = "John";
q = null;
}

void Main()
{
Person p = new Person();
p.Name = "Mark";

DoSomething(ref p);

//here p is null, because of the DoSomething method.
}

Hi, wow! Thanks alot for that really detailed answer! :-)

I understood everything upto the code above, You say its passed by
reference, but doSomething doesnt change p unless i use "ref"? Surely
that is by value then? :-/

Also, is the above true for everything by reference or just classes?

In this example:
A a1 = new A();
B b = new B(ref a1);

///

A a2;
public B(ref A aa)
{
a2 = aa;
}
Is my declaration of a2 correct? Or does it need to be some kind of
pointer, and how would i declare that?

Thanks Alot,

Andrew :-)
Feb 26 '06 #5

P: n/a
Hi Andrew,
I understood everything upto the code above, You say its passed by
reference, but doSomething doesnt change p unless i use "ref"? Surely
that is by value then? :-/


The subtle point to note is that the underlying object is passed by
reference, hence both p and q pointing to the same object, not to different
object BUT the actual variable which points to the object is copied when you
don't use the ref keyword.

So for example if you don't use the ref keyword then passing a reference
type is like:

void Main()
{
Test t = new Test();
t.Execute();
}

class Test
{
Person p = new Person();
Person q;

void Execute()
{
//p and q point to same object but are
//different variable
q = p;
}

void DoSomething()
{
q.Name = "bob";

//p.Name will now also be bob

q = null;

//p will not be null because q is a copy of the reference to bob.
}
}

so normally q is a parameter of the method DoSomething. When you are using
the ref keyword it is like directly accessing p inside the DoSomething
method, a copy of p is not made first (p not the thing p is pointing to).

So we have two things:
1. The underlying object being pointed to.
2. The thing that points to the object ie Person p;

When using the ref keyword on a reference type you are saying that you don't
want 2 to be be copied into the function.
In .Net classes are reference types, structs are valeu types, primities like
int, float, double etc are value types. If something derives from ValueType
then it should behave like a value type.

Mark
http://www.markdawson.org
"Andrew Bullock" wrote:
> <snip>
Now classes are by default reference types, when you pass a reference into
a function as a parameter a copy of the object is not made, but (a subtle
point to note) the reference that refers to the object is copied if the ref
keyword is not used. For example:

void DoSomething(Person q)
{
//Change the name of the person
q.Name = "Frank";

//make q point to nothing
q = null;
}

void Main()
{
Person p = new Person();
p.Name = "Bob";

DoSomething(p);

//at this point p.Name == "Frank"
//and p is not null
}

The variables p and q were still pointing to the same object but when p was
passed to the function a copy of the p variable was made so when we set q to
null we were not setting p to null because they were different variables.

If we want q and p to be the same variable pointing to the same object we
can use the ref keyword on the ref object i.e.

void DoSomething(ref Person q)
{
q.Name = "John";
q = null;
}

void Main()
{
Person p = new Person();
p.Name = "Mark";

DoSomething(ref p);

//here p is null, because of the DoSomething method.
}

Hi, wow! Thanks alot for that really detailed answer! :-)

I understood everything upto the code above, You say its passed by
reference, but doSomething doesnt change p unless i use "ref"? Surely
that is by value then? :-/

Also, is the above true for everything by reference or just classes?

In this example:
A a1 = new A();
B b = new B(ref a1);

///

A a2;
public B(ref A aa)
{
a2 = aa;
}
Is my declaration of a2 correct? Or does it need to be some kind of
pointer, and how would i declare that?

Thanks Alot,

Andrew :-)

Feb 26 '06 #6

P: n/a
You never pass actual objects, but references to those objects.

When you pass a reference to an object by 'ref', you are passing the actual
reference to the object - this reference can be changed by the method upon
return.

When you pass a reference to an object by value, you are passing a copy of
the reference to the object - this reference cannot be changed by the method
upon return.

For both cases, the method can manipulate and change the internals of the
object, since a reference and a copy of a reference point to the same object.
--
David Anton
www.tangiblesoftwaresolutions.com
Instant C#: VB to C# converter
Instant VB: C# to VB converter
Instant C++: C# to C++ converter & VB to C++ converter
Instant J#: VB to J# converter

"Andrew Bullock" wrote:
Hi,

I have two classes, A and B,

B takes an A as an argument in its constructor:
A a1 = new A();
B b = new B(a1);

///

A a2;
public B(A aa)
{
a2 = aa;
}


However, I figured that I could reduce memory usage and increase
performance by passing aa by reference.

How do I alter my code to do this?

I know I need to do this:

public B(ref A aa)

but how do i declare a2? If i leave it as it is, does that mean a1 and
a2 both point to the same memory location, or when assigning a2 is the
object copied?
Thanks

Andrew

Feb 26 '06 #7

P: n/a
Even if you are so performance-obsessed that you would use 'ref' where not
appropriate, be aware that 'ref' is not necessarily faster since the argument
needs to be passed back. Passing by value creates a trivial copy of the
object reference (not the object remember), but data is only going in one
direction. Depending on where the method resides, passing by 'ref' may or
may not be faster than passing by value.
Regardless, this is really not an area that will generate performance gains
for you. Better to use a performance profiling tool to find the real
bottlenecks.
--
David Anton
www.tangiblesoftwaresolutions.com
Instant C#: VB to C# converter
Instant VB: C# to VB converter
Instant C++: C# to C++ converter & VB to C++ converter
Instant J#: VB to J# converter

"Andrew Bullock" wrote:
Hi,

I have two classes, A and B,

B takes an A as an argument in its constructor:
A a1 = new A();
B b = new B(a1);

///

A a2;
public B(A aa)
{
a2 = aa;
}


However, I figured that I could reduce memory usage and increase
performance by passing aa by reference.

How do I alter my code to do this?

I know I need to do this:

public B(ref A aa)

but how do i declare a2? If i leave it as it is, does that mean a1 and
a2 both point to the same memory location, or when assigning a2 is the
object copied?
Thanks

Andrew

Feb 26 '06 #8

P: n/a

"Andrew Bullock" <an*********************@ANDntlworldTHIS.com> wrote in message
news:m0*******************@newsfe2-win.ntli.net...
<snip>
Hi, wow! Thanks alot for that really detailed answer! :-)

I understood everything upto the code above, You say its passed by reference, but doSomething
doesnt change p unless i use "ref"? Surely that is by value then? :-/


The terms "Pass by reference" and "Pass in a reference" do not mean the same thing.
"Pass by reference" refers to using the ref keyword (out probably qualifies as well)
"Pass in a reference" means to pass in a reference to an object BY VALUE.

Using Marks sample we have

void DoSomething(Person q) // pass in a reference BY VALUE
and
void DoSomething(ref Person q) // pass in a reference BY reference

In the first case you can modify the state of the passed in object.
In the second case you can modify the state of the passed in object AND you can replace the external
object.
It is important to note that in the first case EVERYONE with a reference to that object will see the
change.
In the second case ONLY guy following the ref will be changed.

here is some example code
-----------------------------------------
using System;

public class Test
{
static void Main()
{
Foo foo1 = new Foo("Spongebob");
Foo foo2 = foo1;
Foo foo3 = foo1;
Console.WriteLine("Original");
Console.WriteLine(" foo1.bar:{0}", foo1.Bar);
Console.WriteLine(" foo2.bar:{0}", foo2.Bar);
Console.WriteLine(" foo3.bar:{0}", foo3.Bar);

ChangeBar( foo1);
Console.WriteLine("After ChangeBar");
Console.WriteLine(" foo1.bar:{0}", foo1.Bar);
Console.WriteLine(" foo2.bar:{0}", foo2.Bar);
Console.WriteLine(" foo3.bar:{0}", foo3.Bar);

ChangeFoo(ref foo1);
Console.WriteLine("After ChangeFoo");
Console.WriteLine(" foo1.bar:{0}", foo1.Bar);
Console.WriteLine(" foo2.bar:{0}", foo2.Bar);
Console.WriteLine(" foo3.bar:{0}", foo3.Bar);
}

public static void ChangeFoo(ref Foo foo)
{
foo = new Foo("Squidward");
}

public static void ChangeBar(Foo foo)
{
foo.Bar = "Patrick";
}
}

public class Foo
{
private string bar;
public Foo(string bar)
{
this.bar = bar;
}
public string Bar {get{return bar;} set{bar = value;}}
}

------------------------------------------
Output:
Original
foo1.bar:Spongebob
foo2.bar:Spongebob
foo3.bar:Spongebob
After ChangeBar
foo1.bar:Patrick
foo2.bar:Patrick
foo3.bar:Patrick
After ChangeFoo
foo1.bar:Squidward
foo2.bar:Patrick
foo3.bar:Patrick

Hope this helps
Bill

Feb 26 '06 #9

P: n/a
Andrew Bullock <an*********************@ANDntlworldTHIS.com> wrote:

<snip>
So is the ref keyword just for passing value variables by reference?


No, it's for passing any variable by reference - but there's a
difference between passing a reference by value and passing a reference
variable *by* reference.

See http://www.pobox.com/~skeet/csharp/parameters.html

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too
Feb 27 '06 #10

P: n/a
Mark R. Dawson <Ma*********@discussions.microsoft.com> wrote:
I understood everything upto the code above, You say its passed by
reference, but doSomething doesnt change p unless i use "ref"? Surely
that is by value then? :-/


The subtle point to note is that the underlying object is passed by
reference, hence both p and q pointing to the same object, not to different
object BUT the actual variable which points to the object is copied when you
don't use the ref keyword.


Passing a reference by value *isn't* passing an object by reference.
It's similar, I admit - but there are very specific meanings for the
teams, and they're not the same thing.

(This is compounded by the fact that no expression is actually an
object in C#.)

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too
Feb 27 '06 #11

P: n/a
Thanks everyone for all your advice :)

If i pass an object by reference (using ref keyword) how do i store this
reference for later use: for example:

main()
{
A a1 = new A();
B b = new B(ref a1);
}
///

A a2;
public B(ref A aa)
{
a2 = aa;
}
public doSomethingWithA2()
{
a2.property = value;
}
My question is: Is a2 declared correctly, so that when this line executes:
a2 = aa;
a2 is pointing at the original a1, and doesnt become a copy.

Thanks

Andrew
Feb 27 '06 #12

P: n/a
Andrew Bullock wrote:
Thanks everyone for all your advice :)

If i pass an object by reference (using ref keyword)
You're not passing an object by reference. You're passing a variable by
reference.
You're saying "I want my formal parameter to be the same variable as
the actual parameter".
how do i store this reference for later use


You don't - and once you understand the above, you should be able to
see why. The lifetime of the formal parameter is just the lifetime of
the method.

However, when you're using reference types and the value of a variable
*is* a reference, you rarely need to pass the variable by reference
anyway. Using "ref" should be quite rare.

Jon

Feb 27 '06 #13

This discussion thread is closed

Replies have been disabled for this discussion.