10 September 2015

ref vs out in C#

While writing a code, we often come across situations where we need to return multiple values from a single function/method. But a method can only return a single value.The question is how do we overcome such situation.Answer is simple, use reference types.


Parameters are always passed by value to a method by default.If we want to pass them by reference then we can use either out or ref keyword.


Ref


The ref keyword is used to pass an argument as a reference. This means that when value of that parameter is changed in the method, it gets reflected in the calling method. An argument that is passed using a ref keyword must be initialized in the calling method before it is passed to the called method.


Ref keyword will pass parameter as a reference this means when the value of parameter is changed in called method it get reflected in calling method also. There is no "boxing" when a value type is passed by reference


Out


The out keyword is also used to pass an argument like ref keyword, but the argument can be passed without assigning any value to it. An argument that is passed using an out keyword must be initialized in the called method before it returns back to calling method.


Out keyword also will pass parameter as a reference but here out parameter must be initialized in called method before it return value to calling method



public ActionResult Index()
{
int val1 = 0; //must be initialized for ref
int val2 = 0; //optional for out
Example1(ref val1);
ViewBag.Message += val1 + "\n"; // val1=0
Example2(out val2);
ViewBag.Message += val2 + "\n"; // val1=2
return View();
}

static void Example1(ref int value) //called method
{
//value = 1; // optional
}
static void Example2(out int value) //called method
{
value = 2; //must to assign value
}

These ref and out parameters are useful whenever your method wants to return more than one value.


Both the method definition and the calling method must explicitly use the ref / out keyword


Several inbuilt methods as "TryParse" (one of my favourite) use out and not ref, may be the internal implementation of library mainly uses ref.


Properties/Indexers/Dynamic member access cannot be passed to ref or out parameters since internally they are functions/methods and not members/variables


ref tells the compiler that the object is initialized before entering the function, while out tells the compiler that the object will be initialized inside the function.


Ref and out in method overloading


Both ref and out cannot be used in method overloading simultaneously. However, ref and out are treated differently at run-time but they are treated same at compile time (CLR doesn't differentiates between the two while it created IL for ref and out). Hence methods cannot be overloaded when one method takes a ref parameter and other method takes an out parameter. The following two methods are identical in terms of compilation.



class MyClass
{
   public void Method(out int a) // compiler error “cannot define overloaded”
   {
       // method that differ only on ref and out"
   }
  public void Method(ref int a)
   {
     // method that differ only on ref and out"
  }
}

However, method overloading can be done, if one method takes a ref or out argument and the other method takes simple argument. The following example is perfectly valid to be overloaded.



class MyClass
{
          public void Method(int a)
          {
          }
          public void Method(out int a)
          {
                   // method differ in signature.
          }
}

Ex:
public static void Foo()
{
int val = 0;
Example1(val);
Console.WriteLine(val); // Still 0!
Example2(ref val);
Console.WriteLine(val); // Now 2!
Example3(out val);
Console.WriteLine(val); // Now 3!
}

static void Example1(int value)
{
value = 1;
}
static void Example2(ref int value)
{
value = 2;
}
static void Example3(out int value)
{
value = 3;
}


































RefOut
The parameter or argument must be initialized first before it is passed to ref.It is not compulsory to initialize a parameter or argument before it is passed to an out.
It is not required to assign or initialize the value of a parameter (which is passed by ref) before returning to the calling method.A called method is required to assign or initialize a value of a parameter (which is passed to an out) before returning to the calling method.
Passing a parameter value by Ref is useful when the called method is also needed to modify the pass parameter.Declaring a parameter to an out method is useful when multiple values need to be returned from a function or method.
It is not compulsory to assign a parameter value before leaving calling method.A parameter value must be assigned within the calling method before its use.
When we use REF, data can be passed bi-directionally.When we use OUT data is passed only in a unidirectional way (from the called method to the caller method).
Both ref and out are treated differently at run time and they are treated the same at compile time.
Properties are not variables, therefore it cannot be passed as an out or ref parameter.

The out and ref keywords are useful when we want to return a value in the same variables as are passed as an argument

No comments: