473,378 Members | 1,099 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,378 software developers and data experts.

System.String: It doesn't seem to act like a reference type.

I know that a String is immutable, but I don't understand why this
piece of code fails in nUnit:

// BEGIN CODE

using System;

class Test
{
public static void Main( String[] args )
{

String testField;
testField = "Old Value";

changeString( testField );

Console.WriteLine( testField );

}
private static void changeString( String field )
{

field = "New Value";

}
}
// END CODE

produces the output:
Old Value

As I understand String, I though the output should have been:
New Value

I was under the understanding that Strings, although immutable, were
still reference objects and would be passed by reference to a method.
Can someone tell me how I'm thinking incorrectly?

Nov 16 '05 #1
6 2785
"Chris Simmons" wrote:
I know that a String is immutable, but I don't understand why this
piece of code fails in nUnit:

// BEGIN CODE

using System;

class Test
{
public static void Main( String[] args )
{

String testField;
testField = "Old Value";

changeString( testField );

Console.WriteLine( testField );

}
private static void changeString( String field )
{

field = "New Value";

}
}
// END CODE

produces the output:
Old Value

As I understand String, I though the output should have been:
New Value

I was under the understanding that Strings, although immutable, were
still reference objects and would be passed by reference to a method.
Can someone tell me how I'm thinking incorrectly?


because reference types are NOT passed in by reference. in .NET, pass
something by reference means you declare your parameter with the ref keyword
(or out). in your example, a reference is passed in (rather than a copy),
but you can't change where that reference points to, which is what you are
trying to do with assignment (because strings are immutable).
Nov 16 '05 #2
"Chris Simmons" <ne***************@netchris.com> wrote in message news:11**********************@z14g2000cwz.googlegr oups.com...
I know that a String is immutable, but I don't understand why this
piece of code fails in nUnit:

// BEGIN CODE

using System;

class Test
{
public static void Main( String[] args )
{
String testField;
testField = "Old Value";

changeString( testField );

Console.WriteLine( testField );
}
private static void changeString( String field )
{
field = "New Value";
}
}
// END CODE

produces the output:
Old Value

As I understand String, I though the output should have been:
New Value

I was under the understanding that Strings, although immutable, were
still reference objects and would be passed by reference to a method.
Can someone tell me how I'm thinking incorrectly?

The argument to changeString was passed by reference.
It locally changed the reference to refer to another String.
That is why the change did not take. If you instead write:
private static void changeString( ref String field )
{
field = "New Value";
}
and change the call to read:
changeString( ref testField );
then you will see what you expected. The difference is that
you are passing a reference to the object named "testField",
allowing it to be changed. Your previous code had no effect
on that object.

--
--Larry Brasfield
email: do***********************@hotmail.com
Above views may belong only to me.
Nov 16 '05 #3
Larry Brasfield <do***********************@hotmail.com> wrote:
I was under the understanding that Strings, although immutable, were
still reference objects and would be passed by reference to a method.
Can someone tell me how I'm thinking incorrectly?
The argument to changeString was passed by reference.


No it wasn't. It was passed by value. The argument was a reference in
itself, but it was passed by value.
It locally changed the reference to refer to another String.
That is why the change did not take. If you instead write:
private static void changeString( ref String field )
{
field = "New Value";
}
and change the call to read:
changeString( ref testField );
then you will see what you expected. The difference is that
you are passing a reference to the object named "testField",
allowing it to be changed. Your previous code had no effect
on that object.


No, the difference is that you are passing the reference *by*
reference. The object itself has no name, and its data cannot be
changed.

See 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
Chris Simmons <ne***************@netchris.com> wrote:

<snip>
I was under the understanding that Strings, although immutable, were
still reference objects and would be passed by reference to a method.
Can someone tell me how I'm thinking incorrectly?


It's unfortunate that people talk about things being passed "by
reference" when they don't really mean it - they mean references being
passed by value.

Hopefully you'll find the following page clears things up:
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 #5
A couple of problems here.

First, because Strings are immutable, changing the value of a string
doesn't really change the string _in situ_ in memory. Instead, it
creates a whole new string and points the String reference to it.

When you say:

String a = "Old Value";
a = "New Value";

you haven't really changed what is at the memory location where the
string "Old Value" lives. It's still there, if only for a short time
before the garbage collector comes around to sweep it up. What has
happened is that a whole new object in memory, a String instance, has
been created with the value "New Value". The variable a, which contains
a pointer (or a _reference_) to a string, is then changed to refer to
the new String instance (with the value "New Value") instead of the old
one (with the value "Old Value").

Now let's look at what happens when two String variables are involved:

String a = "Old Value";
String b = a;
a = "New Value";

After the first line executes, there is a new String instance in the
heap with the value "Old Value", and the variable "a" contains a
reference to the memory location on the heap where that String instance
is stored.

The second line just copies the reference to the String instance with
the value "Old Value" from "a" to "b". Now both String variables have
the same value, but be careful what I mean by "value": their value is
_not_ a String "Old Value". Their value is a _reference_ or a pointer
to a memory location at which is found a String with the value "Old
Value".

The third line instantiates a new String instance in the heap and gives
it the value "New Value". It then changes the String variable "a" to
contain a reference to this new String instance. Notice that nothing
has happened to the variable "b" in the third line of code: "b" is
still a reference to the first instance of String, which has the value
"Old Value". "a" and "b" now point to different memory locations.

This is _exactly_ what happens with reference types:

ArrayList x = new ArrayList();
ArrayList y = x;
x = new ArrayList();
x.Add("Hello world");

The first line of code creates and empty array list and points "x" to
it. The second line of code points "x" and "y" to the same array list.
The third line of code points "x" to a new array list that is distinct
from the first one. The last line modifies the second array list to
contain one item: a reference to a string with the value "Hello world".
The array list pointed to by "y" will still be the original, empty one,
so x.Count will be 1, but y.Count will be 0.

The different with the String type is that you don't see that "new"
operation taking place. It happens behind the scenes, which can be
confusing.

On top of this, there is one _true_ difference between Strings and most
other reference types that _does_ make Strings look like value types:
comparing two Strings with the "==" operator compares their _values_,
not their addresses (references), whereas comparing two object
references with "==" usually compares addresses, not values.

The second bit of confusion in your question relates to the fact that
objects are not, in fact, _passed by reference_ to methods. Instead,
object references are passed by value, which is exactly what happens
with String. To understand the difference, read Jon Skeet's excellent
page on parameter passing in C#:

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

Suffice to say that your question would have been more interesting if
in your method changeString() you had said:

field.Replace("l", "i");

and asked why the resulting output was not "Oid Vaiue" instead of "Old
Value". The problem with your original example is that setting "field"
to refer to a new object would _never_ change testField back in Main,
regardless of what kind of object "field" was declared to be. The only
way to make that happen is to do this:

changeString(ref testField);
....
private static void changeString(ref String field) ...

You will then see that yes, in fact testField changes its value in Main
after changeString completes.

Nov 16 '05 #6
Many thanks to all of you. I see the error in my understanding (or
lack thereof) now.
--
Thanks,
Chris Simmons
ne***************@netchris.com
Nov 16 '05 #7

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

Similar topics

9
by: Penn Markham | last post by:
Hello all, I am writing a script where I need to use the system() function to call htpasswd. I can do this just fine on the command line...works great (see attached file, test.php). When my...
1
by: Brian | last post by:
I've looked through the previous posts on this one and have verified permissions and location of my Dlls, but I am still getting an exception when I try to Load an assembly. The directory where...
0
by: Aryeh Holzer | last post by:
Hi, I've been trying to use the weather webservice available from the National Weather Service (NWS), at http://www.nws.noaa.gov/forecasts/xml/DWMLgen/wsdl/ndfdXML. wsdl without success. Here's...
0
by: nicomp | last post by:
I created a Web Service: I imported System.Data.SqlClient so I could access SQL server tables programmatically. The web service builds and deploys with no problems. When I try to add the...
13
by: Jiho Han | last post by:
Here's the issue. You have a class, Class Person { public int id; public string firstname; public string lastname; }
6
by: Mark Rae | last post by:
Hi, I'm in the process of updating an ASP.NET v1.1 web app to v2. The app uses ActiveDirectory a great deal, and I'm trying to use the new System.Collections.Generic namespace where possible,...
15
by: =?Utf-8?B?TWFkcyBOaWVsc2Vu?= | last post by:
Hi, I am developing a web service for a customer. The service has a method, that returns an array of Forms. Each form has a Name property of Type String. The customer wants the contract to...
9
by: Nathan Sokalski | last post by:
I am trying to use the System.Array.ForEach method in VB.NET. The action that I want to perform on each of the Array values is: Private Function AddQuotes(ByVal value As String) As String Return...
3
by: Marco Shaw | last post by:
I've got some C# code to create a custom PowerShell cmdlet with these statements: .... using System.Collections; using System.Collections.Generic; using System.Collections.ObjectModel; .... ...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 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 former...
0
by: ryjfgjl | last post by:
In our work, we often need to import Excel data into databases (such as MySQL, SQL Server, Oracle) for data analysis and processing. Usually, we use database tools like Navicat or the Excel import...
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: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
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
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
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...

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.