473,750 Members | 2,253 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Passing arguements by reference

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
12 2683
"Andrew Bullock" <an************ *********@ANDnt lworldTHIS.com> wrote in message
news:oI******** ***********@new sfe4-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
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
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 ConsoleApplicat ion19
{
class Program
{
static void Main(string[] args)
{
// Value Type Examples
int j = 1;
AddOne(j);

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

int k = 1;
AddOne(ref k);

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

Console.ReadLin e();
}

/// <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(Per son 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
> <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(Per son 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
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(Per son 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
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
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

"Andrew Bullock" <an************ *********@ANDnt lworldTHIS.com> wrote in message
news:m0******** ***********@new sfe2-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(Per son 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.WriteLi ne("Original") ;
Console.WriteLi ne(" foo1.bar:{0}", foo1.Bar);
Console.WriteLi ne(" foo2.bar:{0}", foo2.Bar);
Console.WriteLi ne(" foo3.bar:{0}", foo3.Bar);

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

ChangeFoo(ref foo1);
Console.WriteLi ne("After ChangeFoo");
Console.WriteLi ne(" foo1.bar:{0}", foo1.Bar);
Console.WriteLi ne(" foo2.bar:{0}", foo2.Bar);
Console.WriteLi ne(" 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:Sponge bob
foo2.bar:Sponge bob
foo3.bar:Sponge bob
After ChangeBar
foo1.bar:Patric k
foo2.bar:Patric k
foo3.bar:Patric k
After ChangeFoo
foo1.bar:Squidw ard
foo2.bar:Patric k
foo3.bar:Patric k

Hope this helps
Bill

Feb 26 '06 #9
Andrew Bullock <an************ *********@ANDnt lworldTHIS.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.co m>
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

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

9
1658
by: Randell D. | last post by:
Folks, I have created a function that accepts a dynamic number of arguements and while it works, I'm wondering if I am passing it data in a correct format... I call the function as so myFunction($myArray, a, b ,c);
58
10170
by: jr | last post by:
Sorry for this very dumb question, but I've clearly got a long way to go! Can someone please help me pass an array into a function. Here's a starting point. void TheMainFunc() { // Body of code... TCHAR myArray; DoStuff(myArray);
3
1755
by: junk | last post by:
Hi, Given the following function:- void foo (char *fmt, ...) { } I know how to use va_start, va_end etc to process the parameters but is there an easy way of passing the parameter list onto another function that also has variable length arguements.
2
3792
by: Balamurukan | last post by:
I have one Interface has one Method namely Showlookup which has one Ref arguement Like (ref object ctrl) I want to pass this as ref Arguement when i call the method. I tried ShowLookup(ref this); It shows an error Like u can not pass this as ref or out parameter Because it is readonly.
8
2117
by: Dennis Myrén | last post by:
I have these tiny classes, implementing an interface through which their method Render ( CosWriter writer ) ; is called. Given a specific context, there are potentially a lot of such objects, each requiring a call to that method to fulfill their purpose. There could be 200, there could be more than 1000. That is a lot of references passed around. It feels heavy. Let us say i changed the signature of the interface method to:
6
5996
by: MSDNAndi | last post by:
Hi, I get the following warning: "Possibly incorrect assignment to local 'oLockObject' which is the argument to a using or lock statement. The Dispose call or unlocking will happen on the original value of the local." My code is: using System; using System.Collections.Generic;
12
5400
by: Mike | last post by:
Consider the following code: """ struct person { char *name; int age; }; typedef struct person* StructType;
7
3305
by: TS | last post by:
I was under the assumption that if you pass an object as a param to a method and inside that method this object is changed, the object will stay changed when returned from the method because the object is a reference type? my code is not proving that. I have a web project i created from a web service that is my object: public class ExcelService : SoapHttpClientProtocol {
2
1819
by: Nike | last post by:
I have a small question w.r.t usage of default arguements in template.. I shall try to elaborate this with an example.. let's say I have some template function , where EntryType is the input for the template fn 1.. and another type where EntryType and lass P1 are both inputs.. case1 (1)template<class EntryType_> i.e void A<EntryType_>::createObject(EntryType::inputIdType inpId_ )..
0
8836
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
9575
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
9394
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
0
9256
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
1
6803
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
4885
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
3322
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
2
2798
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
3
2223
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.