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

Passing reference type as method parameter

P: n/a
Hi!

A have a string variable (which is a reference type).
Now I define my Method like that:

void MakeFullName(string sNamePrivate)
{
sNamePrivate+="Gates"
}

The calling code:
string sName="Bill";
MakeFullName(sName);

My variable sName wasn't changed (the same "Bill"). String is a
reference type and I would expect
that it will be passed by reference without defining the method
parameter as "ref". Only after defining it as "ref" I get the expected
result ("BillGates").
void MakeFullName1(ref string sNamePrivate)
{
sNamePrivate+="Gates"
}

The calling code:
string sName="Bill";
MakeFullName1(ref sName);

In the following article Jesse Liberty explicitly says, that reference
parameters are passed by reference:
http://www.ondotnet.com/pub/a/dotnet...ps.html?page=2

"Value types are passed to methods by value (a copy is made) while
reference types are effectively passed by reference."

Does it mean, that unless I declare my paramter as "ref" my value
outside the mehtod is never changed?

Thanks for you help.

Maxim

Nov 17 '05 #1
Share this Question
Share on Google+
13 Replies


P: n/a
Hi Maxim,

I think it means that unless you explicitly declare otherwise (by using
"ref"), then assume that
you're passing all parameters by value.

Anyone please correct me if I am wrong.

Cheers!

"Maxim" <ma*********@gmail.com> wrote in message
news:11**********************@g49g2000cwa.googlegr oups.com...
Hi!

A have a string variable (which is a reference type).
Now I define my Method like that:

void MakeFullName(string sNamePrivate)
{
sNamePrivate+="Gates"
}

The calling code:
string sName="Bill";
MakeFullName(sName);

My variable sName wasn't changed (the same "Bill"). String is a
reference type and I would expect
that it will be passed by reference without defining the method
parameter as "ref". Only after defining it as "ref" I get the expected
result ("BillGates").
void MakeFullName1(ref string sNamePrivate)
{
sNamePrivate+="Gates"
}

The calling code:
string sName="Bill";
MakeFullName1(ref sName);

In the following article Jesse Liberty explicitly says, that reference
parameters are passed by reference:
http://www.ondotnet.com/pub/a/dotnet...ps.html?page=2

"Value types are passed to methods by value (a copy is made) while
reference types are effectively passed by reference."

Does it mean, that unless I declare my paramter as "ref" my value
outside the mehtod is never changed?

Thanks for you help.

Maxim

Nov 17 '05 #2

P: n/a
Hi Maxim,
you chose an unfortunate example for your testing. A string is a
reference type object but it has value type semantics, meaning a string is
immutable. If you change a string i.e you try to append, or change any part
of the string, then what is really happening is that you make a copy of the
entire string.

Classes are usually reference types, so in the example below the Person
instance is automatically passed by reference without the ref keyword:

class Person
{
private string _name;

public Person(string name)
{
_name = name;
}

public string Name
{
get
{
return _name;
}
set
{
_name = value;
}
}
}

public static void Main(string[] args)
{
Person p = new Person("mark");
ChangePersonName(p);

//this will print "new name"
Console.WriteLine(p.Name);
}

public static void ChangePersonName(Person p)
{
p.Name = "new name";
}
In your example I would change the MakeFullName function return a string as
the result.

The ref keyword is only required when you want to pass value types like
references, which in my opinion is usually not desirable as it makes code not
as readable. You do not need the ref keyword to pass normal reference types
by reference, this will happen automatically.

Also beware that structs are value types not reference types :-)

Hope that helps
Mark R Dawson

"Maxim" wrote:
Hi!

A have a string variable (which is a reference type).
Now I define my Method like that:

void MakeFullName(string sNamePrivate)
{
sNamePrivate+="Gates"
}

The calling code:
string sName="Bill";
MakeFullName(sName);

My variable sName wasn't changed (the same "Bill"). String is a
reference type and I would expect
that it will be passed by reference without defining the method
parameter as "ref". Only after defining it as "ref" I get the expected
result ("BillGates").
void MakeFullName1(ref string sNamePrivate)
{
sNamePrivate+="Gates"
}

The calling code:
string sName="Bill";
MakeFullName1(ref sName);

In the following article Jesse Liberty explicitly says, that reference
parameters are passed by reference:
http://www.ondotnet.com/pub/a/dotnet...ps.html?page=2

"Value types are passed to methods by value (a copy is made) while
reference types are effectively passed by reference."

Does it mean, that unless I declare my paramter as "ref" my value
outside the mehtod is never changed?

Thanks for you help.

Maxim

Nov 17 '05 #3

P: n/a
if you add the "ref" keyword to a reference type, you in fact pass a
reference to a reference. kind of like a pointer to a pointer in C.
without the ref, when you added the last name, you reassined
sNamePrivate to a new string, instead of what it was. with it, you
reassigned the original variable.

Nov 17 '05 #4

P: n/a
Try calling with the ref token before sName like this: MakeFullName(ref
sName);

class objects are automatically passed by reference. (the heap)
strings, structures etc. are passed by value. (the stack)

:-)

"Maxim" <ma*********@gmail.com> wrote in message
news:11**********************@g49g2000cwa.googlegr oups.com...
Hi!

A have a string variable (which is a reference type).
Now I define my Method like that:

void MakeFullName(string sNamePrivate)
{
sNamePrivate+="Gates"
}

The calling code:
string sName="Bill";
MakeFullName(sName);

My variable sName wasn't changed (the same "Bill"). String is a
reference type and I would expect
that it will be passed by reference without defining the method
parameter as "ref". Only after defining it as "ref" I get the expected
result ("BillGates").
void MakeFullName1(ref string sNamePrivate)
{
sNamePrivate+="Gates"
}

The calling code:
string sName="Bill";
MakeFullName1(ref sName);

In the following article Jesse Liberty explicitly says, that reference
parameters are passed by reference:
http://www.ondotnet.com/pub/a/dotnet...ps.html?page=2

"Value types are passed to methods by value (a copy is made) while
reference types are effectively passed by reference."

Does it mean, that unless I declare my paramter as "ref" my value
outside the mehtod is never changed?

Thanks for you help.

Maxim

Nov 17 '05 #5

P: n/a
Value types are passed by value i.e. int's doubles etc, reference types are
passed by reference and do not require the ref keyword to be passed by
reference this is the default behaviour.

The ref keyword is used to allow you to pass value types by reference or to
pass a reference to a reference type.

"AdamM" wrote:
Hi Maxim,

I think it means that unless you explicitly declare otherwise (by using
"ref"), then assume that
you're passing all parameters by value.

Anyone please correct me if I am wrong.

Cheers!

"Maxim" <ma*********@gmail.com> wrote in message
news:11**********************@g49g2000cwa.googlegr oups.com...
Hi!

A have a string variable (which is a reference type).
Now I define my Method like that:

void MakeFullName(string sNamePrivate)
{
sNamePrivate+="Gates"
}

The calling code:
string sName="Bill";
MakeFullName(sName);

My variable sName wasn't changed (the same "Bill"). String is a
reference type and I would expect
that it will be passed by reference without defining the method
parameter as "ref". Only after defining it as "ref" I get the expected
result ("BillGates").
void MakeFullName1(ref string sNamePrivate)
{
sNamePrivate+="Gates"
}

The calling code:
string sName="Bill";
MakeFullName1(ref sName);

In the following article Jesse Liberty explicitly says, that reference
parameters are passed by reference:
http://www.ondotnet.com/pub/a/dotnet...ps.html?page=2

"Value types are passed to methods by value (a copy is made) while
reference types are effectively passed by reference."

Does it mean, that unless I declare my paramter as "ref" my value
outside the mehtod is never changed?

Thanks for you help.

Maxim


Nov 17 '05 #6

P: n/a
By default all parameters in C# are passed by value. This is a very
subtle
concept in that the _variable_ to a reference type is passed by value,
not the
object. A copy of the variable goes on the stack. When the method
returns,
the variable is cleared off the stack. You can touch the actual object
from
within the method using the copy of the variable and IF the object is
mutable,
you can change the state of the object and this change will persist when
the
method returns. Unfortunately, in your example, you used an immutable
object. The local copy of the variable is assigned to a new immutable
string
and then the copy is cleaned off the stack. To prove the subtle
difference
between _effective_ pass by reference and true pass by reference, you
only
need to write a swap routine. The swap routine does not work as you
would
expect if C# supported true pass by refererence by default. To write a
swap
routine in C# you need to use the ref keyword.

This topic has been a source of great confusion to C++ coders, so I will
elaborate. If you want to write a swap routine then you need to add
another
degree of indirection to the method call. You can do this by use the
keyword
ref. Here is some sample code that demonstrates the concept. The swap
routine only works if you pass a reference to a concrete Drawable object
by
reference.

using System;
namespace TestSwap
{
abstract class Drawable
{
abstract public void DrawMe();
}
class Circle : Drawable
{
public override void DrawMe()
{
System.Console.WriteLine("Circle");
}
}
class Square : Drawable
{
public override void DrawMe()
{
System.Console.WriteLine("Square");
}
}
/// <summary>
/// Summary description for Class1.
/// </summary>
class Class1
{
static public void SwapByValue(Drawable d1, Drawable d2)
{
Drawable temp= d1;
d1 = d2;
d2= temp;
}
static public void SwapByRef(ref Drawable d1, ref
Drawable d2)
{
Drawable temp= d1;
d1 = d2;
d2= temp;
}
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main(string[] args)
{
//
// TODO: Add code to start application here
//
Drawable wasCircle= new Circle();
Drawable wasSquare= new Square();
wasCircle.DrawMe(); // outputs Circle
wasSquare.DrawMe(); // outputs Square
SwapByValue(wasCircle, wasSquare); // fails
wasCircle.DrawMe(); // outputs Circle
wasSquare.DrawMe(); // outputs Square
SwapByRef(ref wasCircle, ref wasSquare); //
succeeds
wasCircle.DrawMe(); // outputs Square
wasSquare.DrawMe(); // outputs Circle
System.Console.ReadLine();
}
}
}

Regards,
Jeff

*** Sent via Developersdex http://www.developersdex.com ***
Nov 17 '05 #7

P: n/a
So to be clear. If this was a _mutable_ string class that you had
authored and in
the body of the method you called sName.append("Gates"), on exit the
calling
code sName variable would refer to an object with the content
"BillGates". This is
due to the fact that both variables refer to the same single object. If
you
reassign the local copy of the variable sName to a new object, the
calling sName
variable would still point to the original object with content "Bill".
When the
method returned, the local object with the content "BillGates" would
most likely
be eligible for garbage collection.

Regards,
Jeff

*** Sent via Developersdex http://www.developersdex.com ***
Nov 17 '05 #8

P: n/a
Ok. Thank you for your all help.
Now I understand my problem: String is immutable sequence of characters
and cosequently me returned the new instance. Changing the string to
muttable StringBuilder also gives desired result:

public void MakeFullNameEx(StringBuilder sNamePrivate)
{
sNamePrivate.Append("Gates");
}

StringBuilder sNameEx = new StringBuilder("Bill");
tst.MakeFullNameEx(sNameEx);
Console.WriteLine(sNameEx);

Output: BillGates
Mark R. Dawson wrote:
Hi Maxim,
you chose an unfortunate example for your testing. A string is a
reference type object but it has value type semantics, meaning a string is
immutable. If you change a string i.e you try to append, or change any part
of the string, then what is really happening is that you make a copy of the
entire string.

Classes are usually reference types, so in the example below the Person
instance is automatically passed by reference without the ref keyword:

class Person
{
private string _name;

public Person(string name)
{
_name = name;
}

public string Name
{
get
{
return _name;
}
set
{
_name = value;
}
}
}

public static void Main(string[] args)
{
Person p = new Person("mark");
ChangePersonName(p);

//this will print "new name"
Console.WriteLine(p.Name);
}

public static void ChangePersonName(Person p)
{
p.Name = "new name";
}
In your example I would change the MakeFullName function return a string as
the result.

The ref keyword is only required when you want to pass value types like
references, which in my opinion is usually not desirable as it makes code not
as readable. You do not need the ref keyword to pass normal reference types
by reference, this will happen automatically.

Also beware that structs are value types not reference types :-)

Hope that helps
Mark R Dawson

"Maxim" wrote:
Hi!

A have a string variable (which is a reference type).
Now I define my Method like that:

void MakeFullName(string sNamePrivate)
{
sNamePrivate+="Gates"
}

The calling code:
string sName="Bill";
MakeFullName(sName);

My variable sName wasn't changed (the same "Bill"). String is a
reference type and I would expect
that it will be passed by reference without defining the method
parameter as "ref". Only after defining it as "ref" I get the expected
result ("BillGates").
void MakeFullName1(ref string sNamePrivate)
{
sNamePrivate+="Gates"
}

The calling code:
string sName="Bill";
MakeFullName1(ref sName);

In the following article Jesse Liberty explicitly says, that reference
parameters are passed by reference:
http://www.ondotnet.com/pub/a/dotnet...ps.html?page=2

"Value types are passed to methods by value (a copy is made) while
reference types are effectively passed by reference."

Does it mean, that unless I declare my paramter as "ref" my value
outside the mehtod is never changed?

Thanks for you help.

Maxim


Nov 17 '05 #9

P: n/a
"Mark R. Dawson" wrote:
Hi Maxim,
you chose an unfortunate example for your testing. A string is a
reference type object but it has value type semantics, meaning a string is
immutable.


I never understood why people keep making this false claim. a string has
absolutely no value type semantics what-so-ever. and value type semantic
does not mean immutability, because value types are totally mutable. the
only time a value type becomes immutable is when it's boxed, and ironically
at which point, it ceased to be a value type.

a string acts exactly like how any other reference types work, with one
exception, it's immutable.
Nov 17 '05 #10

P: n/a
you are absolutely correct.

what gets most people confused is that passing a variable "by value" or "by
reference" has nothing to do with variable being a value type or reference
type.

you can pass a value type by value, pass a value type by reference, pass a
reference type by value or pass a reference type by reference. and without
"ref" keyword (or "out") everything is passed by value.

for more information, check out Jon Skeet's little article
http://www.yoda.arachsys.com/csharp/parameters.html

"AdamM" wrote:
Hi Maxim,

I think it means that unless you explicitly declare otherwise (by using
"ref"), then assume that
you're passing all parameters by value.

Anyone please correct me if I am wrong.

Cheers!

"Maxim" <ma*********@gmail.com> wrote in message
news:11**********************@g49g2000cwa.googlegr oups.com...
Hi!

A have a string variable (which is a reference type).
Now I define my Method like that:

void MakeFullName(string sNamePrivate)
{
sNamePrivate+="Gates"
}

The calling code:
string sName="Bill";
MakeFullName(sName);

My variable sName wasn't changed (the same "Bill"). String is a
reference type and I would expect
that it will be passed by reference without defining the method
parameter as "ref". Only after defining it as "ref" I get the expected
result ("BillGates").
void MakeFullName1(ref string sNamePrivate)
{
sNamePrivate+="Gates"
}

The calling code:
string sName="Bill";
MakeFullName1(ref sName);

In the following article Jesse Liberty explicitly says, that reference
parameters are passed by reference:
http://www.ondotnet.com/pub/a/dotnet...ps.html?page=2

"Value types are passed to methods by value (a copy is made) while
reference types are effectively passed by reference."

Does it mean, that unless I declare my paramter as "ref" my value
outside the mehtod is never changed?

Thanks for you help.

Maxim


Nov 17 '05 #11

P: n/a
Charlieee <ch*******@newsgroup.nospam> wrote:
class objects are automatically passed by reference. (the heap)
strings, structures etc. are passed by value. (the stack)


This is wrong. Everything is passed by value by default, and
System.Strings are reference types.

See <http://www.yoda.arachsys.com/csharp/parameters.html> and
<http://www.yoda.arachsys.com/csharp/strings.html>.
Nov 17 '05 #12

P: n/a
Mark,

Can I refer you to Jon Skeet's article referenced by anoth poster?
"Mark R. Dawson" <Ma*********@discussions.microsoft.com> wrote in message
news:65**********************************@microsof t.com...
Value types are passed by value i.e. int's doubles etc, reference types
are
passed by reference and do not require the ref keyword to be passed by
reference this is the default behaviour.

The ref keyword is used to allow you to pass value types by reference or
to
pass a reference to a reference type.

Nov 17 '05 #13

P: n/a
Mark,

Reference types are passed by value. Passing a reference type by reference
is something quite different.

Can I refer you to Jon Skeet's excellent article referenced by another
poster:

http://www.yoda.arachsys.com/csharp/parameters.html

There's enough confusion on this topic without spreading further
misunderstanding. Jesse Liberty's article doesn't help by saying
"effectively passed by reference", which is what confused the OP.

---
Nigel Norris

"Mark R. Dawson" <Ma*********@discussions.microsoft.com> wrote in message
news:65**********************************@microsof t.com...
Value types are passed by value i.e. int's doubles etc, reference types
are
passed by reference and do not require the ref keyword to be passed by
reference this is the default behaviour.

The ref keyword is used to allow you to pass value types by reference or
to
pass a reference to a reference type.

Nov 17 '05 #14

This discussion thread is closed

Replies have been disabled for this discussion.