Type 'string' as an argument in C# function

prosseek picture prosseek · May 29, 2011 · Viewed 13.4k times · Source

The string type in C# is a reference type, and passing a reference type argument by value copies the reference so that I don't need to use the ref modifier. However, I need to use the ref modifier for modifying the input string. Why is this?

using System;

class TestIt
{
    static void Function(ref string input)
    {
        input = "modified";
    }

    static void Function2(int[] val) // Don't need ref for reference type
    {
        val[0] = 100;
    }

    static void Main()
    {
        string input = "original";
        Console.WriteLine(input);
        Function(ref input);      // Need ref to modify the input
        Console.WriteLine(input);

        int[] val = new int[10];
        val[0] = 1;
        Function2(val);
        Console.WriteLine(val[0]);
    }
}

Answer

dlev picture dlev · May 29, 2011

The reason you need to ref the string parameter is that even though you pass in a reference to a string object, assigning something else to the parameter will just replace the reference currently stored in the parameter variable. In other words, you have changed what the parameter refers to, but the original object is unchanged.

When you ref the parameter, you have told the function that the parameter is actually an alias for the passed-in variable, so assigning to it will have the desired effect.

EDIT: Note that while string is an immutable reference type, that's not too relevant here. Since you're just trying to assign a new object (in this case the string object "modified"), your approach wouldn't work with any reference type. For example, consider this slight modification to your code:

using System;

class TestIt 
{
    static void Function(ref string input)
    {
        input = "modified";
    }

    static void Function2(int[] val) // don't need ref for reference type
    {
        val = new int[10];  // Change: create and assign a new array to the parameter variable
        val[0] = 100;
    }
    static void Main()
    {
        string input = "original";
        Console.WriteLine(input);
        Function(ref input);      // need ref to modify the input
        Console.WriteLine(input);

        int[] val = new int[10];
        val[0] = 1;
        Function2(val);
        Console.WriteLine(val[0]); // This line still prints 1, not 100!
    }
}

Now, the array test "fails", because you're assigning a new object to the non-ref parameter variable.