-3

As I know string is a referenced type and when you send a referenced type to a function, if you change its value, the value of the original object will change, but why when I call change function the original string remains unchanged. But when I have an object of a class and send it to a function, it original value will change. Here is an example:

    static void Main(string[] args)
    {
        string x = "Hi";
        Change(x);
        Console.WriteLine(x);

        var y = new Test();
        y.Str = "Hi";
        Change(y);
        Console.WriteLine(y.Str);

        Console.ReadKey();
    }
    static void Change(string str)
    {
        str = "Test";
    }
    static void Change(Test x)
    {
        x.Str = "Test";
    }

The output is "Hi" instead of "Test" for string, but for Test object it is "Test"

EO102030
  • 31
  • 6
  • 4
    Strings are immutable – Tim Schmelter Aug 18 '15 at 13:30
  • 2
    @TimSchmelter True, but it's not the answer to this particular question. – Theodoros Chatzigiannakis Aug 18 '15 at 13:31
  • https://msdn.microsoft.com/en-us/library/0f66670z.aspx – SquidScareMe Aug 18 '15 at 13:32
  • 2
    @TheodorosChatzigiannakis: it's not an answer but a comment. OP wants to modify a string that he passes to a method. That doesn't work. An answer could be that the former modifies a local variable(the parameter) and the latter an object which has a string property. The object is mutable. – Tim Schmelter Aug 18 '15 at 13:33
  • 1
    @TimSchmelter Even if string is mutable, it will not do what OP expect it to be. Answer to his question is he needs to pass the string the string by ref. i.e `Change(ref x);` because OP is overwriting the variable, not mutating. – Sriram Sakthivel Aug 18 '15 at 13:35
  • 2
    @TimSchmelter What I'm saying is that if the OP passed a `ref string` instead of a `string`, the result would be what he/she expected. So the immutability is not the main problem. – Theodoros Chatzigiannakis Aug 18 '15 at 13:35
  • @SriramSakthivel: not quite true. If `String` was mutable you don't need `ref` if `String` would provide properties or methods to let it change because `String` is a reference type(f.e. `str.Value = "Test"`). – Tim Schmelter Aug 18 '15 at 13:37
  • 2
    @TimSchmelter You're mixing two different concepts. Reference type has nothing to do with "Call By Reference". When you overwrite a variable(not mutating) then reference type doesn't matter. What matters is, is it passed as value or reference. In this case it is passed as value (i.e not by `ref x`) – Sriram Sakthivel Aug 18 '15 at 13:38

5 Answers5

4

It's not just strings, you also won't be able to change objects to be new objects, i.e., this won't work:

static void Change(ClassA aObj) 
{
    aObj = new ClassA(); // Won't hold when you leave the function
}

The reason is that you are passing the reference of those parameters by value. That means you get to see and mess around with what's there, but you can't change it to point to a new reference slot in the memory.

In order to fix that, you need to use the ref/out keywords.

For a more elaborate explanation, read this.

Omri Aharon
  • 16,959
  • 5
  • 40
  • 58
2

Because you're changing the value of the parameter that's passed in, not the original value.

i.e. str becomes a copy of x when you pass it in. Changing that makes no difference to the value stored in x.

EDIT: Ok, that was an overly simplified explanation, but as pointed out, better explanations are already available. Tim's right, strings are immutable, so you can't change the contents of the string that's stored in that reference, you can only replace it with a new one, but unless you specifically specify the parameter as 'ref', you can't change that reference inside the method.

Flynn1179
  • 11,925
  • 6
  • 38
  • 74
  • string is reference type, thus what I passed is a reference not a value – EO102030 Aug 18 '15 at 13:33
  • 2
    This questions has been asked multiple times on SO. Use Google. An example would be: http://stackoverflow.com/questions/1069155/is-string-a-value-type-or-a-reference-type – dotNET Aug 18 '15 at 13:34
  • But is a immutable reference type, strings are special because some API functions allows you to pass null. – Alexandre Borela Aug 18 '15 at 13:35
  • what Flynn *means* (somewhat ill-stated right now) is that you need to change what the string reference itself points to in the method implementation - that's only possible if you pass the string reference by reference (add the `ref` keyword) and not by value, which is the default. – BrokenGlass Aug 18 '15 at 13:35
  • Thanks, it makes sense now. – EO102030 Aug 18 '15 at 13:43
1

Try passing the string with the keyword ref:

static void Change(ref string str)
{
    str = "Test";
}
manabreak
  • 5,415
  • 7
  • 39
  • 96
0

When you call the Change(string str) method a new reference(variable) is created and assigned the value of x which is passed as parameter. When str is changed in the method x is uneffected as they are two seprated references.

Try Change(ref string str)

Faizan Khan
  • 172
  • 8
0

First of all, strings are immutable. They cannot change. Second, You passed this string by "reference" since string is a reference type. Assigning the method parameter won't change the value of the reference, it'll only change the value of this string in particular. You can use ref to reference the string location instead of its value.

public void Change(ref string str)
{
    str = "New String";
}
Philippe Paré
  • 4,279
  • 5
  • 36
  • 56