Satbir
Satbir

Reputation: 6496

Behavior of String in C#

I am a C++ programmer, now working on a C# project.

I am trying to understand in the below snippet why the value of string does not change even though the function is changing its value, I thought it is an object and would be passed as a reference.

public class TestClass
    {
        public TestClass(String passedStr)
        {
            passedStr = "Change me";
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            String aString="I am what i am";
            TestClass obj = new TestClass(aString);
            Console.WriteLine(aString);

        }
    }

But behavior with user defined classes are different.

 public class TestClass
    {
        private int x;
        public int ID
        {
            get
            {
                return x;
            }
            set
            {
                x = value;
            }
        }
        public TestClass(int a)
        {
            x = a;
        }
    }
    public class Tester
    {
        public Tester(TestClass obj)
        {
            obj.ID = 999;
        }
    }

    class Program
    {
        static void Main(string[] args)
        {

            TestClass obj = new TestClass(555);
            Tester tester = new Tester(obj);
            Console.WriteLine(obj.ID);
        }
    }

Upvotes: 2

Views: 316

Answers (7)

Eric Lippert
Eric Lippert

Reputation: 659964

Let's go back to basics.

A variable is a storage location.

A variable of type string is a storage location that stores either null, or a reference to a string.

"passedStr" and "aString" are different variables.

When you call "new TestClass(aString)" you create a new storage location for "passedStr" and copy the contents of "aString" into it. You now have two variables that have the same content: a reference to a string.

Inside the constructor you change the value stored in the storage location for "passedStr". "aString" remains the same.

The "ref" and "out" keywords in C# mean "make the formal parameter and the argument aliases of each other". In that case you have only one variable with two different names. When you change one of them the other one changes as well, because they are the same variable.

Upvotes: 6

abhilash
abhilash

Reputation: 5641

public class Employee
{
    public string ID { get; set; }
    public string Name { get; set; }

    public override string ToString()
    {
        return string.Format("ID = {0} Name = {1}", ID, Name);
    }
}

public class TestClass2
{
    public TestClass2(Employee e)
    {
        e.ID="007";
        e.Name="james";
    }
}  



static void Main()
{

    Employee e = new Employee();
    e.ID = "0";
    e.Name = "nobody";
    TestClass2 t = new TestClass2(e);
    Console.WriteLine(e); //Output ID = 007 Name = James 
}  

strings are passed by reference but the pointer is passed by value in C#

Parameter passing in C# by Jon Skeet

Upvotes: 0

Andrew Cooper
Andrew Cooper

Reputation: 32576

passedStr is not the string, but a constructor parameter that holds a reference to the string. All your TestClass constructor is doing is changing the string that this parameter references. It has no effect outside the constructor.

Upvotes: 1

Kevin
Kevin

Reputation: 5694

Strings are passed by reference but the pointer is passed by value in C#. If you want to pass the string by reference you'll have to make use of the ref key word.

For example:

public class TestClass
{
    public TestClass(ref string passedStr)
    {
        passedStr = "Change me";
    }
}

class Program
{
    static void Main(string[] args)
    {
        string aString="I am what i am";
        TestClass obj = new TestClass(ref aString);
        Console.WriteLine(aString); // "Change me"

    }
}

Upvotes: 1

Daren Thomas
Daren Thomas

Reputation: 70314

The object I am what i am is being passed by reference, but the reassignment is to a local variable. You don't change the original object, but instead assign a new object (Change me) to the location of the argument.

Upvotes: 0

Heinzi
Heinzi

Reputation: 172210

What you are doing in the constructor, is that you are assigning a new String literal to the local variable passedStr.

In C, the equivalent function would look something like this:

Testclass constructor_testclass(char* passedStr) {
    passedStr = "Change me";
}

I think it's obvious that this function does not change the value of the char* in the calling function.

Upvotes: 0

user541686
user541686

Reputation: 210352

No, it's passed by value; there's no ref keyword.

It's passing a reference type (here, a class) by value (no ref keyword), just like passing a copy of a pointer in C++. You're reassigning the pointer, not the actual data (which you can't do with strings anyway).

If you need pass-by-reference, try:

    public TestClass(ref String passedStr)
    {
        passedStr = "Change me";
    }

    ...
    TestClass obj = new TestClass(ref aString);

Upvotes: 5

Related Questions