How to pass string by reference?

Asked

Viewed 1,350 times

19

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

I took the test below and it didn’t happen what I expected. I’m wrong in what I’m thinking? It certainly isn’t bug 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 made a Fiddle.

4 answers

19


In fact what is passed by reference is the object, not the reference itself. The reference is passed by value, therefore by copy, so changing the reference will not reflect the past argument. If I changed the object there yes I would reflect in the past argument, but as string It is immutable that it is not possible, it can only change the whole object, but if it were another mutable object, yes, whatever you change internally, without changing the identity of the object, it would be seen by the one who called. In this example changed the whole object.

If you really want to allow the reference to be exchanged, that is, that another object is bound to that parameter and reflects in the argument, you have to pass the reference itself by reference. It may seem strange, but it makes sense to understand that the reference is a simple value since it is only 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";
}

Behold working in the ideone. And in the .NET Fiddle. Also put on the Github for future reference.

Note that the signature of the methods It’s different, so I didn’t even have to change the name.

Complement: What "immutable" really means?

10

In the 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 those changes in the same Fiddle, in case you want to see:

https://dotnetfiddle.net/FvijX6

6

In C#, string is, yes, a type by reference. Strings in C# are immutable, that is, you never really change the value of a string and yes gets a modified copy which 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 for the variable s.

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

More details here.

A simple way to solve the problem posed would be to change the function return type ChangeText to string and reassign the variable value text with 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 example in . NET Fiddle

Another alternative to solve by reference would be using the Stringbuilder class from the standard C 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 example in . NET Fiddle

-1

I won’t explain but I’ll 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
}
  • 1

    It would be better to give a better explanation, because the user seeks an explanation for the behavior presented, please supplement your question.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.