简体   繁体   中英

Changing reference types(strings) inside methods

I am passing a string variable to a method. I know strings are reference types but the value that I assign inside the method is lost.

public static void TestMethod(string myString)
{
    myString = "world";
}

static void Main(string[] args)
{
    string s = "hello";
    Console.WriteLine(s); // output is "hello"
    TestMethod(s);
    Console.WriteLine(s); // output is also "hello" not "world" !?
}

Anyway this does not happen with an array for example. Can someone explain why might be the cause?

Because myString = "world" assigns a new string to the parameter, not updating the existing string. To update the original reference to the string you must pass the parameter with ref .

public static void TestMethod(ref string myString)
{
    myString = "world";
}

static void Main(string[] args)
{
    string s = "hello";
    Console.WriteLine(s); // output is "hello"
    TestMethod(ref s);
    Console.WriteLine(s); // output is also "hello" not "world" !?
}

Yes, because without a ref (or out) you can't assign a new object to a parameter. Since you didn't pass it in through a ref, the variable outside the method still references the original string which didn't change. Consequently, strings are immutable, so you can't do anything to it without create a new string once it is instantiated.

The array can be altered (or the contents of the array can be altered), because the references inside the array are not immutable (you can say reassign my_object 1 to equal "BLAH"). You can replace a value in the array and have it accessible outside of the array, because the reference to the array outside of the method hasn't changed.

Link to String in MSDN (talks about immutability)

For this to work you need to add the "ref" keyword to the parameter in the method signature.

Though your string is passed by reference, when you pass it to your method you have 2 references to the same string - the one in the Main() and the one in TestMethod(). When you assign a new value to the variable in the TestMethod() you are changing its reference, but not what Main()'s variable is referencing.

If you were able to just change the string from the TestMethod() instead of reassigning then you would see the effects in the Main(), but you can't with strings since they are immutable.

To play with this further you can try the following - change TestMethod() to receive a IList and add items to this list. You can see these new items in the variable you passed in from Main(). Now if you change TestMethod(IList listArg) to first reassign listArg to a new list (ie listArg = new List) and then add items, the list in Main() remains unchanged. This is the same idea.

Strings are immutable, which means that you can't change it's value, like you do with the items in an array. You can only replace a string object with a different string object.

The same happens if you try to replace an array object. This will put a new array in the parameter variable, but it will not change the variable that you used to call the method, and thus does not replace the array that you passed in:

public static void TestMethod(string[] myArray) {
  myArray = new string[] { "world" };
}

Parameters are always passed by value unless you use the ref or out keywords. For a reference type that means that you pass a copy of the reference.

Using the ref keyword you pass the variable, so that you can change it in the method:

public static void TestMethod(ref string myString) {
  myString = "world";
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM