This C# tutorial will explain the main differences between ref and out parameters with examples and also with respect to Common language runtime(CLR).
- Ref vs Out in C# difference
- Ref Parameter in C# with Example
- Out Parameter in C# with Example
- Why Out Parameter in C#
- Difference between ref and out Parameters in C# at CLR level
- Overloading of Methods with ref and out Parameters in C#
Ref vs Out in C# difference:
The difference between ref and out parameter in C# is Out parameters is not required to assign the value before calling the function where as ref parameter should assign the value like normal parameters.
The simple way of declaring methods with ref and out parameters are as follows
//Methods public static void MethodRef(ref int a){ } public static void MethodOut(out int a){ } //Calling MethodRef(ref b); MethodOut(out b).
Ref Parameter in C# with Example:
We will understand “ref” parameter further with a simple c# program. Have a look at the following C# sample.
private static void Main(string[] args) { int aref; int bref; //This is Wrong Method(aref); MethodRef(ref aref); //This is correct MethodOut(out bref); } public static void Method(int a) { } public static void MethodRef(ref int a) { Console.WriteLine(a); } public static void MethodOut(out int a) { a = 1; Console.WriteLine(a); }
The code will throw following error
- Use of unassigned local variable ‘aref’
That means you must assign the value before calling the function.(Same for normal variables but the difference is ref parameter called by reference and normal parameters called by Value).
So When to use “ref” parameters If you want to do manipulations on parameters (For example swapping two variables) we can use the ref parameters. Please see the below example
//You must assign a and b before calling the method public static void swap(ref int a,ref int b) { int c; c = a; a = b; b = c; }
Out Parameter in C# with example:
Have a look at below C# example with ref and out parameters.
internal class Program { private static void Main(string[] args) { int aref = 1; int bref = 2; MethodRef(ref aref); MethodOut(out bref); } public static void MethodRef(ref int a) { Console.WriteLine(a); } public static void MethodOut(out int a) { Console.WriteLine("Called"); } }
If you compile the above program you will get following error
The out parameter ‘a’ must be assigned to before control leaves the current method
i.e., you must initialise the out parameter in CalledMethod (MethodOut).
It’s not necessary to initialise the out parameter before calling the method. Even though you initialise the variable, called method cannot read it.
Have a look at the below C# program I am assigning the value as 2 to bref variable before passing it as out parameter and using it in Called method. If you compile the program we will get following error
Use of Unassigned out parameter ‘a’.
That means it does not matter whether you assign the out parameter before calling method. The called method (MethodOut) cannot access the value. i.e., we must assign the out parameter before using it.
As in below example we can use the out parameter after assigning it to some value.
private static void Main(string[] args) { int bref = 2; MethodOut(out bref); } void MethodOut(out int a) { //This is wrong Console.WriteLine(a); a = 1; //This is correct //Console.WriteLine(a); }
Called method should assign the “out” parameter before returning to calling method.
Why Out parameter in C#?
We can have only one return type to a particular Method. So “out” parameter is useful when you want a method to return multiple values.
public static bool UpdateDb(int a,out string reason) { bool success = true; try { reason = string.Empty; //Callling Database //update Db Success } catch (Exception ex) { //If Fails success = false; reason = ex.Message; } return success; }
In the above example we are updating “a” to Database the method will return true or false. If its failed we want the reason why it got failed. In that case we can “out” parameter as reason and assign corresponding error to that “out” parameter.
You must assign out parameter that’ y I assigned to Empty in the success case (I have used this example for understanding the out parameter)
Difference between ref and out Parameters in C# at CLR level:
Both allows us to pass parameters by reference instead of by Value
For CLR(Common Language Run time) both ref and out parameters are identical that means same Intermediate code will generate for both keywords. and the metadata also same except for one bit which specifies whether you specified out or ref when declaring the method.
The difference is that the C# Compiler ensures that we write the correct code.(That’s why compile time error will come when didn’t initialize the ref parameter).
A ref or Out parameter cannot have default values as normal parameters. The following code snippet will not compile, Because I have passed default parameters to ref and out parameters.
public static void Method(int a = 1) { } public static void MethodRef(ref int a=1) { Console.WriteLine(a); } public static void MethodOut(out int a=1) { a = 1; Console.WriteLine(a); }
Overloading of Methods with ref and out Parameters in C#:
This is an interesting question just execute the following code snippet
public static void Add(out int a) { a = 1; } public static void Add(ref int a) { Console.WriteLine(a); }
This will throw the following error
Cannot define overloaded method ‘Add’ because it differs from another method only on ref and out
As I mentioned before CLR (Common Language Runtime) treat both ref and out keywords as same and their Metadata representation of the method signature will be identical. It’s not correct to declare a method with same signatures and parameters.
It’s again C# Compiler responsibility to ensure we write the correct code(third point in similarities) So that’s why it’s returned an error.
But overloading can be possible if one method takes a simple parameter and other method takes either ref or out parameter. The following case is perfectly valid
public static void Add(out int a) { a = 1; } public static void Add(int a) { Console.WriteLine(a); }
No comments:
Post a Comment