Reference types are always passed by value in C#

Last week i had a discussion with a friend about C# and passing parameters to methods. My friend asked why it is possible to use the ‘ref’ keyword for a reference type in C# when passing it to a method, he was under the impression that reference types are passed by reference to methods. This seems to be a quite common misunderstanding about C#, to make it clear:

Reference types are always passed to methods by value (unless you use the ‘ref’ keyword)

What happens when you call a method with a reference type as parameter is that the value of the reference (the pointer, an address to pointing to the referenced object) is passed to the method (by value). What this means is that you can not modify the original reference, but you can modify the object it is referencing (pointing to).

By using the ‘ref’ keyword you will pass the address of the reference to the method, which means that you can modify its value.

This is a short example illustrating this (remember, in C#, a string is a reference type):

class Program
{
    static void Main(string[] args)
    {
        string s = "orig value";
        Console.WriteLine("Orig value: " + s);
            
        MyFunc1(s);
        Console.WriteLine("After MyFunc1: " + s);

        MyFunc2(ref s);
        Console.WriteLine("After MyFunc2: " + s);
    }

    public static void MyFunc1(string s)
    {
        s = "new value 1";
    }

    public static void MyFunc2(ref string s)
    {
        s = "new value 2";
    }
}

Output:
Orig value: orig value
After MyFunc1: orig value
After MyFunc2: new value 2

Peter

.NET, C#

2 thoughts on “Reference types are always passed by value in C#

  1. //what about this ?
    class Program
    {
    static void Main(string[] args)
    {
    string[] s = {“orig value”};
    Console.WriteLine(“Orig value: ” + s[0]);

    MyFunc1(s);
    Console.WriteLine(“After MyFunc1: ” + s[0]);

    MyFunc2(ref s);
    Console.WriteLine(“After MyFunc2: ” + s[0]);
    }

    public static void MyFunc1(string[] s2)
    {
    s2[0] = “new value 1”;
    }

    public static void MyFunc2(ref string[] s3)
    {
    s3[0] = “new value 2”;
    }
    }

  2. Yunus:

    A string[] is a reference type, in MyFunc1 you copy the reference (the pointer) and pass it by value to the method. So s2 is also pointing at the same list that s is pointing at.

    In MyFunc2 s is passed by reference, that means that we pass on the address to the reference, so s3 and s is actually the same, while s and s2 is just two different references pointing at the same list. Since they are pointing at the same list we can of course modify the data.

    In MyFunc2 we could assign s3 a new list and s in Main would reflect this. We can not do the same with s2.

    static void Main(string[] args)
    {
    string[] s = { “orig value” };
    Console.WriteLine(“Orig value: ” + s[0]);

    MyFunc1(s);
    Console.WriteLine(“After MyFunc1: ” + s[0]);

    MyFunc2(ref s);
    Console.WriteLine(“After MyFunc2: ” + s[0]);

    Console.ReadLine();
    }

    public static void MyFunc1(string[] s2)
    {
    s2 = new[] {“new value 1”};
    }

    public static void MyFunc2(ref string[] s3)
    {
    s3 = new[] { “new value 2” };
    }

    The program above would print:
    Orig value: orig value
    After MyFunc1: orig value
    After MyFunc2: new value 2

Leave a Reply

Your email address will not be published. Required fields are marked *