ref or no ref

aronmatthew

Well-known member
Joined
Aug 5, 2019
Messages
46
Programming Experience
Beginner
Hello I'm trying to understand exactly how the ref keyword works. From my experiments it seems that to modify any type of object that is passed to a method requires the ref keyword. But for reference types modifying field or property works without ref. But ref is required to set the object to null.
 
Last edited:
Moving to General C#. This is not specific to WinForms.
 
When used as method parameter modifiers, ref is used so that an object or value can be passed in a method, and the method can potentially change that value so that the caller gets the changes. (In a similar fashion, out is used when the method wants to pass a value back to the caller, but cannot use a return value.)

I assume you've played with code that looks like this that demonstrates the difference:
C#:
using System;

record class Node(string Name);

public class Program
{
    static void SwapNot(Node a, Node b)
    {
        Node temp = a;
        a = b;
        b = temp;
    }

    static void SwapReally(ref Node a, ref Node b)
    {
        Node temp = a;
        a = b;
        b = temp;
    }

    public static void Main()
    {
        var left = new Node("Luke");
        var right = new Node("Leia");
       
        Console.WriteLine($"{left} {right}");
        SwapNot(left, right);
        Console.WriteLine($"{left} {right}");
        SwapReally(ref left, ref right);
        Console.WriteLine($"{left} {right}");
    }
}

How does the ref work? When you use ref, the compiler pass in the actual memory address of the variable as the parameter, rather than the value of the variable. Since callee now knows where in memory that variable lives, it can modify the value stored in the memory location.
 
The ref keyword is a fundamental concept in C# that allows you to pass arguments to methods by reference rather than by value. This means that when you use ref, you pass a reference to the original variable, enabling the method to modify the actual variable's value.
The ref keyword is primarily used when you want to modify the original value of a variable within a method. It is commonly used with value types (e.g., int, float) but can also be applied to reference types (e.g., class objects).
public void ModifyValue(ref int number).
Basic Example:
public void ModifyValue(ref int number)
{
     number = 42; // Changes the original value of 'number'
}
 
@Rythorian : that explains why you would use ref, but does not explain how it works.
 
it seems to me that all objects are passed as reference by default only they have security attached to not be set to null. while intregral types such as int, ext... need to be passed using the ref keyword.
 
You can't assign a new object to caller without ref (or out).
C#:
record class ReferenceType (int Id);

static void ChangerRef(ref ReferenceType obj) => obj = new ReferenceType(4);
static void ChangerValue(ReferenceType obj) => obj = new ReferenceType(4);
static void ChangerOut(out ReferenceType obj) => obj = new ReferenceType(4);
C#:
ReferenceType A = new(1);
ReferenceType B = new(2);
ReferenceType C = new(3);
ChangerRef(ref A);
ChangerValue(B);
ChangerOut(out C);
Console.WriteLine(A.Id);
Console.WriteLine(B.Id);
Console.WriteLine(C.Id);
obj parameter for all three contains the memory address for the object, but for ChangerValue it is a copy of the memory address (a new 'value'), which means this method can reach the object and change its properties, but it can't assign a new object to the caller.
 
it seems to me that all objects are passed as reference by default only they have security attached to not be set to null. while intregral types such as int, ext... need to be passed using the ref keyword.

All method arguments are passed by value by default. They are only passed by reference if you specify that. If the argument is a value type, e.g. int or DateTime, then the value of the argument is a value. If the argument is a reference type then the value of the argument is a reference. When you pass by reference, you are passing a reference to the value. If the argument is a value type, you're passing a reference to a value. If the argument is a reference type, you're passing a reference to a reference. The latter is akin to a pointer to a pointer in C/C++, which is exactly how the same thing is achieved in those languages.
 

Latest posts

Back
Top Bottom