473,397 Members | 2,116 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,397 software developers and data experts.

pass by value vs. by reference question

I'm reading the MS press C# book and there seems to be a contradiction.
Please tell me which one is correct, 1 or 2.
Thanks!
Jeff

1. First it gives the code below saying that it prints 0 then 42.
They say that 42 is printed the second time since the value was wrapped in a
class and therefore became passed by reference.
(sorry for any typos I am a newbie here ;-)

class Application
{
static void Entrance()
{
WrappedInt wi = new WrappedInt();
Console.WriteLine(wi.Number); //This one prints 0
they say...
Pass.Reference(wi);
Console.WriteLine(wi.Number) //And this one
prints 42.
}
}

class WrappedInt
{
public int Number;
}

class Pass
{
public static void Reference(WrappedInt param)
{
param.Number = 42;
}
}

--------------------------------

2. Then it goes on to say that whether it is passed by value or reference,
the original arguement is unchanged unless you use 'ref' or 'out'.
So what gives? Which is correct, 1 or 2? If 2 is correct, then the example
they gave in 1 shouldn't be valid right? I may be missing something you
would find obvious.

Thanks for any explanations!
Nov 16 '05 #1
4 3381
The first one does print 0, and the second does print 42. And both 1 and 2
are technically correct.

Explanation:

The key to this is understanding the difference between a reference type an
a value type.

Anything that you define as a class (like the WrappedInteger class) is a
reference type. That means that in memory, it never really "lives" inside a
variable. Rather, any variables that are of type WrappedInteger, are
"references" (think "pointer" -- not exactly like a C++ pointer, but along
those lines).

So, when you set wi = new WrappedInt();

Whats really happening is that a WrappedInt() object is being created
somewhere in memory, and then a reference (kinda like a pointer) to that
object is being stored in the variable wi.

So if you do this:
WrappedInt wi = new WrappedInt();
WrappedInt wi2 = wi;

wi2 and wi are both referencing (pointing to) the same object instance. So,
if you do this:
wi.Number = 10;
w2.Number = 20;
Console.WriteLine(wi.Number)

You get "20", because wi and w2 are both pointing to exactly the same
location in memory.

Now, in contrast, lets look at a value type. your primitives like
ints/floats/bools (full list in the help) are value types, as is anything
that you define as a struct. That means that when you assign one to the
other it is copied in memory -- it really does "live" in the variable.

So:
int x = 5;

The value 5 is deposited in the memory location for x.

int y = x;
x = 10;

y is 5, and x is a 10.

the 5 is copied from x to y, and it is now a copy -- y is independent of x
so when you change x, it only affects x. This should be very familiar
ground -- its the behavior you would expect when dealing with ints in most
common languages (VB 6, Delphi, etc)

Now, lets look at their example:
when they call Pass.Reference(wi), you are passing the value in wi, which is
really just a pointer to an object in memory. When the code in reference
sets Param.Number:
param.Number = 42;
It is getting the reference (pointer) location from param and runnign out
into memory to access the .Number member. It is accessing the same object
in memory as wi, and setting its Number property = 42, so that set "counts"
inside of Main because you passed a reference type.

So, right now it looks like #1 was right.

Now, why is #2 right?

Well, when you call Pass.Reference(wi), you are passing the reference (the
pointer in wi) to the ReferenceMethod by value. If reference tries to
modify the actual value of the pointer (by assigning it to another object),
it will not affect the variable wi in the calling method.

Here's what I mean:
WrappedInt wi = new WrappedInt();
wi.Number = 5;
Pass.Reference(wi);
Console.WriteLine(wi.Number);
// prints "5"

public class Pass
{
public static void Reference(WrappedInt param)
{
// instead of changing .Number, lets try reassign to a new object
// note the difference: I'm reassining param rather than one
// of its members
param = new WrappedInt()
param.Number = 10;
}
}

On the other hand, if you modify Referenct to accept param as a ref
parameter, and then you pass wi as a ref:
Pass.Reference(ref wi)
Console.WriteLine(wi.Number) will print a 10;

Since you passed wi by reference, the Reference method changed the location
in memory that it was pointing to such that it is pointing to the new object
instance. You now don't have any way to access the WrappedInt object that
you originally created in main, and it will be garbage collected and removed
from memory.
I know that was a really long, somewhat contorted explanation. I hope it
helped.

"z_learning_tester" <so*****@microsoft.com> wrote in message
news:mfpAc.66015$0y.328@attbi_s03...
I'm reading the MS press C# book and there seems to be a contradiction.
Please tell me which one is correct, 1 or 2.
Thanks!
Jeff

1. First it gives the code below saying that it prints 0 then 42.
They say that 42 is printed the second time since the value was wrapped in a class and therefore became passed by reference.
(sorry for any typos I am a newbie here ;-)

class Application
{
static void Entrance()
{
WrappedInt wi = new WrappedInt();
Console.WriteLine(wi.Number); //This one prints 0 they say...
Pass.Reference(wi);
Console.WriteLine(wi.Number) //And this one
prints 42.
}
}

class WrappedInt
{
public int Number;
}

class Pass
{
public static void Reference(WrappedInt param)
{
param.Number = 42;
}
}

--------------------------------

2. Then it goes on to say that whether it is passed by value or reference,
the original arguement is unchanged unless you use 'ref' or 'out'.
So what gives? Which is correct, 1 or 2? If 2 is correct, then the example
they gave in 1 shouldn't be valid right? I may be missing something you
would find obvious.

Thanks for any explanations!

Nov 16 '05 #2
OK, had to read that a *few* times.
But I've got it now.

It really took all of those examples for me to put it together- so thanks
for taking the time!

"J.Marsch" <je****@ctcdeveloper.com> wrote in message
news:eO*************@TK2MSFTNGP09.phx.gbl...
The first one does print 0, and the second does print 42. And both 1 and 2 are technically correct.

Explanation:

The key to this is understanding the difference between a reference type an a value type.

Anything that you define as a class (like the WrappedInteger class) is a
reference type. That means that in memory, it never really "lives" inside a variable. Rather, any variables that are of type WrappedInteger, are
"references" (think "pointer" -- not exactly like a C++ pointer, but along
those lines).

So, when you set wi = new WrappedInt();

Whats really happening is that a WrappedInt() object is being created
somewhere in memory, and then a reference (kinda like a pointer) to that
object is being stored in the variable wi.

So if you do this:
WrappedInt wi = new WrappedInt();
WrappedInt wi2 = wi;

wi2 and wi are both referencing (pointing to) the same object instance. So, if you do this:
wi.Number = 10;
w2.Number = 20;
Console.WriteLine(wi.Number)

You get "20", because wi and w2 are both pointing to exactly the same
location in memory.

Now, in contrast, lets look at a value type. your primitives like
ints/floats/bools (full list in the help) are value types, as is anything
that you define as a struct. That means that when you assign one to the
other it is copied in memory -- it really does "live" in the variable.

So:
int x = 5;

The value 5 is deposited in the memory location for x.

int y = x;
x = 10;

y is 5, and x is a 10.

the 5 is copied from x to y, and it is now a copy -- y is independent of x
so when you change x, it only affects x. This should be very familiar
ground -- its the behavior you would expect when dealing with ints in most
common languages (VB 6, Delphi, etc)

Now, lets look at their example:
when they call Pass.Reference(wi), you are passing the value in wi, which is really just a pointer to an object in memory. When the code in reference
sets Param.Number:
param.Number = 42;
It is getting the reference (pointer) location from param and runnign out
into memory to access the .Number member. It is accessing the same object
in memory as wi, and setting its Number property = 42, so that set "counts" inside of Main because you passed a reference type.

So, right now it looks like #1 was right.

Now, why is #2 right?

Well, when you call Pass.Reference(wi), you are passing the reference (the
pointer in wi) to the ReferenceMethod by value. If reference tries to
modify the actual value of the pointer (by assigning it to another object), it will not affect the variable wi in the calling method.

Here's what I mean:
WrappedInt wi = new WrappedInt();
wi.Number = 5;
Pass.Reference(wi);
Console.WriteLine(wi.Number);
// prints "5"

public class Pass
{
public static void Reference(WrappedInt param)
{
// instead of changing .Number, lets try reassign to a new object
// note the difference: I'm reassining param rather than one
// of its members
param = new WrappedInt()
param.Number = 10;
}
}

On the other hand, if you modify Referenct to accept param as a ref
parameter, and then you pass wi as a ref:
Pass.Reference(ref wi)
Console.WriteLine(wi.Number) will print a 10;

Since you passed wi by reference, the Reference method changed the location in memory that it was pointing to such that it is pointing to the new object instance. You now don't have any way to access the WrappedInt object that
you originally created in main, and it will be garbage collected and removed from memory.
I know that was a really long, somewhat contorted explanation. I hope it
helped.

"z_learning_tester" <so*****@microsoft.com> wrote in message
news:mfpAc.66015$0y.328@attbi_s03...
I'm reading the MS press C# book and there seems to be a contradiction.
Please tell me which one is correct, 1 or 2.
Thanks!
Jeff

1. First it gives the code below saying that it prints 0 then 42.
They say that 42 is printed the second time since the value was wrapped in
a
class and therefore became passed by reference.
(sorry for any typos I am a newbie here ;-)

class Application
{
static void Entrance()
{
WrappedInt wi = new WrappedInt();
Console.WriteLine(wi.Number); //This one
prints 0
they say...
Pass.Reference(wi);
Console.WriteLine(wi.Number) //And this one
prints 42.
}
}

class WrappedInt
{
public int Number;
}

class Pass
{
public static void Reference(WrappedInt param)
{
param.Number = 42;
}
}

--------------------------------

2. Then it goes on to say that whether it is passed by value or

reference, the original arguement is unchanged unless you use 'ref' or 'out'.
So what gives? Which is correct, 1 or 2? If 2 is correct, then the example they gave in 1 shouldn't be valid right? I may be missing something you
would find obvious.

Thanks for any explanations!


Nov 16 '05 #3
z_learning_tester <so*****@microsoft.com> wrote:
I'm reading the MS press C# book and there seems to be a contradiction.
Please tell me which one is correct, 1 or 2.
I would need to see *exactly* what they wrote to say for sure - it's
easy to rewrite it in your own words and end up with mistakes.
2. Then it goes on to say that whether it is passed by value or reference,
the original arguement is unchanged unless you use 'ref' or 'out'.
That's true.
So what gives? Which is correct, 1 or 2? If 2 is correct, then the example
they gave in 1 shouldn't be valid right? I may be missing something you
would find obvious.


What you're missing is that you can change a value within the object
which a variable refers to without changing the value of the variable
itself.

I've written a page trying to explain all this carefully:
http://www.pobox.com/~skeet/csharp/parameters.html

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
Nov 16 '05 #4
Well, I'm glad it helped. I know that it wasn't the most elegant
explanation available.
"John Smith" <so*****@microsoft.com> wrote in message
news:BZ********************@comcast.com...
OK, had to read that a *few* times.
But I've got it now.

It really took all of those examples for me to put it together- so thanks
for taking the time!

"J.Marsch" <je****@ctcdeveloper.com> wrote in message
news:eO*************@TK2MSFTNGP09.phx.gbl...
The first one does print 0, and the second does print 42. And both 1 and
2
are technically correct.

Explanation:

The key to this is understanding the difference between a reference type an
a value type.

Anything that you define as a class (like the WrappedInteger class) is a
reference type. That means that in memory, it never really "lives" inside a
variable. Rather, any variables that are of type WrappedInteger, are
"references" (think "pointer" -- not exactly like a C++ pointer, but
along those lines).

So, when you set wi = new WrappedInt();

Whats really happening is that a WrappedInt() object is being created
somewhere in memory, and then a reference (kinda like a pointer) to that
object is being stored in the variable wi.

So if you do this:
WrappedInt wi = new WrappedInt();
WrappedInt wi2 = wi;

wi2 and wi are both referencing (pointing to) the same object instance.

So,
if you do this:
wi.Number = 10;
w2.Number = 20;
Console.WriteLine(wi.Number)

You get "20", because wi and w2 are both pointing to exactly the same
location in memory.

Now, in contrast, lets look at a value type. your primitives like
ints/floats/bools (full list in the help) are value types, as is anything that you define as a struct. That means that when you assign one to the
other it is copied in memory -- it really does "live" in the variable.

So:
int x = 5;

The value 5 is deposited in the memory location for x.

int y = x;
x = 10;

y is 5, and x is a 10.

the 5 is copied from x to y, and it is now a copy -- y is independent of x so when you change x, it only affects x. This should be very familiar
ground -- its the behavior you would expect when dealing with ints in most common languages (VB 6, Delphi, etc)

Now, lets look at their example:
when they call Pass.Reference(wi), you are passing the value in wi, which is
really just a pointer to an object in memory. When the code in
reference sets Param.Number:
param.Number = 42;
It is getting the reference (pointer) location from param and runnign out into memory to access the .Number member. It is accessing the same object in memory as wi, and setting its Number property = 42, so that set

"counts"
inside of Main because you passed a reference type.

So, right now it looks like #1 was right.

Now, why is #2 right?

Well, when you call Pass.Reference(wi), you are passing the reference (the pointer in wi) to the ReferenceMethod by value. If reference tries to
modify the actual value of the pointer (by assigning it to another

object),
it will not affect the variable wi in the calling method.

Here's what I mean:
WrappedInt wi = new WrappedInt();
wi.Number = 5;
Pass.Reference(wi);
Console.WriteLine(wi.Number);
// prints "5"

public class Pass
{
public static void Reference(WrappedInt param)
{
// instead of changing .Number, lets try reassign to a new object // note the difference: I'm reassining param rather than one
// of its members
param = new WrappedInt()
param.Number = 10;
}
}

On the other hand, if you modify Referenct to accept param as a ref
parameter, and then you pass wi as a ref:
Pass.Reference(ref wi)
Console.WriteLine(wi.Number) will print a 10;

Since you passed wi by reference, the Reference method changed the

location
in memory that it was pointing to such that it is pointing to the new

object
instance. You now don't have any way to access the WrappedInt object that you originally created in main, and it will be garbage collected and

removed
from memory.
I know that was a really long, somewhat contorted explanation. I hope it helped.

"z_learning_tester" <so*****@microsoft.com> wrote in message
news:mfpAc.66015$0y.328@attbi_s03...
I'm reading the MS press C# book and there seems to be a contradiction. Please tell me which one is correct, 1 or 2.
Thanks!
Jeff

1. First it gives the code below saying that it prints 0 then 42.
They say that 42 is printed the second time since the value was wrapped in
a
class and therefore became passed by reference.
(sorry for any typos I am a newbie here ;-)

class Application
{
static void Entrance()
{
WrappedInt wi = new WrappedInt();
Console.WriteLine(wi.Number); //This one

prints
0
they say...
Pass.Reference(wi);
Console.WriteLine(wi.Number) //And this one
prints 42.
}
}

class WrappedInt
{
public int Number;
}

class Pass
{
public static void Reference(WrappedInt param)
{
param.Number = 42;
}
}

--------------------------------

2. Then it goes on to say that whether it is passed by value or

reference, the original arguement is unchanged unless you use 'ref' or 'out'.
So what gives? Which is correct, 1 or 2? If 2 is correct, then the example they gave in 1 shouldn't be valid right? I may be missing something

you would find obvious.

Thanks for any explanations!



Nov 16 '05 #5

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

Similar topics

110
by: Mr A | last post by:
Hi! I've been thinking about passing parameteras using references instead of pointers in order to emphasize that the parameter must be an object. Exemple: void func(Objec& object); //object...
10
by: John Bailo | last post by:
I want to pass a SqlCommand object as a input parameter to a method. I want to pass the SqlCommand "by value" so that any updates to the original object are *not* reflected in the object within...
4
by: Jon Slaughter | last post by:
I'm reading a book on C# and it says there are 4 ways of passing types: 1. Pass value type by value 2. Pass value type by reference 3. Pass reference by value 4. Pass reference by reference. ...
14
by: xdevel | last post by:
Hi, I need your help because I don't understand very well this: in C arguments are passed by-value. The function parameters get a copy of the argument values. But if I pass a pointer what really...
4
by: kinaxx | last post by:
Hello, now I'm learning progamming language in university. but i have some question. in textbook. says there are four passing Mechanism 1) pass by value (inother words : call by value) 2)...
11
by: kinaxx | last post by:
Hello, now I'm learning progamming language in university. but i have some question. in textbook. says there are four passing Mechanism 1) pass by value (inother words : call by value) 2)...
10
by: Robert Dailey | last post by:
Hi, I noticed in Python all function parameters seem to be passed by reference. This means that when I modify the value of a variable of a function, the value of the variable externally from the...
12
by: Bryan Parkoff | last post by:
I write my large project in C++ source code. My C++ source code contains approximate four thousand small functions. Most of them are inline. I define variables and functions in the global scope....
12
by: raylopez99 | last post by:
Keywords: scope resolution, passing classes between parent and child forms, parameter constructor method, normal constructor, default constructor, forward reference, sharing classes between forms....
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
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...
0
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,...
0
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...
0
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...

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.