Ref Vs Out And Value Type Vs Reference Type

These are very common questions that have been asked in interviews. 

  • What is the difference between reference type and value type?
  • What is the difference between out and ref?

After reading this article you will be clear on that. So read it carefully.

Before going further deep, first, we need to understand what is passing by reference and passing by value as parameters.

Reference Type

In simple word, reference type variable contains a reference to data stored in memory.

For example, objects

var student = new Student();
var newStudent = student;

Now in above example, student and newStudent both refer to same memory location. Remember it is not referring to actual data.

Your data is stored somewhere in memory and that memory location is stored in student and newStudent.

Also note that, if you change newStudent it also reflects student object as they both share same location.

Now come to Value Type.

Value Type

Value type variable stores actual data instead of reference to it. 

For example, Int32, DateTime.

So, whatever you declare by above value types is stored as data.

Now let's understand both pass by reference and pass by value with example.

Pass By Reference

See below example and read comments carefully.

internal class Ref_Out {
    public class Employee {
        public int Id {
            get;
            set;
        }
        public string Name {
            get;
            set;
        }
        public int DeptId {
            get;
            set;
        }
    }
    public void Process() {
        Employee employee = new Employee() {
            Id = 1, Name = "amit", DeptId = 1
        };
        PassByRef(employee); // here it will pass copy of employee reference        
        Console.WriteLine(employee.Name);
    }
    private static void PassByRef(Employee emp) // this contains copy of reference, so if you change on this object, it will reflected on caller variable(employee)
    {
        emp.Name = emp.Name + " updated"; // employee name updated
        emp = new Employee(); // it stores new copy reference of employee and caller employee variable reference is disconnected.
        emp.Name = "New Employee"; // this will change on local variable copy, new employee in this case.
    }
}

So I hope you guess the correct output here.

Console.WriteLine(employee.Name);   // amit updated

Pass By Value

This one is very simple compared to pass by reference as it directly passes data. See below example and read comments carefully.

internal class Ref_Out {
    public void Process() {
        int i = 5;
        PassByVal(i); // it pass value variable here. so 5 will be passed. 
        Console.WriteLine(i);
    }
    private static void PassByVal(int i) // int i is local variable here and 5 is assigned to it
    {
        i = i * 2; // now it multiply 5 * 2 and stores 10 as a result in local variable i. so this is not reflected to caller variable.
    }
}

Hope it is clear now. Then let's move to further section. out and ref both pass parameter as a reference. so whatever changes you will do on passing parameter also changes in original variable.

out

The intent of using out is to get a modified value from method as out parameter. So you may or may not assign value to out parameter. It also works as two way binding when you assign value to out before passing and after passing you modified that variable on called method.

int index = 5;
PassByOut(out index);
private static void PassByOut(out int i) {
    i = i * 2; // This will give compile time error as it is unassigned.
    i = 20;
    i = i * 2; // it will not give error as i is already assigned.
}

In above example, out parameter works as two way binding, passing 5 as input parameter to method and modifying 'i' value to method and returning that value in original variable index. 

Ref

It is required to initialize ref variable before passing it. 

Note so the difference between out and ref is ref required to initialize before passed.

Employee employee = new Employee() {
    Id = 1, Name = "amit", DeptId = 1
};
PassByRef(ref employee); // it pass origional reference
Console.WriteLine(employee.Name);
private static void PassByRef(ref Employee emp) // origional reference of employee
{
    emp.Name = emp.Name + " updated"; // origional employee name changed to amit updated
    emp = new Employee(); // origional reference is changed to new employee
    emp.Name = "New Employee"; // origional employee name changed to New Employee
}

Now let's see above scenario with out parameter and check comments.

Employee employee = new Employee() { Id = 1, Name = "amit", DeptId = 1 };
            PassByOut(out employee);            
            Console.WriteLine(employee.Name);

	 private static void PassByOut(out Employee emp)
        {            
            emp.Name = emp.Name + " updated";  // compile time error, use of unassigned out parameter emp
            emp = new Employee();  
            emp.Name = "New Employee"; // it works as assigned previously
        }

I hope this article helps to understand in depth. Please motivate me by sharing and liking this article.