
- C# Basic Tutorial
- C# - Home
- C# - Overview
- C# - Environment
- C# - Program Structure
- C# - Basic Syntax
- C# - Data Types
- C# - Type Conversion
- C# - Variables
- C# - Constants
- C# - Operators
- C# - Decision Making
- C# - Loops
- C# - Encapsulation
- C# - Methods
- C# - Nullables
- C# - Arrays
- C# - Strings
- C# - Structure
- C# - Enums
- C# - Classes
- C# - Inheritance
- C# - Polymorphism
- C# - Operator Overloading
- C# - Interfaces
- C# - Namespaces
- C# - Preprocessor Directives
- C# - Regular Expressions
- C# - Exception Handling
- C# - File I/O
- C# Advanced Tutorial
- C# - Attributes
- C# - Reflection
- C# - Properties
- C# - Indexers
- C# - Delegates
- C# - Events
- C# - Collections
- C# - Generics
- C# - Anonymous Methods
- C# - Unsafe Codes
- C# - Multithreading
- C# Useful Resources
- C# - Questions and Answers
- C# - Quick Guide
- C# - Useful Resources
- C# - Discussion
What is the usage of ref, out, and in keywords in C#?
In C#, most of the methods can have zero or more parameters which define the data that must be provided to the method. Any code that calls the method has to pass the data (called arguments) to the method. A method declares its inputs as parameters, and they're provided by calling code in the form of arguments.
For example, consider the following method and subsequent method call.
static void Greet(string greeting){ Console.WriteLine(greeting); } ... Greet("Hello");
In the above example, greeting is a parameter of the Greet() method, and "Hello" is an argument passed to the method.
When you call a method and pass arguments, they are passed by value, which means a copy of the value is created when passed to the method. Any changes made to the argument inside the method are not reflected on the original variable.
using System; int number = 8; Increase(number); Console.WriteLine(number); // prints 8 static void Increase(int num){ num = num + 1; Console.WriteLine(num); // prints 9 }
When you pass a reference type variable, such as an object, C# still copies the reference by value, because the variable holds the reference, not the actual object. So even though a copy of the reference variable is passed around, both of them refer to the same object in the memory. So any changes made to the object by the variable inside the method are visible to the variable outside the method.
using System; var john = new User{ Name = "John", Salary = 50000 }; Promote(john); Console.WriteLine(john.Salary); // prints 60000 static void Promote(User u){ u.Salary += 10000; Console.WriteLine(u.Salary); // prints 60000 }
However, if you change the variable's value itself inside the method, that change is not reflected outside the method, as only a copy was changed, not the actual object. For example, we can assign the argument to null inside the method, and the actual variable will remain unchanged.
using System; var john = new User{ Name = "John", Salary = 50000 }; Promote(john); Console.WriteLine(john.Salary); // prints 50000 static void Promote(User u){ u = null; }
C# allows three different modifier keywords using which you can control the parameters of methods.
The ref modifier
C# allows you to pass parameters by reference using the ref modifier. It doesn't matter if the variable getting passed belongs to a reference type or a value type. Both the parameter and the argument will refer to the same memory location.
In the following example, setting the argument u to null will also make the john variable null, causing the null reference exception.
Example
using System; var john = new User{ Name = "John", Salary = 50000 }; Promote(ref john); Console.WriteLine(john.Salary); // throws System.NullReferenceException static void Promote(ref User u){ u = null; }
An argument passed with a ref modifier must be initialized before it is passed.
The out modifier
It is similar to the ref modifier, except
The argument doesn't have to be initialized before it's going into the function
The argument must be initialized (assigned to) before it comes out of the function.
In the example below, the Hire function initializes a new user object passed to it via the out modifier. Notice that the variable is variable john is declared on the fly when calling the Hire method.
using System; Hire(out User john); Console.WriteLine(john.Salary); // prints 50000 static void Hire(out User u){ u = new User{ Name = "John", Salary = 50000 }; }
Like the ref modifier, a variable marked by the out modifier is passed by reference.
Often an out variable is used to get multiple return values from a function as follows −
using System; var john = new User{ Name = "John", Salary = 50000 }; bool shouldPromote = Raise(john.Salary, out double hike); Console.WriteLine(shouldPromote); // True Console.WriteLine($"Hike Amount = {hike}"); // prints 5000 static bool Raise(int salary, out double hike){ hike = salary * 0.1; return hike < 7000; }
The in modifier
It is similar to the ref and out parameters, except that the method accepting a in argument's value cannot modify the argument. If it tries, the C# compiler generates a compile-time error.
The in parameter saves the compiler from copying a large value type's memory to the parameter variable, at the same time preventing the object from accidental modification. This makes them very useful when passing a large value type to the method.
var point = new Coord(); Verify(point); static void Verify(in Coord c){ // error: Cannot assign to variable 'in Coord' because it is a readonly variable c = new Coord(); } struct Coord{ public int X; public int Y; }
Example
using System; class Program{ static void Main(){ int number = 8; Increase(number); Console.WriteLine(number); // prints 8 var john = new User { Name = "John", Salary = 50000 }; Promote(john); Console.WriteLine(john.Salary); // prints 60000 Leave(john); Console.WriteLine(john.Salary); // prints 60000 LeaveByRef(ref john); Console.WriteLine(john?.Salary); // prints nothing User dave; Hire(out dave); Console.WriteLine(dave.Salary); // prints 50000 } static void Increase(int num){ num = num + 1; Console.WriteLine(num); // prints 9 } static void Promote(User u){ u.Salary += 10000; Console.WriteLine(u.Salary); // prints 60000 } static void Leave(User u){ u = null; } static void LeaveByRef(ref User u){ u = null; } static void Hire(out User u){ u = new User{ Name = "John", Salary = 50000 }; } } class User{ public string Name { get; set; } public int Salary { get; set; } }
Output
9 8 60000 60000 60000 50000
- Related Articles
- What are the differences between ref and out parameters in C#?
- Difference Between ref and out in C#
- Difference between out and ref keyword in C#
- What are Ref locals and Ref returns in C# 7.0?
- What is the difference between keywords and reserved words in Java?
- What is the difference between super and this, keywords in Java?
- What is the difference between throw and throws keywords in Java?
- What is the difference between VAR and DYNAMIC keywords in C#?
- What is the difference between keywords const and readonly in C#?
- What is a reference/ref parameter of an array type in C#?
- What is the difference between public, static and void keywords in C#?
- What is the meaning and usage of ‘=&’ assignment operator in PHP?
- What is the usage of in operator in JavaScript?
- What is the purpose and usage of SCROLLABLE CURSOR in COBOLDB2 program?
- What are the different types of keywords in Java?
