How to pass string by reference?

18

I passed a string as a parameter. From what I know it is passed by reference, so if I change anything in it within the method, when I leave it the value will continue to change.

I did the test below and it did not happen what I expected. Am I mistaken in what I am thinking? Certainly not of language.

using System;

public class Program
{
    public static void Main()
    {
        string text = "text";
        ChangeText(text);
        Console.WriteLine(text);
    }
    static void ChangeText(string text) { 
        text = "new text";
    }
}

I did a Fiddle .

    
asked by anonymous 31.03.2017 / 13:21

4 answers

18

In fact, what is passed by reference is an object, not the reference itself. The reference is passed by value, therefore by copy, so if changing the reference will not reflect in the argument passed. If you change the object then it would reflect on the last argument, but since string is immutable this is not possible, it can only change the whole object, but if it were another changeable object, yes, what you change internally, without changing the identity of the object, would be seen by those who called. In this example, you changed the entire object.

If you really want to allow the reference to be changed, that is, that another object is bound to that parameter and reflects on the argument, you have to pass the reference itself by reference. It may seem strange, but it makes sense if you understand that the reference is a simple value since it is just a pointer and not the whole object.

using static System.Console;

public class Program {
    public static void Main() {
        var text = "text";
        ChangeText(text);
        WriteLine(text);
        ChangeText(ref text);
        WriteLine(text);
    }
    static void ChangeText(string text) { 
        text = "new text";
    }
    static void ChangeText(ref string text) { 
        text = "new text";
    }
}

See running on .NET Fiddle . And No Coding Ground . Also put it on GitHub for future reference .

Note that signature methods is different. so I did not even have to rename it.

Complement: What "immutable" really means ?

    
31.03.2017 / 13:34
9

In C# to pass a variable by reference, use the keyword ref . Just change your method to:

static void ChangeText(ref string text) { 
        text = "new text";
}

and your call to:

ChangeText(ref text);

I made these changes in the same Fiddle, if you'd like to see:

link

    
31.03.2017 / 13:32
5

In C #, string is, rather, a type by reference. Strings in C # are immutable, that is, you never actually change the value of a string , but you get an altered copy that is then assigned to a variable. Example:

string s = "foo";
s = "bar"; 

What the above code does is create a copy of the string "foo", assign it the value "bar" and pass this new string to the variable s .

Because of this behavior, it is recommended to use C # StringBuilder for string manipulation, thus avoiding the creation of multiple copies in memory.

More details here.

A simple way to solve the problem is to change the return type of the function ChangeText to string and reassign the value of the variable text to the return of the function:

public static void Main()
{
    string text = "text";
    text = ChangeText(text);
    Console.WriteLine(text);
}
static string ChangeText(string text) { 
    text = "new text";
    return text;
}

Functional sample in .NET Fiddle

Another alternative to solve by passing by reference would be to use the StringBuilder class from the C # default library:

public static void Main()
{
    StringBuilder text = new StringBuilder("text");
    Console.WriteLine(text);
    ChangeText(text);
    Console.WriteLine(text);
}
static void ChangeText(StringBuilder text) { 
    text.Replace(text.ToString(), "new text");
}

Functional sample in .NET Fiddle

    
31.03.2017 / 13:40
-2

I will not explain, but I will give you what you need

internal Object funcao(object obj)
{
     return new Object(); // Estas a criar algo dentro da função e retornas o teu objecto
}

internal void funcao(ref object obj)
{
     obj = new Object(); // Das o teu objecto, e retornas o objecto modificado
}

internal void funcao(out Object obj)
{
     Object obj = new Object(); // Aqui tens de o declarar sempre, e o que modificares aqui sai para fora
}

internal void funcao(Object obj)
{
     obj = new Object(); // O que modificares aqui dentro não sai para fora
}
    
31.03.2017 / 16:28