SoFunction
Updated on 2025-03-04

In-depth analysis of the difference between ref and out

ref and out are both keywords in C#, and the functions implemented are similar. They both specify a parameter to be passed according to the reference.
There is no difference between them for compiled programs, which means they only have syntax differences.
To sum up, they have the following syntax differences:
 
1. The parameters passed in ref must be initialized before calling, and out does not need to be:

Copy the codeThe code is as follows:

int i;
SomeMethod( ref i );// Syntax error
SomeMethod( out i );//pass

2. The parameters passed in ref can be used directly within the function, but out cannot:
Copy the codeThe code is as follows:

public void SomeMethod(ref int i)
{
int j=i;//pass
   //...
}
public void SomeMethod(out int i)
{
int j=i;// Syntax error
}

3. The parameters passed in ref cannot be modified inside the function, but out must be assigned before leaving the function body.
Ref must be initialized before the parameter is passed; while out does not have to be initialized before the parameter is passed, and the conversion process between the ... value type and the reference type is called boxing and unboxing.

Summarize:
It should be said that the system has fewer restrictions on ref. Although out does not require initialization before calling, its value is invisible inside the function, that is, the value passed through out cannot be used, and a value must be assigned within the function. Or the function assumes the responsibility of initializing this variable.

Let’s talk about the difference between ref and out:
1 About reload
Principle: Methods with out|ref keywords can be overloaded with methods without out and ref keywords; but if you want to overload between out and ref, the compiler will prompt: You cannot define methods that are only overloaded on ref and out.

2 About the initial value before call
Principle: Before calling a function with ref as a parameter, the actual parameter must be assigned an initial value. Otherwise, the compiler will prompt: unassigned local variables are used;
The actual parameter may not assign the initial value before the function out as a parameter is called.

3 Regarding the principle of the initial value of the parameter introduced in the function:In the called function, the parameters introduced by out are assigned at least once before returning, otherwise the compiler will prompt: the unassigned out parameter is used;
In the called function, the parameters introduced by ref do not have to assign initial values ​​to them before returning.

Summarize:Ref and out in C# provide a solution for passing value types by reference. Of course, reference types can also be modified with ref and out, but this has lost its meaning. Because the reference data type is originally a copy of the passed reference itself rather than a copy of the value. The ref and out keywords will tell the compiler that the address of the parameter is now passed instead of the parameter itself, which is the same as the default pass of the reference type. At the same time, the compiler does not allow overloading between out and ref, which fully shows that the difference between out and ref is only from the compiler perspective, and the IL code they generate is the same. Some people may have a question, just like when I first started learning: the value type does not allocate memory in the managed heap, so why can it be passed by address? Although the value type itself represents the data itself in the stack of the live thread (as opposed to the reference data type itself does not represent data but points to a memory reference), the value type also has its own address, namely a pointer. Now after being modified with ref and out, this pointer is passed, so the real exchange of the modified values ​​of a and b can be realized. This is the benefit that ref and out bring to us.

first:Both are passed by address, and the value of the original parameter will be changed after use.
Second:rel can pass the value of the parameter into a function, but out needs to clear the parameter, that is, you cannot pass a value from out. After out, the value of the parameter is empty, so you must initialize it once. This is the difference between the two, or as some netizens said, rel is in and out, and out is only out but not in.

ref (C# reference)
The ref keyword causes the parameters to be passed by reference. The effect is that when control is passed back to the call method, any changes to the parameters in the method will be reflected in the variable. To use the ref parameter, both the method definition and the method calling must use the ref keyword explicitly.
For example:

Copy the codeThe code is as follows:

class RefExample
{
    static void Method(ref int i)
    {
        i = 44;
    }
    static void Main()
    {
        int val = 0;
        Method(ref val);
        // val is now 44
    }
}

The parameters passed to the ref parameter must be initialized first. This is different from out, where the parameters of the latter do not need to be explicitly initialized before being passed.
Although ref and out are handled differently at runtime, they are handled the same at compile time. Therefore, if one method takes the ref parameter and the other method takes the out parameter, the two methods cannot be overloaded. For example, from a compilation point of view, the two methods in the following code are exactly the same, so the following code will not be compiled:
Copy the codeThe code is as follows:

class CS0663_Example
{
    // Compiler error CS0663: "cannot define overloaded
    // methods that differ only on ref and out".
    public void SampleMethod(ref int i) { }
    public void SampleMethod(out int i) { }
}

However, if one method takes the ref or out parameter and the other method does not take these two parameters, overloading can be performed, as shown in the following example:
Copy the codeThe code is as follows:

class RefOutOverloadExample
{
    public void SampleMethod(int i) { }
    public void SampleMethod(ref int i) { }
}

out (C# reference)
The out keyword causes the parameters to be passed by reference. This is similar to the ref keyword, except that ref requires that variables must be initialized before being passed. To use the out parameter, both the method definition and the method calling must use the out keyword explicitly.
For example:
Copy the codeThe code is as follows:

class OutExample
{
    static void Method(out int i)
    {
        i = 44;
    }
    static void Main()
    {
        int value;
        Method(out value);
        // value is now 44
    }
}

Although variables passed as out parameters do not have to be initialized before passing, methods need to be called to assign values ​​before the method returns.

The ref and out keywords are handled differently at runtime, but are handled the same at compile time. Therefore, if one method takes the ref parameter and the other method takes the out parameter, the two methods cannot be overloaded. For example, from a compilation point of view, the two methods in the following code are exactly the same, so the following code will not be compiled:
Copy the codeThe code is as follows:

class CS0663_Example
{
    // Compiler error CS0663: "Cannot define overloaded
    // methods that differ only on ref and out".
    public void SampleMethod(out int i) { }
    public void SampleMethod(ref int i) { }
}

However, if one method takes ref or out parameters and the other method does not take these two parameters, it can be overloaded.
As shown below:
Copy the codeThe code is as follows:

class RefOutOverloadExample
{
    public void SampleMethod(int i) { }
    public void SampleMethod(out int i) { }
}