-2

I was reading a code that made me stop at some line:

List<object> props = new List<object>();
DoWork(param1, param2, props);
//props.Count grew up

I was thinking that changing a variable outside its scope requires passing it as out or ref, but then I realized that unless the DoWork method changes the props reference like:

props = new List<object>();

the reference will be point to the same location. So there is no need to use ref here.

and then I created a method for string type:

static void ChangeMe(string str)
{
    str = "W77";
}
public static void Main(string[] args)
{
    string str = "p1";
    ChangeMe(str);
    //str is still "p1"
}

If the behavior motivated the List to be changed outside its scope is that it's reference type, why string doesn't change if it's not reallocated in the callee method and it's a reference type like List<object>?

Gilad Green
  • 36,708
  • 7
  • 61
  • 95
mshwf
  • 7,009
  • 12
  • 59
  • 133

2 Answers2

1

Reason is because string is an immutable type in C# and therefore whenever you "change" it what actually you are doing is creating a new string with the new value and referencing to it.

When calling the ChangeMe a new reference to the same string is created. Then in the method you are referencing the new reference to a completely new string, which does not influence the previous string defined in Main.

Gilad Green
  • 36,708
  • 7
  • 61
  • 95
1

In the function ChangeMe you have a local copy of the reference to the object you passed in. When you store something in str you basically replace that reference with a new one. Immutability does not play a role here, because you did not actually try to modify the object referenced by str. So you now have a new reference stored in str which points to a new object created by string constructor when you use string literal "W77". And as you pointed out, you can get that outside the scope of the function by ref or out.

Luboš Hemala
  • 69
  • 1
  • 5