开发者

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);
       开发者_运维问答 }
    }


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.


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);


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"

    }
}


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.


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.


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.


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

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜